diff --git a/docs/devs/extensions.md b/docs/devs/extensions.md index cd81a0210..5e5c2e8bc 100644 --- a/docs/devs/extensions.md +++ b/docs/devs/extensions.md @@ -28,7 +28,9 @@ Going over the example extension's structure: Adding new dependencies ----------------------- -If for some reason your extensions needs a new python package to work, you can add a new package using `venv`, or `poerty`: +DO NOT ADD NEW DEPENDENCIES. Try to use the dependencies that are availabe in `pyproject.toml`. Getting the LNbits project to accept a new dependency is time consuming and uncertain, and may result in your extension NOT being made available to others. + +If for some reason your extensions must have a new python package to work, and its nees are not met in `pyproject.toml`, you can add a new package using `venv`, or `poerty`: ```sh $ poetry add @@ -37,8 +39,7 @@ $ ./venv/bin/pip install ``` **But we need an extra step to make sure LNbits doesn't break in production.** -Dependencies need to be added to `pyproject.toml` and `requirements.txt`, then tested by running on `venv` and `poetry`. -`nix` compatability can be tested with `nix build .#checks.x86_64-linux.vmTest`. +Dependencies need to be added to `pyproject.toml` and `requirements.txt`, then tested by running on `venv` and `poetry` compatability can be tested with `nix build .#checks.x86_64-linux.vmTest`. SQLite to PostgreSQL migration diff --git a/lnbits/extensions/example/static/qrcode-example.png b/lnbits/extensions/example/static/qrcode-example.png new file mode 100644 index 000000000..29781f536 Binary files /dev/null and b/lnbits/extensions/example/static/qrcode-example.png differ diff --git a/lnbits/extensions/example/static/qrcode-example1.png b/lnbits/extensions/example/static/qrcode-example1.png new file mode 100644 index 000000000..a6c748f11 Binary files /dev/null and b/lnbits/extensions/example/static/qrcode-example1.png differ diff --git a/lnbits/extensions/example/static/websocket-example.png b/lnbits/extensions/example/static/websocket-example.png new file mode 100644 index 000000000..52171d309 Binary files /dev/null and b/lnbits/extensions/example/static/websocket-example.png differ diff --git a/lnbits/extensions/example/templates/example/index.html b/lnbits/extensions/example/templates/example/index.html index 03f66b5f7..36d325bb8 100644 --- a/lnbits/extensions/example/templates/example/index.html +++ b/lnbits/extensions/example/templates/example/index.html @@ -51,8 +51,15 @@
- {{SITE_TITLE}} Extension Development Guide - (Collection of resources for extension developers) + Extension Development Guide + (also check the + docs)
@@ -188,8 +195,8 @@

LNbits uses Vue - components for best-in-class high-performance and responsive - performance. + for best-in-class, responsive and high-performance + components.

Typical example of Vue components in a frontend script:

@@ -199,8 +206,7 @@ />

- In a page body, models can be called.
Content can be - conditionally rendered using Vue's + Content can be conditionally rendered using Vue's v-if:

MAGICAL G EXCHANGE RATES + QR CODES + WEBSOCKETS @@ -255,6 +263,85 @@ >:
+ +
QR Codes
+

+ For most purposes use Quasar's inbuilt VueQrcode library: +

+ +

+ LNbits does also include a handy + + QR code enpoint +

+ {% raw %} You can use via + {{protocol + location}}{% endraw + %}/api/v1/qrcode/some-data-you-want-in-a-qrcode:
+
+ +
+ + +
+
+ + +
Websockets
+

+ Fastapi includes a great + websocket tool +

+ {% raw %} +

+ A few LNbits extensions also make use of a weird and useful + websocket/GET tool built into LNbits, such as extensions + Copilot and LNURLDevices
+ You can subscribe to websocket with + wss:{{location}}/api/v1/ws/{SOME-ID}
+ You can post to any clients subscribed to the endpoint with + {{protocol + + location}}/api/v1/ws/{SOME-ID}/{THE-DATA-YOU-WANT-TO-POST}
+
+

+ DEMO: Hit + {{protocol + + location}}/api/v1/ws/32872r23g29/blah%20blah%20blah + in a different browser window to change this text to + `blah blah blah`. +
+
+ Function used in this demo:
+

+ + {% endraw %} @@ -296,6 +383,8 @@ data: function () { return { ///// Declare models/variables ///// + protocol: window.location.protocol, + location: '//' + window.location.hostname, thingDialog: { show: false, data: {} @@ -310,7 +399,7 @@ }, ///// Where functions live ///// methods: { - exampleFunction(data) { + exampleFunction: function (data) { var theData = data LNbits.api .request( @@ -325,6 +414,28 @@ LNbits.utils.notifyApiError(error) // Error will be passed to the frontend }) }, + initWs: async function () { + if (location.protocol !== 'http:') { + localUrl = + 'wss://' + + document.domain + + ':' + + location.port + + '/api/v1/ws/32872r23g29' + } else { + localUrl = + 'ws://' + + document.domain + + ':' + + location.port + + '/api/v1/ws/32872r23g29' + } + this.ws = new WebSocket(localUrl) + this.ws.addEventListener('message', async ({data}) => { + const res = data.toString() + document.getElementById('text-to-change').innerHTML = res + }) + }, sendThingDialog() { console.log(this.thingDialog) } @@ -333,6 +444,7 @@ created: function () { self = this // Often used to run a real object, rather than the event (all a bit confusing really) self.exampleFunction('lorum') + self.initWs() } })