Merge remote-tracking branch 'origin/main' into improved-pwa
This commit is contained in:
commit
80f8d83548
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -33,3 +33,4 @@ __bundle__
|
|||
|
||||
node_modules
|
||||
lnbits/static/bundle.*
|
||||
docker
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
|
||||
all: format check requirements.txt
|
||||
|
||||
format: prettier black
|
||||
format: black
|
||||
|
||||
check: mypy checkprettier checkblack
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<code>[<copilot_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/copilot -d '{"title":
|
||||
>curl -X POST {{ request.base_url }}copilot/api/v1/copilot -d '{"title":
|
||||
<string>, "animation": <string>,
|
||||
"show_message":<string>, "amount": <integer>,
|
||||
"lnurl_title": <string>}' -H "Content-type: application/json"
|
||||
|
@ -59,7 +59,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url
|
||||
}}api/v1/copilot/<copilot_id> -d '{"title": <string>,
|
||||
}}copilot/api/v1/copilot/<copilot_id> -d '{"title": <string>,
|
||||
"animation": <string>, "show_message":<string>,
|
||||
"amount": <integer>, "lnurl_title": <string>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key:
|
||||
|
@ -87,7 +87,7 @@
|
|||
<code>[<copilot_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/copilot/<copilot_id>
|
||||
>curl -X GET {{ request.base_url }}copilot/api/v1/copilot/<copilot_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -110,7 +110,7 @@
|
|||
<code>[<copilot_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/copilots -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}copilot/api/v1/copilots -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -136,7 +136,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}api/v1/copilot/<copilot_id> -H "X-Api-Key: {{
|
||||
}}copilot/api/v1/copilot/<copilot_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -161,7 +161,7 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}/api/v1/copilot/ws/<string,
|
||||
>curl -X GET {{ request.base_url }}copilot/api/v1/copilot/ws/<string,
|
||||
copilot_id>/<string, comment>/<string, gif name> -H
|
||||
"X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<code>[<jukebox_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/jukebox -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}jukebox/api/v1/jukebox -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<code><jukebox_object></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/jukebox/<juke_id> -H
|
||||
>curl -X GET {{ request.base_url }}jukebox/api/v1/jukebox/<juke_id> -H
|
||||
"X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -86,7 +86,7 @@
|
|||
<code><jukbox_object></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/jukebox/ -d '{"user":
|
||||
>curl -X POST {{ request.base_url }}jukebox/api/v1/jukebox/ -d '{"user":
|
||||
<string, user_id>, "title": <string>,
|
||||
"wallet":<string>, "sp_user": <string,
|
||||
spotify_user_account>, "sp_secret": <string,
|
||||
|
@ -116,7 +116,7 @@
|
|||
<code><jukebox_object></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url }}api/v1/jukebox/<juke_id>
|
||||
>curl -X DELETE {{ request.base_url }}jukebox/api/v1/jukebox/<juke_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<code>[<livestream_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root }}api/v1/livestream -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}livestream/api/v1/livestream -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -59,8 +59,8 @@
|
|||
</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.url_root
|
||||
}}api/v1/livestream/track/<track_id> -H "X-Api-Key: {{
|
||||
>curl -X PUT {{ request.base_url }}
|
||||
livestream/api/v1/livestream/track/<track_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -81,8 +81,8 @@
|
|||
</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.url_root
|
||||
}}api/v1/livestream/fee/<fee_pct> -H "X-Api-Key: {{
|
||||
>curl -X PUT {{ request.base_url }}
|
||||
livestream/api/v1/livestream/fee/<fee_pct> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -109,7 +109,8 @@
|
|||
</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root }}api/v1/livestream/tracks -d
|
||||
>curl -X POST {{ request.base_url }}
|
||||
livestream/api/v1/livestream/tracks -d
|
||||
'{"name": <string>, "download_url": <string>,
|
||||
"price_msat": <integer>, "producer_id": <integer>,
|
||||
"producer_name": <string>}' -H "Content-type: application/json"
|
||||
|
@ -123,6 +124,7 @@
|
|||
dense
|
||||
expand-separator
|
||||
label="Delete a withdraw link"
|
||||
class="q-pb-md"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
|
@ -136,8 +138,8 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.url_root
|
||||
}}api/v1/livestream/tracks/<track_id> -H "X-Api-Key: {{
|
||||
>curl -X DELETE {{ request.base_url }}
|
||||
livestream/api/v1/livestream/tracks/<track_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<code>JSON list of users</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root }}lnaddress/api/v1/domains -H
|
||||
>curl -X GET {{ request.base_url }}lnaddress/api/v1/domains -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -81,7 +81,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root }}lnaddress/api/v1/domains -d
|
||||
>curl -X POST {{ request.base_url }}lnaddress/api/v1/domains -d
|
||||
'{"wallet": "{{ user.wallets[0].id }}", "domain": <string>,
|
||||
"cf_token": <string>,"cf_zone_id": <string>,"webhook":
|
||||
<Optional string> ,"cost": <integer>}' -H "X-Api-Key: {{
|
||||
|
@ -101,7 +101,7 @@
|
|||
<code>{"X-Api-Key": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.url_root
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}lnaddress/api/v1/domains/<domain_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
|
@ -122,7 +122,7 @@
|
|||
<code>JSON list of addresses</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root }}lnaddress/api/v1/addresses -H
|
||||
>curl -X GET {{ request.base_url }}lnaddress/api/v1/addresses -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -142,14 +142,14 @@
|
|||
<code>JSON list of addresses</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root
|
||||
>curl -X GET {{ request.base_url
|
||||
}}lnaddress/api/v1/address/<domain>/<username>/<wallet_key>
|
||||
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" dense expand-separator label="POST address">
|
||||
<q-expansion-item group="api" dense expand-separator label="POST address" class="q-pb-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
|
@ -160,7 +160,7 @@
|
|||
<code>{"X-Api-Key": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root
|
||||
>curl -X POST {{ request.base_url
|
||||
}}lnaddress/api/v1/address/<domain_id> -d '{"domain":
|
||||
<string>, "username": <string>,"email": <Optional
|
||||
string>, "wallet_endpoint": <string>, "wallet_key":
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<code>[<lnurldevice_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/lnurldevice -d '{"title":
|
||||
>curl -X POST {{ request.base_url }}lnurldevice/api/v1/lnurlpos -d '{"title":
|
||||
<string>, "message":<string>, "currency":
|
||||
<integer>}' -H "Content-type: application/json" -H "X-Api-Key:
|
||||
{{user.wallets[0].adminkey }}"
|
||||
|
@ -71,7 +71,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url
|
||||
}}api/v1/lnurlpos/<lnurldevice_id> -d ''{"title":
|
||||
}}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -d ''{"title":
|
||||
<string>, "message":<string>, "currency":
|
||||
<integer>} -H "Content-type: application/json" -H "X-Api-Key:
|
||||
{{user.wallets[0].adminkey }}"
|
||||
|
@ -104,7 +104,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key: {{
|
||||
}}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -133,7 +133,7 @@
|
|||
<code>[<lnurldevice_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/lnurldevices -H
|
||||
>curl -X GET {{ request.base_url }}lnurldevice/api/v1/lnurlpos -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -159,7 +159,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key: {{
|
||||
}}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<code>[<pay_link_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/links -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}lnurlp/api/v1/links -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -39,7 +39,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/links/<pay_id> -H
|
||||
>curl -X GET {{ request.base_url }}lnurlp/api/v1/links/<pay_id> -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -68,7 +68,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/links -d '{"description":
|
||||
>curl -X POST {{ request.base_url }}lnurlp/api/v1/links -d '{"description":
|
||||
<string>, "amount": <integer>, "max": <integer>,
|
||||
"min": <integer>, "comment_chars": <integer>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key: {{
|
||||
|
@ -99,7 +99,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.base_url }}api/v1/links/<pay_id> -d
|
||||
>curl -X PUT {{ request.base_url }}lnurlp/api/v1/links/<pay_id> -d
|
||||
'{"description": <string>, "amount": <integer>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
|
@ -126,7 +126,7 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url }}api/v1/links/<pay_id> -H
|
||||
>curl -X DELETE {{ request.base_url }}lnurlp/api/v1/links/<pay_id> -H
|
||||
"X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}/offlineshop/api/v1/offlineshop/items -H "Content-Type:
|
||||
}}offlineshop/api/v1/offlineshop/items -H "Content-Type:
|
||||
application/json" -H "X-Api-Key: {{ user.wallets[0].inkey }}" -d
|
||||
'{"name": <string>, "description": <string>, "image":
|
||||
<data-uri string>, "price": <integer>, "unit": <"sat"
|
||||
|
@ -96,7 +96,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}/offlineshop/api/v1/offlineshop -H
|
||||
>curl -X GET {{ request.base_url }}offlineshop/api/v1/offlineshop -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -118,7 +118,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}/offlineshop/api/v1/offlineshop/items/<item_id> -H
|
||||
}}offlineshop/api/v1/offlineshop/items/<item_id> -H
|
||||
"Content-Type: application/json" -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}" -d '{"name": <string>, "description":
|
||||
<string>, "image": <data-uri string>, "price":
|
||||
|
@ -127,7 +127,7 @@
|
|||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" dense expand-separator label="Delete item">
|
||||
<q-expansion-item group="api" dense expand-separator label="Delete item" class="q-pb-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code><span class="text-blue">DELETE</span></code>
|
||||
|
@ -138,7 +138,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}/offlineshop/api/v1/offlineshop/items/<item_id> -H "X-Api-Key:
|
||||
}}offlineshop/api/v1/offlineshop/items/<item_id> -H "X-Api-Key:
|
||||
{{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<code>[<paywall_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root }}api/v1/paywalls -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}paywall/api/v1/paywalls -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -48,7 +48,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root }}api/v1/paywalls -d '{"url":
|
||||
>curl -X POST {{ request.base_url }}paywall/api/v1/paywalls -d '{"url":
|
||||
<string>, "memo": <string>, "description": <string>,
|
||||
"amount": <integer>, "remembers": <boolean>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key: {{
|
||||
|
@ -80,8 +80,8 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root
|
||||
}}api/v1/paywalls/<paywall_id>/invoice -d '{"amount":
|
||||
>curl -X POST {{ request.base_url
|
||||
}}paywall/api/v1/paywalls/<paywall_id>/invoice -d '{"amount":
|
||||
<integer>}' -H "Content-type: application/json"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -111,8 +111,8 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root
|
||||
}}api/v1/paywalls/<paywall_id>/check_invoice -d
|
||||
>curl -X POST {{ request.base_url
|
||||
}}paywall/api/v1/paywalls/<paywall_id>/check_invoice -d
|
||||
'{"payment_hash": <string>}' -H "Content-type: application/json"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -137,8 +137,8 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.url_root
|
||||
}}api/v1/paywalls/<paywall_id> -H "X-Api-Key: {{
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}paywall/api/v1/paywalls/<paywall_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<code>[<satsdice_link_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/links -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}satsdice/api/v1/links -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -44,7 +44,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/links/<satsdice_id> -H
|
||||
>curl -X GET {{ request.base_url }}satsdice/api/v1/links/<satsdice_id> -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/links -d '{"title":
|
||||
>curl -X POST {{ request.base_url }}satsdice/api/v1/links -d '{"title":
|
||||
<string>, "min_satsdiceable": <integer>,
|
||||
"max_satsdiceable": <integer>, "uses": <integer>,
|
||||
"wait_time": <integer>, "is_unique": <boolean>}' -H
|
||||
|
@ -109,7 +109,7 @@
|
|||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.base_url }}api/v1/links/<satsdice_id> -d
|
||||
>curl -X PUT {{ request.base_url }}satsdice/api/v1/links/<satsdice_id> -d
|
||||
'{"title": <string>, "min_satsdiceable": <integer>,
|
||||
"max_satsdiceable": <integer>, "uses": <integer>,
|
||||
"wait_time": <integer>, "is_unique": <boolean>}' -H
|
||||
|
@ -137,7 +137,7 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url }}api/v1/links/<satsdice_id>
|
||||
>curl -X DELETE {{ request.base_url }}satsdice/api/v1/links/<satsdice_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -165,7 +165,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}api/v1/links/<the_hash>/<lnurl_id> -H "X-Api-Key: {{
|
||||
}}satsdice/api/v1/links/<the_hash>/<lnurl_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -186,7 +186,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}/satsdice/img/<lnurl_id>"
|
||||
>curl -X GET {{ request.base_url }}satsdice/img/<lnurl_id>"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<code>[<charge_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/charge -d
|
||||
>curl -X POST {{ request.base_url }}satspay/api/v1/charge -d
|
||||
'{"onchainwallet": <string, watchonly_wallet_id>,
|
||||
"description": <string>, "webhook":<string>, "time":
|
||||
<integer>, "amount": <integer>, "lnbitswallet":
|
||||
|
@ -60,7 +60,7 @@
|
|||
<code>[<charge_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/charge/<charge_id>
|
||||
>curl -X POST {{ request.base_url }}satspay/api/v1/charge/<charge_id>
|
||||
-d '{"onchainwallet": <string, watchonly_wallet_id>,
|
||||
"description": <string>, "webhook":<string>, "time":
|
||||
<integer>, "amount": <integer>, "lnbitswallet":
|
||||
|
@ -89,7 +89,7 @@
|
|||
<code>[<charge_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/charge/<charge_id>
|
||||
>curl -X GET {{ request.base_url }}satspay/api/v1/charge/<charge_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -112,7 +112,7 @@
|
|||
<code>[<charge_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/charges -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}satspay/api/v1/charges -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -123,7 +123,6 @@
|
|||
dense
|
||||
expand-separator
|
||||
label="Delete a pay link"
|
||||
class="q-pb-md"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
|
@ -138,13 +137,18 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}api/v1/charge/<charge_id> -H "X-Api-Key: {{
|
||||
}}satspay/api/v1/charge/<charge_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" dense expand-separator label="Get balances">
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense expand-separator
|
||||
label="Get balances"
|
||||
class="q-pb-md"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
|
@ -161,7 +165,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}api/v1/charges/balance/<charge_id> -H "X-Api-Key: {{
|
||||
}}satspay/api/v1/charges/balance/<charge_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/livestream -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}splitpayments/api/v1/targets -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -63,6 +63,7 @@
|
|||
dense
|
||||
expand-separator
|
||||
label="Set Target Wallets"
|
||||
class="q-pb-md"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
|
@ -78,7 +79,7 @@
|
|||
</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.base_url }}api/v1/splitpayments/targets -H
|
||||
>curl -X PUT {{ request.base_url }}splitpayments/api/v1/targets -H
|
||||
"X-Api-Key: {{ user.wallets[0].adminkey }}" -H 'Content-Type:
|
||||
application/json' -d '{"targets": [{"wallet": <wallet id or invoice
|
||||
key>, "alias": <name to identify this>, "percent": <number
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import asyncio
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from lnbits.db import Database
|
||||
from lnbits.helpers import template_renderer
|
||||
from lnbits.tasks import catch_everything_and_restart
|
||||
|
||||
db = Database("ext_tpos")
|
||||
|
||||
|
@ -12,5 +15,11 @@ def tpos_renderer():
|
|||
return template_renderer(["lnbits/extensions/tpos/templates"])
|
||||
|
||||
|
||||
from .tasks import wait_for_paid_invoices
|
||||
from .views_api import * # noqa
|
||||
from .views import * # noqa
|
||||
|
||||
|
||||
def tpos_start():
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
"name": "TPoS",
|
||||
"short_description": "A shareable PoS terminal!",
|
||||
"icon": "dialpad",
|
||||
"contributors": ["talvasconcelos", "arcbtc"]
|
||||
"contributors": ["talvasconcelos", "arcbtc", "leesalminen"]
|
||||
}
|
||||
|
|
|
@ -10,10 +10,17 @@ async def create_tpos(wallet_id: str, data: CreateTposData) -> TPoS:
|
|||
tpos_id = urlsafe_short_hash()
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO tpos.tposs (id, wallet, name, currency)
|
||||
VALUES (?, ?, ?, ?)
|
||||
INSERT INTO tpos.tposs (id, wallet, name, currency, tip_options, tip_wallet)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(tpos_id, wallet_id, data.name, data.currency),
|
||||
(
|
||||
tpos_id,
|
||||
wallet_id,
|
||||
data.name,
|
||||
data.currency,
|
||||
data.tip_options,
|
||||
data.tip_wallet,
|
||||
),
|
||||
)
|
||||
|
||||
tpos = await get_tpos(tpos_id)
|
||||
|
|
|
@ -12,3 +12,25 @@ async def m001_initial(db):
|
|||
);
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
async def m002_addtip_wallet(db):
|
||||
"""
|
||||
Add tips to tposs table
|
||||
"""
|
||||
await db.execute(
|
||||
"""
|
||||
ALTER TABLE tpos.tposs ADD tip_wallet TEXT NULL;
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
async def m003_addtip_options(db):
|
||||
"""
|
||||
Add tips to tposs table
|
||||
"""
|
||||
await db.execute(
|
||||
"""
|
||||
ALTER TABLE tpos.tposs ADD tip_options TEXT NULL;
|
||||
"""
|
||||
)
|
||||
|
|
|
@ -6,6 +6,8 @@ from pydantic import BaseModel
|
|||
class CreateTposData(BaseModel):
|
||||
name: str
|
||||
currency: str
|
||||
tip_options: str
|
||||
tip_wallet: str
|
||||
|
||||
|
||||
class TPoS(BaseModel):
|
||||
|
@ -13,6 +15,8 @@ class TPoS(BaseModel):
|
|||
wallet: str
|
||||
name: str
|
||||
currency: str
|
||||
tip_options: str
|
||||
tip_wallet: str
|
||||
|
||||
@classmethod
|
||||
def from_row(cls, row: Row) -> "TPoS":
|
||||
|
|
70
lnbits/extensions/tpos/tasks.py
Normal file
70
lnbits/extensions/tpos/tasks.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
import asyncio
|
||||
import json
|
||||
|
||||
from lnbits.core import db as core_db
|
||||
from lnbits.core.crud import create_payment
|
||||
from lnbits.core.models import Payment
|
||||
from lnbits.helpers import urlsafe_short_hash
|
||||
from lnbits.tasks import internal_invoice_queue, register_invoice_listener
|
||||
|
||||
from .crud import get_tpos
|
||||
|
||||
|
||||
async def wait_for_paid_invoices():
|
||||
invoice_queue = asyncio.Queue()
|
||||
register_invoice_listener(invoice_queue)
|
||||
|
||||
while True:
|
||||
payment = await invoice_queue.get()
|
||||
await on_invoice_paid(payment)
|
||||
|
||||
|
||||
async def on_invoice_paid(payment: Payment) -> None:
|
||||
if "tpos" == payment.extra.get("tag") and payment.extra.get("tipSplitted"):
|
||||
# already splitted, ignore
|
||||
return
|
||||
|
||||
# now we make some special internal transfers (from no one to the receiver)
|
||||
tpos = await get_tpos(payment.extra.get("tposId"))
|
||||
|
||||
tipAmount = payment.extra.get("tipAmount")
|
||||
|
||||
if tipAmount is None:
|
||||
# no tip amount
|
||||
return
|
||||
|
||||
tipAmount = tipAmount * 1000
|
||||
|
||||
# mark the original payment with one extra key, "splitted"
|
||||
# (this prevents us from doing this process again and it's informative)
|
||||
# and reduce it by the amount we're going to send to the producer
|
||||
await core_db.execute(
|
||||
"""
|
||||
UPDATE apipayments
|
||||
SET extra = ?, amount = amount - ?
|
||||
WHERE hash = ?
|
||||
AND checking_id NOT LIKE 'internal_%'
|
||||
""",
|
||||
(
|
||||
json.dumps(dict(**payment.extra, tipSplitted=True)),
|
||||
tipAmount,
|
||||
payment.payment_hash,
|
||||
),
|
||||
)
|
||||
|
||||
# perform the internal transfer using the same payment_hash
|
||||
internal_checking_id = f"internal_{urlsafe_short_hash()}"
|
||||
await create_payment(
|
||||
wallet_id=tpos.tip_wallet,
|
||||
checking_id=internal_checking_id,
|
||||
payment_request="",
|
||||
payment_hash=payment.payment_hash,
|
||||
amount=tipAmount,
|
||||
memo=payment.memo,
|
||||
pending=False,
|
||||
extra={"tipSplitted": True},
|
||||
)
|
||||
|
||||
# manually send this for now
|
||||
await internal_invoice_queue.put(internal_checking_id)
|
||||
return
|
|
@ -17,7 +17,7 @@
|
|||
<code>[<tpos_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/tposs -H "X-Api-Key:
|
||||
>curl -X GET {{ request.base_url }}tpos/api/v1/tposs -H "X-Api-Key:
|
||||
<invoice_key>"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -42,7 +42,7 @@
|
|||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/tposs -d '{"name":
|
||||
>curl -X POST {{ request.base_url }}tpos/api/v1/tposs -d '{"name":
|
||||
<string>, "currency": <string>}' -H "Content-type:
|
||||
application/json" -H "X-Api-Key: <admin_key>"
|
||||
</code>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url }}api/v1/tposs/<tpos_id> -H
|
||||
>curl -X DELETE {{ request.base_url }}tpos/api/v1/tposs/<tpos_id> -H
|
||||
"X-Api-Key: <admin_key>"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
></q-btn>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.value }}
|
||||
{{ (col.name == 'tip_options' ? JSON.parse(col.value).join(", ") : col.value) }}
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
|
@ -116,6 +116,29 @@
|
|||
:options="currencyOptions"
|
||||
label="Currency *"
|
||||
></q-select>
|
||||
<q-select
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model="formDialog.data.tip_wallet"
|
||||
:options="g.user.walletOptions"
|
||||
label="Tip Wallet"
|
||||
></q-select>
|
||||
<q-select
|
||||
filled
|
||||
multiple
|
||||
dense
|
||||
emit-value
|
||||
v-model="formDialog.data.tip_options"
|
||||
v-if="formDialog.data.tip_wallet"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add-unique"
|
||||
label="Tip % Options"
|
||||
></q-select>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
unelevated
|
||||
|
@ -333,7 +356,19 @@
|
|||
align: 'left',
|
||||
label: 'Currency',
|
||||
field: 'currency'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'tip_wallet',
|
||||
align: 'left',
|
||||
label: "Tip Wallet",
|
||||
field: "tip_wallet",
|
||||
},
|
||||
{
|
||||
name: 'tip_options',
|
||||
align: 'left',
|
||||
label: "Tip Options %",
|
||||
field: "tip_options",
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 10
|
||||
|
@ -367,7 +402,9 @@
|
|||
createTPoS: function () {
|
||||
var data = {
|
||||
name: this.formDialog.data.name,
|
||||
currency: this.formDialog.data.currency
|
||||
currency: this.formDialog.data.currency,
|
||||
tip_options: (this.formDialog.data.tip_options ? JSON.stringify(this.formDialog.data.tip_options.map(str => parseInt(str))) : JSON.stringify([])),
|
||||
tip_wallet: this.formDialog.data.tip_wallet || "",
|
||||
}
|
||||
var self = this
|
||||
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
{% extends "public.html" %} {% block toolbar_title %}{{ tpos.name }}{% endblock
|
||||
%} {% block footer %}{% endblock %} {% block page_container %}
|
||||
<link rel="manifest" href="/tpos/manifest/{{ tpos.id }}.webmanifest" />
|
||||
{% extends "public.html" %}
|
||||
{% block toolbar_title %}
|
||||
{{ tpos.name }}
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
size="md"
|
||||
@click.prevent="urlDialog.show = true"
|
||||
icon="share"
|
||||
color="white"
|
||||
></q-btn>
|
||||
{% endblock %}
|
||||
{% block footer %}{% endblock %} {% block page_container %}
|
||||
<q-page-container>
|
||||
<q-page>
|
||||
<q-page-sticky v-if="exchangeRate" expand position="top">
|
||||
|
@ -43,16 +55,6 @@
|
|||
color="primary"
|
||||
>3</q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
@click="stack = []"
|
||||
size="xl"
|
||||
:outline="!($q.dark.isActive)"
|
||||
rounded
|
||||
color="primary"
|
||||
class="btn-cancel"
|
||||
>C</q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
@click="stack.push(4)"
|
||||
|
@ -107,17 +109,6 @@
|
|||
color="primary"
|
||||
>9</q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
:disabled="amount == 0"
|
||||
@click="showInvoice()"
|
||||
size="xl"
|
||||
:outline="!($q.dark.isActive)"
|
||||
rounded
|
||||
color="primary"
|
||||
class="btn-confirm"
|
||||
>OK</q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
@click="stack.splice(-1, 1)"
|
||||
|
@ -138,12 +129,24 @@
|
|||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
@click="urlDialog.show = true"
|
||||
@click="stack = []"
|
||||
size="xl"
|
||||
:outline="!($q.dark.isActive)"
|
||||
rounded
|
||||
color="primary"
|
||||
>#</q-btn
|
||||
class="btn-cancel"
|
||||
>C</q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
:disabled="amount == 0"
|
||||
@click="submitForm()"
|
||||
size="xl"
|
||||
:outline="!($q.dark.isActive)"
|
||||
rounded
|
||||
color="primary"
|
||||
class="btn-confirm"
|
||||
>OK</q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -176,6 +179,38 @@
|
|||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog
|
||||
v-model="tipDialog.show"
|
||||
position="top"
|
||||
>
|
||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||
<div class="text-center q-mb-xl">
|
||||
<b style="font-size: 24px;">Would you like to leave a tip?</b>
|
||||
</div>
|
||||
<div class="text-center q-mb-xl">
|
||||
<q-btn
|
||||
style="padding: 10px; margin: 3px;"
|
||||
unelevated
|
||||
@click="processTipSelection(tip)"
|
||||
size="xl"
|
||||
:outline="!($q.dark.isActive)"
|
||||
rounded
|
||||
color="primary"
|
||||
v-for="tip in this.tip_options"
|
||||
:key="tip"
|
||||
>{% raw %}{{ tip }}{% endraw %}%</q-btn
|
||||
>
|
||||
</div>
|
||||
<div class="text-center q-mb-xl">
|
||||
<p><a @click="processTipSelection(0)"> No, thanks</a></p>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="urlDialog.show" position="top">
|
||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||
|
@ -214,6 +249,10 @@
|
|||
</q-page-container>
|
||||
{% endblock %} {% block styles %}
|
||||
<style>
|
||||
* {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.keypad {
|
||||
display: grid;
|
||||
grid-gap: 8px;
|
||||
|
@ -225,9 +264,8 @@
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.btn-cancel,
|
||||
.btn-confirm {
|
||||
grid-row: auto/span 2;
|
||||
.keypad .btn-confirm {
|
||||
grid-area: 1 / 4 / 5 / 4;
|
||||
}
|
||||
</style>
|
||||
{% endblock %} {% block scripts %}
|
||||
|
@ -241,14 +279,19 @@
|
|||
return {
|
||||
tposId: '{{ tpos.id }}',
|
||||
currency: '{{ tpos.currency }}',
|
||||
tip_options: JSON.parse('{{ tpos.tip_options }}'),
|
||||
exchangeRate: null,
|
||||
stack: [],
|
||||
tipAmount: 0.00,
|
||||
invoiceDialog: {
|
||||
show: false,
|
||||
data: null,
|
||||
dismissMsg: null,
|
||||
paymentChecker: null
|
||||
},
|
||||
tipDialog: {
|
||||
show: false,
|
||||
},
|
||||
urlDialog: {
|
||||
show: false
|
||||
},
|
||||
|
@ -269,6 +312,10 @@
|
|||
if (!this.exchangeRate) return 0
|
||||
return Math.ceil((this.amount / this.exchangeRate) * 100000000)
|
||||
},
|
||||
tipAmountSat: function () {
|
||||
if (!this.exchangeRate) return 0
|
||||
return Math.ceil((this.tipAmount / this.exchangeRate) * 100000000)
|
||||
},
|
||||
fsat: function () {
|
||||
console.log('sat', this.sat, LNbits.utils.formatSat(this.sat))
|
||||
return LNbits.utils.formatSat(this.sat)
|
||||
|
@ -277,12 +324,46 @@
|
|||
methods: {
|
||||
closeInvoiceDialog: function () {
|
||||
this.stack = []
|
||||
this.tipAmount = 0.00
|
||||
var dialog = this.invoiceDialog
|
||||
setTimeout(function () {
|
||||
clearInterval(dialog.paymentChecker)
|
||||
dialog.dismissMsg()
|
||||
}, 3000)
|
||||
},
|
||||
processTipSelection: function (selectedTipOption) {
|
||||
this.tipDialog.show = false
|
||||
|
||||
if(selectedTipOption) {
|
||||
const tipAmount = parseFloat(parseFloat((selectedTipOption / 100) * this.amount))
|
||||
const subtotal = parseFloat(this.amount)
|
||||
const grandTotal = parseFloat((tipAmount + subtotal).toFixed(2))
|
||||
const totalString = grandTotal.toFixed(2).toString()
|
||||
|
||||
this.stack = []
|
||||
for (var i = 0; i < totalString.length; i++) {
|
||||
const char = totalString[i]
|
||||
|
||||
if(char !== ".") {
|
||||
this.stack.push(char)
|
||||
}
|
||||
}
|
||||
|
||||
this.tipAmount = tipAmount
|
||||
}
|
||||
|
||||
this.showInvoice()
|
||||
},
|
||||
submitForm: function() {
|
||||
if(this.tip_options.length) {
|
||||
this.showTipModal()
|
||||
} else {
|
||||
this.showInvoice()
|
||||
}
|
||||
},
|
||||
showTipModal: function() {
|
||||
this.tipDialog.show = true
|
||||
},
|
||||
showInvoice: function () {
|
||||
var self = this
|
||||
var dialog = this.invoiceDialog
|
||||
|
@ -290,7 +371,8 @@
|
|||
axios
|
||||
.post('/tpos/api/v1/tposs/' + this.tposId + '/invoices', null, {
|
||||
params: {
|
||||
amount: this.sat
|
||||
amount: this.sat,
|
||||
tipAmount: this.tipAmountSat,
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
|
|
|
@ -8,6 +8,10 @@ from starlette.responses import HTMLResponse
|
|||
|
||||
from lnbits.core.models import User
|
||||
from lnbits.decorators import check_user_exists
|
||||
from lnbits.settings import (
|
||||
LNBITS_CUSTOM_LOGO,
|
||||
LNBITS_SITE_TITLE,
|
||||
)
|
||||
|
||||
from . import tpos_ext, tpos_renderer
|
||||
from .crud import get_tpos
|
||||
|
@ -33,3 +37,40 @@ async def tpos(request: Request, tpos_id):
|
|||
return tpos_renderer().TemplateResponse(
|
||||
"tpos/tpos.html", {"request": request, "tpos": tpos}
|
||||
)
|
||||
|
||||
|
||||
@tpos_ext.get("/manifest/{tpos_id}.webmanifest")
|
||||
async def manifest(tpos_id: str):
|
||||
tpos = await get_tpos(tpos_id)
|
||||
if not tpos:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist."
|
||||
)
|
||||
|
||||
return {
|
||||
"short_name": LNBITS_SITE_TITLE,
|
||||
"name": tpos.name + " - " + LNBITS_SITE_TITLE,
|
||||
"icons": [
|
||||
{
|
||||
"src": LNBITS_CUSTOM_LOGO
|
||||
if LNBITS_CUSTOM_LOGO
|
||||
else "https://cdn.jsdelivr.net/gh/lnbits/lnbits@0.3.0/docs/logos/lnbits.png",
|
||||
"type": "image/png",
|
||||
"sizes": "900x900",
|
||||
}
|
||||
],
|
||||
"start_url": "/tpos/" + tpos_id,
|
||||
"background_color": "#1F2234",
|
||||
"description": "Bitcoin Lightning tPOS",
|
||||
"display": "standalone",
|
||||
"scope": "/tpos/" + tpos_id,
|
||||
"theme_color": "#1F2234",
|
||||
"shortcuts": [
|
||||
{
|
||||
"name": tpos.name + " - " + LNBITS_SITE_TITLE,
|
||||
"short_name": tpos.name,
|
||||
"description": tpos.name + " - " + LNBITS_SITE_TITLE,
|
||||
"url": "/tpos/" + tpos_id,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
|
|
@ -52,7 +52,9 @@ async def api_tpos_delete(
|
|||
|
||||
|
||||
@tpos_ext.post("/api/v1/tposs/{tpos_id}/invoices", status_code=HTTPStatus.CREATED)
|
||||
async def api_tpos_create_invoice(amount: int = Query(..., ge=1), tpos_id: str = None):
|
||||
async def api_tpos_create_invoice(
|
||||
amount: int = Query(..., ge=1), tipAmount: int = None, tpos_id: str = None
|
||||
):
|
||||
tpos = await get_tpos(tpos_id)
|
||||
|
||||
if not tpos:
|
||||
|
@ -65,7 +67,7 @@ async def api_tpos_create_invoice(amount: int = Query(..., ge=1), tpos_id: str =
|
|||
wallet_id=tpos.wallet,
|
||||
amount=amount,
|
||||
memo=f"{tpos.name}",
|
||||
extra={"tag": "tpos"},
|
||||
extra={"tag": "tpos", "tipAmount": tipAmount, "tposId": tpos_id},
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
|
||||
|
@ -84,6 +86,7 @@ async def api_tpos_check_invoice(tpos_id: str, payment_hash: str):
|
|||
)
|
||||
try:
|
||||
status = await api_payment(payment_hash)
|
||||
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
return {"paid": False}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<code>[<wallets_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/wallet -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}watchonly/api/v1/wallet -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -66,7 +66,7 @@
|
|||
<code>[<wallet_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/wallet/<wallet_id>
|
||||
>curl -X GET {{ request.base_url }}watchonly/api/v1/wallet/<wallet_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -89,7 +89,7 @@
|
|||
<code>[<wallet_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.base_url }}api/v1/wallet -d '{"title":
|
||||
>curl -X POST {{ request.base_url }}watchonly/api/v1/wallet -d '{"title":
|
||||
<string>, "masterpub": <string>}' -H "Content-type:
|
||||
application/json" -H "X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
|
@ -116,7 +116,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}api/v1/wallet/<wallet_id> -H "X-Api-Key: {{
|
||||
}}watchonly/api/v1/wallet/<wallet_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -142,7 +142,7 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}api/v1/addresses/<wallet_id> -H "X-Api-Key: {{
|
||||
}}watchonly/api/v1/addresses/<wallet_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -173,7 +173,7 @@
|
|||
<code>[<address_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/address/<wallet_id>
|
||||
>curl -X GET {{ request.base_url }}watchonly/api/v1/address/<wallet_id>
|
||||
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -202,7 +202,7 @@
|
|||
<code>[<mempool_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}api/v1/mempool -H "X-Api-Key: {{
|
||||
>curl -X GET {{ request.base_url }}watchonly/api/v1/mempool -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
|
@ -233,7 +233,7 @@
|
|||
<code>[<mempool_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.base_url }}api/v1/mempool -d '{"endpoint":
|
||||
>curl -X PUT {{ request.base_url }}watchonly/api/v1/mempool -d '{"endpoint":
|
||||
<string>}' -H "Content-type: application/json" -H "X-Api-Key:
|
||||
{{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
|
|
|
@ -140,4 +140,10 @@ video {
|
|||
// text-wrap
|
||||
.text-wrap {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.q-card {
|
||||
code {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user