+ In the app go to edit-settings, set the redirect URI to this link
+
+
+ After adding the redirect URI, click the "Authorise access" button
+ below.
+
@@ -281,7 +301,7 @@
None:
- if "livestream" != payment.extra.get("tag"):
+ if payment.extra.get("tag") != "livestream":
# not a livestream invoice
return
diff --git a/lnbits/extensions/livestream/views.py b/lnbits/extensions/livestream/views.py
index ef0354315..97f803a31 100644
--- a/lnbits/extensions/livestream/views.py
+++ b/lnbits/extensions/livestream/views.py
@@ -1,7 +1,5 @@
from http import HTTPStatus
-# from mmap import MAP_DENYWRITE
-
from fastapi.param_functions import Depends
from fastapi.params import Query
from starlette.exceptions import HTTPException
@@ -15,6 +13,8 @@ from lnbits.decorators import check_user_exists
from . import livestream_ext, livestream_renderer
from .crud import get_livestream_by_track, get_track
+# from mmap import MAP_DENYWRITE
+
@livestream_ext.get("/", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_user_exists)):
diff --git a/lnbits/extensions/lnaddress/lnurl.py b/lnbits/extensions/lnaddress/lnurl.py
index 2b064e0a1..e6a1ff486 100644
--- a/lnbits/extensions/lnaddress/lnurl.py
+++ b/lnbits/extensions/lnaddress/lnurl.py
@@ -3,15 +3,13 @@ import json
from datetime import datetime, timedelta
import httpx
-
-from loguru import logger
-
from fastapi.params import Query
from lnurl import ( # type: ignore
LnurlErrorResponse,
LnurlPayActionResponse,
LnurlPayResponse,
)
+from loguru import logger
from starlette.requests import Request
from starlette.responses import HTMLResponse
diff --git a/lnbits/extensions/lnaddress/tasks.py b/lnbits/extensions/lnaddress/tasks.py
index 9702c70b6..9abe10c3d 100644
--- a/lnbits/extensions/lnaddress/tasks.py
+++ b/lnbits/extensions/lnaddress/tasks.py
@@ -43,13 +43,13 @@ async def call_webhook_on_paid(payment_hash):
async def on_invoice_paid(payment: Payment) -> None:
- if "lnaddress" == payment.extra.get("tag"):
+ if payment.extra.get("tag") == "lnaddress":
await payment.set_pending(False)
await set_address_paid(payment_hash=payment.payment_hash)
await call_webhook_on_paid(payment_hash=payment.payment_hash)
- elif "renew lnaddress" == payment.extra.get("tag"):
+ elif payment.extra.get("tag") == "renew lnaddress":
await payment.set_pending(False)
await set_address_renewed(
diff --git a/lnbits/extensions/lndhub/decorators.py b/lnbits/extensions/lndhub/decorators.py
index 149311643..4698e9b90 100644
--- a/lnbits/extensions/lndhub/decorators.py
+++ b/lnbits/extensions/lndhub/decorators.py
@@ -1,14 +1,12 @@
from base64 import b64decode
-from fastapi.param_functions import Security
-
-from fastapi.security.api_key import APIKeyHeader
from fastapi import Request, status
+from fastapi.param_functions import Security
+from fastapi.security.api_key import APIKeyHeader
from starlette.exceptions import HTTPException
from lnbits.decorators import WalletTypeInfo, get_key_type # type: ignore
-
api_key_header_auth = APIKeyHeader(
name="AUTHORIZATION",
auto_error=False,
diff --git a/lnbits/extensions/lndhub/views.py b/lnbits/extensions/lndhub/views.py
index 4b015c09f..38a33a34a 100644
--- a/lnbits/extensions/lndhub/views.py
+++ b/lnbits/extensions/lndhub/views.py
@@ -1,8 +1,10 @@
-from lnbits.decorators import check_user_exists
-from . import lndhub_ext, lndhub_renderer
from fastapi import Request
from fastapi.params import Depends
+
from lnbits.core.models import User
+from lnbits.decorators import check_user_exists
+
+from . import lndhub_ext, lndhub_renderer
@lndhub_ext.get("/")
diff --git a/lnbits/extensions/lndhub/views_api.py b/lnbits/extensions/lndhub/views_api.py
index 8cbf5b01c..a3160fa9a 100644
--- a/lnbits/extensions/lndhub/views_api.py
+++ b/lnbits/extensions/lndhub/views_api.py
@@ -1,6 +1,5 @@
-import time
import asyncio
-
+import time
from base64 import urlsafe_b64encode
from http import HTTPStatus
@@ -13,7 +12,7 @@ from lnbits import bolt11
from lnbits.core.crud import delete_expired_invoices, get_payments
from lnbits.core.services import create_invoice, pay_invoice
from lnbits.decorators import WalletTypeInfo
-from lnbits.settings import WALLET, LNBITS_SITE_TITLE
+from lnbits.settings import LNBITS_SITE_TITLE, WALLET
from . import lndhub_ext
from .decorators import check_wallet, require_admin_key
diff --git a/lnbits/extensions/lnticket/crud.py b/lnbits/extensions/lnticket/crud.py
index 8fe170905..3254ad438 100644
--- a/lnbits/extensions/lnticket/crud.py
+++ b/lnbits/extensions/lnticket/crud.py
@@ -1,11 +1,12 @@
-from lnbits.core.models import Wallet
from typing import List, Optional, Union
+import httpx
+
+from lnbits.core.models import Wallet
from lnbits.helpers import urlsafe_short_hash
from . import db
-from .models import CreateFormData, CreateTicketData, Tickets, Forms
-import httpx
+from .models import CreateFormData, CreateTicketData, Forms, Tickets
async def create_ticket(
diff --git a/lnbits/extensions/lnticket/models.py b/lnbits/extensions/lnticket/models.py
index 50ffc1e1d..a7a3cf8c3 100644
--- a/lnbits/extensions/lnticket/models.py
+++ b/lnbits/extensions/lnticket/models.py
@@ -1,4 +1,5 @@
from typing import Optional
+
from fastapi.param_functions import Query
from pydantic import BaseModel
diff --git a/lnbits/extensions/lnticket/tasks.py b/lnbits/extensions/lnticket/tasks.py
index 23d485b47..7e672115d 100644
--- a/lnbits/extensions/lnticket/tasks.py
+++ b/lnbits/extensions/lnticket/tasks.py
@@ -18,7 +18,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "lnticket" != payment.extra.get("tag"):
+ if payment.extra.get("tag") != "lnticket":
# not a lnticket invoice
return
diff --git a/lnbits/extensions/lnurldevice/lnurl.py b/lnbits/extensions/lnurldevice/lnurl.py
index 26a127f19..5e25dadbe 100644
--- a/lnbits/extensions/lnurldevice/lnurl.py
+++ b/lnbits/extensions/lnurldevice/lnurl.py
@@ -1,30 +1,26 @@
import base64
import hashlib
+import hmac
from http import HTTPStatus
+from io import BytesIO
from typing import Optional
-from embit import bech32
-from embit import compact
-import base64
-from io import BytesIO
-import hmac
-
+from embit import bech32, compact
from fastapi import Request
from fastapi.param_functions import Query
from starlette.exceptions import HTTPException
from lnbits.core.services import create_invoice
-from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
from lnbits.core.views.api import pay_invoice
-
+from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
from . import lnurldevice_ext
from .crud import (
create_lnurldevicepayment,
get_lnurldevice,
get_lnurldevicepayment,
- update_lnurldevicepayment,
get_lnurlpayload,
+ update_lnurldevicepayment,
)
diff --git a/lnbits/extensions/lnurldevice/migrations.py b/lnbits/extensions/lnurldevice/migrations.py
index 67065347c..c7899282c 100644
--- a/lnbits/extensions/lnurldevice/migrations.py
+++ b/lnbits/extensions/lnurldevice/migrations.py
@@ -38,7 +38,7 @@ async def m001_initial(db):
async def m002_redux(db):
"""
- Moves everything from lnurlpos to lnurldevices
+ Moves everything from lnurlpos to lnurldevice
"""
try:
for row in [
diff --git a/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html b/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html
index d5b4b5b8e..940d4691e 100644
--- a/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html
+++ b/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html
@@ -120,7 +120,7 @@
GET
- /lnurldevice/api/v1/lnurlposs
Headers
{"X-Api-Key": <invoice_key>}
diff --git a/lnbits/extensions/lnurlp/crud.py b/lnbits/extensions/lnurlp/crud.py
index c70465881..9cb01fdef 100644
--- a/lnbits/extensions/lnurlp/crud.py
+++ b/lnbits/extensions/lnurlp/crud.py
@@ -1,8 +1,9 @@
from typing import List, Optional, Union
from lnbits.db import SQLITE
+
from . import db
-from .models import PayLink, CreatePayLinkData
+from .models import CreatePayLinkData, PayLink
async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
diff --git a/lnbits/extensions/lnurlp/models.py b/lnbits/extensions/lnurlp/models.py
index bd121cc84..4bd438a4f 100644
--- a/lnbits/extensions/lnurlp/models.py
+++ b/lnbits/extensions/lnurlp/models.py
@@ -1,12 +1,14 @@
import json
-from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
-from starlette.requests import Request
-from fastapi.param_functions import Query
-from typing import Optional, Dict
-from lnbits.lnurl import encode as lnurl_encode # type: ignore
-from lnurl.types import LnurlPayMetadata # type: ignore
from sqlite3 import Row
+from typing import Dict, Optional
+from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
+
+from fastapi.param_functions import Query
+from lnurl.types import LnurlPayMetadata # type: ignore
from pydantic import BaseModel
+from starlette.requests import Request
+
+from lnbits.lnurl import encode as lnurl_encode # type: ignore
class CreatePayLinkData(BaseModel):
diff --git a/lnbits/extensions/lnurlp/static/js/index.js b/lnbits/extensions/lnurlp/static/js/index.js
index e18d6161e..1713e77f6 100644
--- a/lnbits/extensions/lnurlp/static/js/index.js
+++ b/lnbits/extensions/lnurlp/static/js/index.js
@@ -35,6 +35,7 @@ new Vue({
rowsPerPage: 10
}
},
+ nfcTagWriting: false,
formDialog: {
show: false,
fixedAmount: true,
@@ -205,6 +206,42 @@ new Vue({
.catch(err => {
LNbits.utils.notifyApiError(err)
})
+ },
+ writeNfcTag: async function (lnurl) {
+ try {
+ if (typeof NDEFReader == 'undefined') {
+ throw {
+ toString: function () {
+ return 'NFC not supported on this device or browser.'
+ }
+ }
+ }
+
+ const ndef = new NDEFReader()
+
+ this.nfcTagWriting = true
+ this.$q.notify({
+ message: 'Tap your NFC tag to write the LNURL-pay link to it.'
+ })
+
+ await ndef.write({
+ records: [{recordType: 'url', data: 'lightning:' + lnurl, lang: 'en'}]
+ })
+
+ this.nfcTagWriting = false
+ this.$q.notify({
+ type: 'positive',
+ message: 'NFC tag written successfully.'
+ })
+ } catch (error) {
+ this.nfcTagWriting = false
+ this.$q.notify({
+ type: 'negative',
+ message: error
+ ? error.toString()
+ : 'An unexpected error has occurred.'
+ })
+ }
}
},
created() {
diff --git a/lnbits/extensions/lnurlp/tasks.py b/lnbits/extensions/lnurlp/tasks.py
index b632fa13f..525d36ce4 100644
--- a/lnbits/extensions/lnurlp/tasks.py
+++ b/lnbits/extensions/lnurlp/tasks.py
@@ -1,5 +1,6 @@
import asyncio
import json
+
import httpx
from lnbits.core import db as core_db
@@ -19,7 +20,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "lnurlp" != payment.extra.get("tag"):
+ if payment.extra.get("tag") != "lnurlp":
# not an lnurlp invoice
return
diff --git a/lnbits/extensions/lnurlp/templates/lnurlp/display.html b/lnbits/extensions/lnurlp/templates/lnurlp/display.html
index 08e4de15c..944e764bf 100644
--- a/lnbits/extensions/lnurlp/templates/lnurlp/display.html
+++ b/lnbits/extensions/lnurlp/templates/lnurlp/display.html
@@ -14,10 +14,17 @@
-
+
Copy LNURL
+
diff --git a/lnbits/extensions/lnurlp/templates/lnurlp/index.html b/lnbits/extensions/lnurlp/templates/lnurlp/index.html
index c535f2fb4..9677a0274 100644
--- a/lnbits/extensions/lnurlp/templates/lnurlp/index.html
+++ b/lnbits/extensions/lnurlp/templates/lnurlp/index.html
@@ -99,7 +99,8 @@
@click="openUpdateDialog(props.row.id)"
icon="edit"
color="light-blue"
- >
+ >
+
+ >
+
+ >
+
@@ -200,7 +203,8 @@
type="number"
label="Comment maximum characters"
hint="Tell wallets to prompt users for a comment that will be sent along with the payment. LNURLp will store the comment and send it in the webhook."
- >
+ >
+
+ >
+
Shareable link
+
+
int:
diff --git a/lnbits/extensions/offlineshop/helpers.py b/lnbits/extensions/offlineshop/helpers.py
index 6b56cf559..86a653aa2 100644
--- a/lnbits/extensions/offlineshop/helpers.py
+++ b/lnbits/extensions/offlineshop/helpers.py
@@ -1,6 +1,6 @@
import base64
-import struct
import hmac
+import struct
import time
diff --git a/lnbits/extensions/offlineshop/models.py b/lnbits/extensions/offlineshop/models.py
index 06225351c..0128fdb84 100644
--- a/lnbits/extensions/offlineshop/models.py
+++ b/lnbits/extensions/offlineshop/models.py
@@ -1,14 +1,15 @@
-import json
import base64
import hashlib
+import json
from collections import OrderedDict
+from typing import Dict, List, Optional
-from typing import Optional, List, Dict
from lnurl import encode as lnurl_encode # type: ignore
-from lnurl.types import LnurlPayMetadata # type: ignore
from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore
+from lnurl.types import LnurlPayMetadata # type: ignore
from pydantic import BaseModel
from starlette.requests import Request
+
from .helpers import totp
shop_counters: Dict = {}
diff --git a/lnbits/extensions/offlineshop/views.py b/lnbits/extensions/offlineshop/views.py
index e1d3a66e3..34bb7a03e 100644
--- a/lnbits/extensions/offlineshop/views.py
+++ b/lnbits/extensions/offlineshop/views.py
@@ -3,18 +3,18 @@ from datetime import datetime
from http import HTTPStatus
from typing import List
+from fastapi import HTTPException, Request
from fastapi.params import Depends, Query
from starlette.responses import HTMLResponse
-from lnbits.decorators import check_user_exists
-from lnbits.core.models import Payment, User
from lnbits.core.crud import get_standalone_payment
+from lnbits.core.models import Payment, User
from lnbits.core.views.api import api_payment
+from lnbits.decorators import check_user_exists
from . import offlineshop_ext, offlineshop_renderer
-from .models import Item
from .crud import get_item, get_shop
-from fastapi import Request, HTTPException
+from .models import Item
@offlineshop_ext.get("/", response_class=HTMLResponse)
diff --git a/lnbits/extensions/satspay/tasks.py b/lnbits/extensions/satspay/tasks.py
index 7ee6298c5..d325405b8 100644
--- a/lnbits/extensions/satspay/tasks.py
+++ b/lnbits/extensions/satspay/tasks.py
@@ -19,7 +19,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "charge" != payment.extra.get("tag"):
+ if payment.extra.get("tag") != "charge":
# not a charge invoice
return
diff --git a/lnbits/extensions/splitpayments/migrations.py b/lnbits/extensions/splitpayments/migrations.py
index 735afc6c3..b3921c42a 100644
--- a/lnbits/extensions/splitpayments/migrations.py
+++ b/lnbits/extensions/splitpayments/migrations.py
@@ -14,3 +14,41 @@ async def m001_initial(db):
);
"""
)
+
+
+async def m002_float_percent(db):
+ """
+ Add float percent and migrates the existing data.
+ """
+ await db.execute("ALTER TABLE splitpayments.targets RENAME TO splitpayments_old")
+ await db.execute(
+ """
+ CREATE TABLE splitpayments.targets (
+ wallet TEXT NOT NULL,
+ source TEXT NOT NULL,
+ percent REAL NOT NULL CHECK (percent >= 0 AND percent <= 100),
+ alias TEXT,
+
+ UNIQUE (source, wallet)
+ );
+ """
+ )
+
+ for row in [
+ list(row)
+ for row in await db.fetchall("SELECT * FROM splitpayments.splitpayments_old")
+ ]:
+ await db.execute(
+ """
+ INSERT INTO splitpayments.targets (
+ wallet,
+ source,
+ percent,
+ alias
+ )
+ VALUES (?, ?, ?, ?)
+ """,
+ (row[0], row[1], row[2], row[3]),
+ )
+
+ await db.execute("DROP TABLE splitpayments.splitpayments_old")
diff --git a/lnbits/extensions/splitpayments/models.py b/lnbits/extensions/splitpayments/models.py
index 3264bca7c..4b95ed18b 100644
--- a/lnbits/extensions/splitpayments/models.py
+++ b/lnbits/extensions/splitpayments/models.py
@@ -7,14 +7,14 @@ from pydantic import BaseModel
class Target(BaseModel):
wallet: str
source: str
- percent: int
+ percent: float
alias: Optional[str]
class TargetPutList(BaseModel):
wallet: str = Query(...)
alias: str = Query("")
- percent: int = Query(..., ge=1)
+ percent: float = Query(..., ge=0.01)
class TargetPut(BaseModel):
diff --git a/lnbits/extensions/splitpayments/static/js/index.js b/lnbits/extensions/splitpayments/static/js/index.js
index d9750bef1..5d326231d 100644
--- a/lnbits/extensions/splitpayments/static/js/index.js
+++ b/lnbits/extensions/splitpayments/static/js/index.js
@@ -105,7 +105,7 @@ new Vue({
if (currentTotal > 100 && isPercent) {
let diff = (currentTotal - 100) / (100 - this.targets[index].percent)
this.targets.forEach((target, t) => {
- if (t !== index) target.percent -= Math.round(diff * target.percent)
+ if (t !== index) target.percent -= +(diff * target.percent).toFixed(2)
})
}
diff --git a/lnbits/extensions/splitpayments/tasks.py b/lnbits/extensions/splitpayments/tasks.py
index 914e9bd29..0948e849a 100644
--- a/lnbits/extensions/splitpayments/tasks.py
+++ b/lnbits/extensions/splitpayments/tasks.py
@@ -22,7 +22,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "splitpayments" == payment.extra.get("tag") or payment.extra.get("splitted"):
+ if payment.extra.get("tag") == "splitpayments" or payment.extra.get("splitted"):
# already splitted, ignore
return
diff --git a/lnbits/extensions/splitpayments/templates/splitpayments/index.html b/lnbits/extensions/splitpayments/templates/splitpayments/index.html
index 1aae4e334..5862abc16 100644
--- a/lnbits/extensions/splitpayments/templates/splitpayments/index.html
+++ b/lnbits/extensions/splitpayments/templates/splitpayments/index.html
@@ -58,14 +58,14 @@
>
-
-
+
+
Clear
-
+
-
+
Save Targets
-
-
+
+
diff --git a/lnbits/extensions/subdomains/cloudflare.py b/lnbits/extensions/subdomains/cloudflare.py
index 8ada2a908..679ca8436 100644
--- a/lnbits/extensions/subdomains/cloudflare.py
+++ b/lnbits/extensions/subdomains/cloudflare.py
@@ -1,5 +1,8 @@
+import json
+
+import httpx
+
from lnbits.extensions.subdomains.models import Domains
-import httpx, json
async def cloudflare_create_subdomain(
diff --git a/lnbits/extensions/subdomains/tasks.py b/lnbits/extensions/subdomains/tasks.py
index 75223e824..d8f351618 100644
--- a/lnbits/extensions/subdomains/tasks.py
+++ b/lnbits/extensions/subdomains/tasks.py
@@ -19,7 +19,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "lnsubdomain" != payment.extra.get("tag"):
+ if payment.extra.get("tag") != "lnsubdomain":
# not an lnurlp invoice
return
diff --git a/lnbits/extensions/tpos/__init__.py b/lnbits/extensions/tpos/__init__.py
index 1aed95bac..3ce618aa6 100644
--- a/lnbits/extensions/tpos/__init__.py
+++ b/lnbits/extensions/tpos/__init__.py
@@ -16,8 +16,8 @@ def tpos_renderer():
from .tasks import wait_for_paid_invoices
-from .views_api import * # noqa
from .views import * # noqa
+from .views_api import * # noqa
def tpos_start():
diff --git a/lnbits/extensions/tpos/tasks.py b/lnbits/extensions/tpos/tasks.py
index 0bb8dff92..01c11428d 100644
--- a/lnbits/extensions/tpos/tasks.py
+++ b/lnbits/extensions/tpos/tasks.py
@@ -20,7 +20,7 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
- if "tpos" == payment.extra.get("tag") and payment.extra.get("tipSplitted"):
+ if payment.extra.get("tag") == "tpos" and payment.extra.get("tipSplitted"):
# already splitted, ignore
return
diff --git a/lnbits/extensions/tpos/views.py b/lnbits/extensions/tpos/views.py
index 21a471c4a..e1f1d21e3 100644
--- a/lnbits/extensions/tpos/views.py
+++ b/lnbits/extensions/tpos/views.py
@@ -8,10 +8,7 @@ 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 lnbits.settings import LNBITS_CUSTOM_LOGO, LNBITS_SITE_TITLE
from . import tpos_ext, tpos_renderer
from .crud import get_tpos
diff --git a/lnbits/extensions/tpos/views_api.py b/lnbits/extensions/tpos/views_api.py
index 6a4e5c43e..9567f98a6 100644
--- a/lnbits/extensions/tpos/views_api.py
+++ b/lnbits/extensions/tpos/views_api.py
@@ -2,9 +2,8 @@ from http import HTTPStatus
from fastapi import Query
from fastapi.params import Depends
-from starlette.exceptions import HTTPException
-
from loguru import logger
+from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user
from lnbits.core.services import create_invoice
diff --git a/lnbits/extensions/usermanager/models.py b/lnbits/extensions/usermanager/models.py
index 67facec68..15f50e288 100644
--- a/lnbits/extensions/usermanager/models.py
+++ b/lnbits/extensions/usermanager/models.py
@@ -1,8 +1,8 @@
from sqlite3 import Row
+from typing import Optional
from fastapi.param_functions import Query
from pydantic import BaseModel
-from typing import Optional
class CreateUserData(BaseModel):
diff --git a/lnbits/extensions/usermanager/views_api.py b/lnbits/extensions/usermanager/views_api.py
index a36b36bbb..7e7b7653a 100644
--- a/lnbits/extensions/usermanager/views_api.py
+++ b/lnbits/extensions/usermanager/views_api.py
@@ -75,7 +75,7 @@ async def api_usermanager_activate_extension(
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="User does not exist."
)
- update_user_extension(user_id=userid, extension=extension, active=active)
+ await update_user_extension(user_id=userid, extension=extension, active=active)
return {"extension": "updated"}
diff --git a/lnbits/extensions/withdraw/lnurl.py b/lnbits/extensions/withdraw/lnurl.py
index 05b3908c2..18a99599c 100644
--- a/lnbits/extensions/withdraw/lnurl.py
+++ b/lnbits/extensions/withdraw/lnurl.py
@@ -1,15 +1,13 @@
import json
import traceback
-import httpx
-
from datetime import datetime
from http import HTTPStatus
-from loguru import logger
-
+import httpx
import shortuuid # type: ignore
from fastapi import HTTPException
from fastapi.param_functions import Query
+from loguru import logger
from starlette.requests import Request
from starlette.responses import HTMLResponse # type: ignore
diff --git a/lnbits/extensions/withdraw/static/js/index.js b/lnbits/extensions/withdraw/static/js/index.js
index e54005c69..3f484debf 100644
--- a/lnbits/extensions/withdraw/static/js/index.js
+++ b/lnbits/extensions/withdraw/static/js/index.js
@@ -53,6 +53,7 @@ new Vue({
rowsPerPage: 10
}
},
+ nfcTagWriting: false,
formDialog: {
show: false,
secondMultiplier: 'seconds',
@@ -231,6 +232,42 @@ new Vue({
})
})
},
+ writeNfcTag: async function (lnurl) {
+ try {
+ if (typeof NDEFReader == 'undefined') {
+ throw {
+ toString: function () {
+ return 'NFC not supported on this device or browser.'
+ }
+ }
+ }
+
+ const ndef = new NDEFReader()
+
+ this.nfcTagWriting = true
+ this.$q.notify({
+ message: 'Tap your NFC tag to write the LNURL-withdraw link to it.'
+ })
+
+ await ndef.write({
+ records: [{recordType: 'url', data: 'lightning:' + lnurl, lang: 'en'}]
+ })
+
+ this.nfcTagWriting = false
+ this.$q.notify({
+ type: 'positive',
+ message: 'NFC tag written successfully.'
+ })
+ } catch (error) {
+ this.nfcTagWriting = false
+ this.$q.notify({
+ type: 'negative',
+ message: error
+ ? error.toString()
+ : 'An unexpected error has occurred.'
+ })
+ }
+ },
exportCSV: function () {
LNbits.utils.exportCSV(this.paywallsTable.columns, this.paywalls)
}
diff --git a/lnbits/extensions/withdraw/templates/withdraw/display.html b/lnbits/extensions/withdraw/templates/withdraw/display.html
index 5552c77ff..1e632741c 100644
--- a/lnbits/extensions/withdraw/templates/withdraw/display.html
+++ b/lnbits/extensions/withdraw/templates/withdraw/display.html
@@ -13,14 +13,22 @@
:value="this.here + '/?lightning={{lnurl }}'"
:options="{width: 800}"
class="rounded-borders"
- >
+ >
+
-
+
Copy LNURL
+
@@ -51,7 +59,8 @@
mixins: [windowMixin],
data: function () {
return {
- here: location.protocol + '//' + location.host
+ here: location.protocol + '//' + location.host,
+ nfcTagWriting: false
}
}
})
diff --git a/lnbits/extensions/withdraw/templates/withdraw/index.html b/lnbits/extensions/withdraw/templates/withdraw/index.html
index 6d3ab374a..99aa03b2d 100644
--- a/lnbits/extensions/withdraw/templates/withdraw/index.html
+++ b/lnbits/extensions/withdraw/templates/withdraw/index.html
@@ -369,6 +369,13 @@
@click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')"
>Shareable link
+
b.name
+ const nameA = a.name.toUpperCase()
+ const nameB = b.name.toUpperCase()
+ return nameA < nameB ? -1 : nameA > nameB ? 1 : 0
})
)
+
+ this.g.extensions = extensions
}
}
}
diff --git a/lnbits/tasks.py b/lnbits/tasks.py
index 69aa19066..86863f98f 100644
--- a/lnbits/tasks.py
+++ b/lnbits/tasks.py
@@ -1,22 +1,20 @@
-import time
import asyncio
+import time
import traceback
from http import HTTPStatus
-from typing import List, Callable
-
-from loguru import logger
+from typing import Callable, List
from fastapi.exceptions import HTTPException
+from loguru import logger
-from lnbits.settings import WALLET
from lnbits.core.crud import (
- get_payments,
- get_standalone_payment,
delete_expired_invoices,
get_balance_checks,
+ get_payments,
+ get_standalone_payment,
)
from lnbits.core.services import redeem_lnurl_withdraw
-
+from lnbits.settings import WALLET
deferred_async: List[Callable] = []
diff --git a/lnbits/templates/base.html b/lnbits/templates/base.html
index 6ab1ec840..acca92e7a 100644
--- a/lnbits/templates/base.html
+++ b/lnbits/templates/base.html
@@ -228,7 +228,6 @@