From 79762124ede2f36ce0bdfb21ac636b0a3bacb903 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 3 Oct 2025 11:30:08 +0300 Subject: [PATCH 1/7] fix: add `lnurl` field back --- helpers.py | 13 +++++++++++++ models.py | 1 + views_api.py | 10 +++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/helpers.py b/helpers.py index f4b3d89..75fdb7d 100644 --- a/helpers.py +++ b/helpers.py @@ -1,3 +1,6 @@ +from fastapi import Request +from lnurl import encode as lnurl_encode + from .nostr.key import PrivateKey @@ -6,3 +9,13 @@ def parse_nostr_private_key(key: str) -> PrivateKey: return PrivateKey.from_nsec(key) else: return PrivateKey(bytes.fromhex(key)) + + +def lnurl_encode_link_id(req: Request, link_id: str) -> str: + url = req.url_for("lnurlp.api_lnurl_response", link_id=link_id) + url = url.replace(path=url.path) + url_str = str(url) + if url.netloc.endswith(".onion"): + # change url string scheme to http + url_str = url_str.replace("https://", "http://") + return lnurl_encode(url_str) diff --git a/models.py b/models.py index e6b6cfa..ce00000 100644 --- a/models.py +++ b/models.py @@ -48,6 +48,7 @@ class PayLink(BaseModel): comment_chars: int created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + lnurl: str | None = None username: str | None = None zaps: bool | None = None webhook_url: str | None = None diff --git a/views_api.py b/views_api.py index 98d2118..7604680 100644 --- a/views_api.py +++ b/views_api.py @@ -2,7 +2,7 @@ import re from http import HTTPStatus -from fastapi import APIRouter, Depends, HTTPException, Query +from fastapi import APIRouter, Depends, HTTPException, Query, Request from lnbits.core.crud import get_user, get_wallet from lnbits.core.models import SimpleStatus, WalletTypeInfo from lnbits.decorators import ( @@ -22,7 +22,7 @@ update_lnurlp_settings, update_pay_link, ) -from .helpers import parse_nostr_private_key +from .helpers import lnurl_encode_link_id, parse_nostr_private_key from .models import CreatePayLinkData, LnurlpSettings, PayLink lnurlp_api_router = APIRouter() @@ -44,7 +44,7 @@ async def api_links( @lnurlp_api_router.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) async def api_link_retrieve( - link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) + req: Request, link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) ) -> PayLink: link = await get_pay_link(link_id) @@ -62,6 +62,8 @@ async def api_link_retrieve( raise HTTPException( detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN ) + + link.lnurl = lnurl_encode_link_id(req, link.id) return link @@ -77,6 +79,7 @@ async def check_username_exists(username: str): @lnurlp_api_router.post("/api/v1/links", status_code=HTTPStatus.CREATED) @lnurlp_api_router.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) async def api_link_create_or_update( + req: Request, data: CreatePayLinkData, link_id: str | None = None, key_info: WalletTypeInfo = Depends(require_admin_key), @@ -172,6 +175,7 @@ async def api_link_create_or_update( link = await create_pay_link(data) + link.lnurl = lnurl_encode_link_id(req, link.id) return link From 757c7d02caa5b0cf3ec2194e6694fd1c00707410 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 3 Oct 2025 11:40:51 +0300 Subject: [PATCH 2/7] fix: do not store lnurl --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models.py b/models.py index ce00000..07a1076 100644 --- a/models.py +++ b/models.py @@ -48,7 +48,7 @@ class PayLink(BaseModel): comment_chars: int created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) - lnurl: str | None = None + lnurl: str | None = Field(default=None, no_database=True) username: str | None = None zaps: bool | None = None webhook_url: str | None = None From abc36a9001ab4f6ec0c942ecbb6236e084a54e43 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 3 Oct 2025 11:41:00 +0300 Subject: [PATCH 3/7] feat: add lnurl for list --- views_api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/views_api.py b/views_api.py index 7604680..1c0e6e6 100644 --- a/views_api.py +++ b/views_api.py @@ -39,6 +39,8 @@ async def api_links( wallet_ids = user.wallet_ids if user else [] links = await get_pay_links(wallet_ids) + for link in links: + link.lnurl = lnurl_encode_link_id(req=None, link_id=link.id) return links From d9c12d2224a0168b7d99c25032a14b05ef54f9dc Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 3 Oct 2025 11:41:12 +0300 Subject: [PATCH 4/7] fix: use bach32 --- helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers.py b/helpers.py index 75fdb7d..8daf5b9 100644 --- a/helpers.py +++ b/helpers.py @@ -18,4 +18,4 @@ def lnurl_encode_link_id(req: Request, link_id: str) -> str: if url.netloc.endswith(".onion"): # change url string scheme to http url_str = url_str.replace("https://", "http://") - return lnurl_encode(url_str) + return str(lnurl_encode(url_str).bech32) # type: ignore From 7a307af5f748802961c6f658973cf281d8ccf062 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 3 Oct 2025 11:44:45 +0300 Subject: [PATCH 5/7] fix: missing param --- views_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views_api.py b/views_api.py index 1c0e6e6..6d9bb86 100644 --- a/views_api.py +++ b/views_api.py @@ -30,6 +30,7 @@ @lnurlp_api_router.get("/api/v1/links", status_code=HTTPStatus.OK) async def api_links( + req: Request, key_info: WalletTypeInfo = Depends(require_invoice_key), all_wallets: bool = Query(False), ) -> list[PayLink]: @@ -40,7 +41,7 @@ async def api_links( links = await get_pay_links(wallet_ids) for link in links: - link.lnurl = lnurl_encode_link_id(req=None, link_id=link.id) + link.lnurl = lnurl_encode_link_id(req=req, link_id=link.id) return links From e52858f0bd3cce552ae630de6ad00eb921a54c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Fri, 3 Oct 2025 13:24:11 +0200 Subject: [PATCH 6/7] add deprecating message to model `Field` --- models.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/models.py b/models.py index 07a1076..d8e6d6d 100644 --- a/models.py +++ b/models.py @@ -48,7 +48,16 @@ class PayLink(BaseModel): comment_chars: int created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) - lnurl: str | None = Field(default=None, no_database=True) + lnurl: str | None = Field( + default=None, + no_database=True, + deprecated=True, + description=( + "Deprecated: Instead of using this bech32 encoded string, dynamically " + "generate your own static link (lud17/bech32) on the client side. " + "Example: lnurlp://${window.location.hostname}/lnurlp/${paylink_id}" + ), + ) username: str | None = None zaps: bool | None = None webhook_url: str | None = None From 735584aa7c33896f064bd417fd9593bb0efd2e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Fri, 3 Oct 2025 13:25:03 +0200 Subject: [PATCH 7/7] ignore not needed --- helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers.py b/helpers.py index 8daf5b9..ecc45f1 100644 --- a/helpers.py +++ b/helpers.py @@ -18,4 +18,4 @@ def lnurl_encode_link_id(req: Request, link_id: str) -> str: if url.netloc.endswith(".onion"): # change url string scheme to http url_str = url_str.replace("https://", "http://") - return str(lnurl_encode(url_str).bech32) # type: ignore + return str(lnurl_encode(url_str).bech32)