refactor: dont use model property for lnurlpaymetadata (#97)

* refactor: dont use model property for lnurlpaymetadata
domain is really only needed if you do it with via the property. cleans
up code and makes it more readable
This commit is contained in:
dni ⚡ 2025-08-18 10:49:25 +02:00 committed by GitHub
commit 1d91b50a67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 29 deletions

View file

@ -55,7 +55,6 @@ async def create_pay_link(data: CreatePayLinkData) -> PayLink:
served_pr=0, served_pr=0,
username=data.username, username=data.username,
zaps=data.zaps, zaps=data.zaps,
domain=None,
webhook_url=data.webhook_url, webhook_url=data.webhook_url,
webhook_headers=data.webhook_headers, webhook_headers=data.webhook_headers,
webhook_body=data.webhook_body, webhook_body=data.webhook_body,

View file

@ -1,10 +1,9 @@
import json
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Optional
from fastapi import Query, Request from fastapi import Query, Request
from lnbits.helpers import normalize_path from lnbits.helpers import normalize_path
from lnurl import encode as lnurl_encode from lnurl import encode as lnurl_encode
from lnurl.types import LnurlPayMetadata
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .helpers import parse_nostr_private_key from .helpers import parse_nostr_private_key
@ -54,7 +53,6 @@ class PayLink(BaseModel):
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
username: str | None = None username: str | None = None
zaps: bool | None = None zaps: bool | None = None
domain: str | None = None
webhook_url: str | None = None webhook_url: str | None = None
webhook_headers: str | None = None webhook_headers: str | None = None
webhook_body: str | None = None webhook_body: str | None = None
@ -64,6 +62,8 @@ class PayLink(BaseModel):
fiat_base_multiplier: int | None = None fiat_base_multiplier: int | None = None
disposable: bool disposable: bool
# TODO deprecated, unused in the code, should be deleted from db.
domain: Optional[str] = None
def lnurl(self, req: Request) -> str: def lnurl(self, req: Request) -> str:
url = req.url_for("lnurlp.api_lnurl_response", link_id=self.id) url = req.url_for("lnurlp.api_lnurl_response", link_id=self.id)
@ -73,14 +73,3 @@ class PayLink(BaseModel):
# change url string scheme to http # change url string scheme to http
url_str = url_str.replace("https://", "http://") url_str = url_str.replace("https://", "http://")
return lnurl_encode(url_str) return lnurl_encode(url_str)
@property
def lnurlpay_metadata(self) -> LnurlPayMetadata:
if self.domain and self.username:
text = f"Payment to {self.username}"
identifier = f"{self.username}@{self.domain}"
metadata = [["text/plain", text], ["text/identifier", identifier]]
else:
metadata = [["text/plain", self.description]]
return LnurlPayMetadata(json.dumps(metadata))

View file

@ -1,3 +1,4 @@
import json
from http import HTTPStatus from http import HTTPStatus
from typing import Optional from typing import Optional
@ -9,6 +10,7 @@ from lnurl import (
LightningInvoice, LightningInvoice,
LnurlErrorResponse, LnurlErrorResponse,
LnurlPayActionResponse, LnurlPayActionResponse,
LnurlPayMetadata,
LnurlPayResponse, LnurlPayResponse,
LnurlPaySuccessActionTag, LnurlPaySuccessActionTag,
Max144Str, Max144Str,
@ -78,10 +80,6 @@ async def api_lnurl_callback(
) )
) )
# for lnaddress, we have to set this otherwise
# the metadata won't have the identifier
link.domain = request.url.netloc
extra = { extra = {
"tag": "lnurlp", "tag": "lnurlp",
"link": link.id, "link": link.id,
@ -99,11 +97,18 @@ async def api_lnurl_callback(
if nostr: if nostr:
extra["nostr"] = nostr # put it here for later publishing in tasks.py extra["nostr"] = nostr # put it here for later publishing in tasks.py
if link.username and link.domain: if link.username:
extra["lnaddress"] = f"{link.username}@{link.domain}" identifier = f"{link.username}@{request.url.netloc}"
text = f"Payment to {link.username}"
_metadata = [["text/plain", text], ["text/identifier", identifier]]
extra["lnaddress"] = identifier
else:
_metadata = [["text/plain", link.description]]
metadata = LnurlPayMetadata(json.dumps(_metadata))
# we take the zap request as the description instead of the metadata if present # we take the zap request as the description instead of the metadata if present
unhashed_description = nostr.encode() if nostr else link.lnurlpay_metadata.encode() unhashed_description = nostr.encode() if nostr else metadata.encode()
payment = await create_invoice( payment = await create_invoice(
wallet_id=link.wallet, wallet_id=link.wallet,
@ -159,19 +164,20 @@ async def api_lnurl_response(
if webhook_data: if webhook_data:
url = url.include_query_params(webhook_data=webhook_data) url = url.include_query_params(webhook_data=webhook_data)
link.domain = request.url.netloc
callback_url = parse_obj_as(CallbackUrl, str(url)) callback_url = parse_obj_as(CallbackUrl, str(url))
if link.username:
identifier = f"{link.username}@{request.url.netloc}"
text = f"Payment to {link.username}"
metadata = [["text/plain", text], ["text/identifier", identifier]]
else:
metadata = [["text/plain", link.description]]
res = LnurlPayResponse( res = LnurlPayResponse(
callback=callback_url, callback=callback_url,
minSendable=MilliSatoshi(round(link.min * rate) * 1000), minSendable=MilliSatoshi(round(link.min * rate) * 1000),
maxSendable=MilliSatoshi(round(link.max * rate) * 1000), maxSendable=MilliSatoshi(round(link.max * rate) * 1000),
metadata=link.lnurlpay_metadata, metadata=LnurlPayMetadata(json.dumps(metadata)),
# todo library bug should not be in issue to onot specify
payerData=None,
commentAllowed=None,
allowsNostr=None,
nostrPubkey=None,
) )
if link.comment_chars > 0: if link.comment_chars > 0: