feat: remove lnurl from api (#91)

This commit is contained in:
dni ⚡ 2025-08-18 10:55:13 +02:00 committed by GitHub
commit 4784ebc9f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 48 deletions

View file

@ -1,9 +1,7 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Optional from typing import Optional
from fastapi import Query, Request from fastapi import Query
from lnbits.helpers import normalize_path
from lnurl import encode as lnurl_encode
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .helpers import parse_nostr_private_key from .helpers import parse_nostr_private_key
@ -62,14 +60,6 @@ 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. # TODO deprecated, unused in the code, should be deleted from db.
domain: Optional[str] = None domain: Optional[str] = None
def lnurl(self, req: Request) -> str:
url = req.url_for("lnurlp.api_lnurl_response", link_id=self.id)
url = url.replace(path=normalize_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)

View file

@ -1,7 +1,7 @@
{% extends "print.html" %} {% block page %} {% extends "print.html" %} {% block page %}
<div class="row justify-center"> <div class="row justify-center">
<div class="qr"> <div class="qr">
<lnbits-qrcode value="lightning:{{ lnurl }}"></lnbits-qrcode> <lnbits-qrcode :value="lnurl"></lnbits-qrcode>
</div> </div>
</div> </div>
{% endblock %} {% block styles %} {% endblock %} {% block styles %}
@ -15,10 +15,16 @@
window.app = Vue.createApp({ window.app = Vue.createApp({
el: '#vue', el: '#vue',
created() { created() {
const url = window.location.origin + '/lnurlp/{{ link_id }}'
const bytes = new TextEncoder().encode(url)
const bech32 = NostrTools.nip19.encodeBytes('lnurl', bytes)
this.lnurl = `lightning:${bech32.toUpperCase()}`
window.print() window.print()
}, },
data() { data() {
return {width: window.innerWidth * 0.5} return {
width: window.innerWidth * 0.5
}
} }
}) })
</script> </script>

View file

@ -41,5 +41,5 @@ async def print_qr(request: Request, link_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist."
) )
ctx = {"request": request, "lnurl": link.lnurl(req=request)} ctx = {"request": request, "link_id": link.id}
return lnurlp_renderer().TemplateResponse("lnurlp/print_qr.html", ctx) return lnurlp_renderer().TemplateResponse("lnurlp/print_qr.html", ctx)

View file

@ -3,16 +3,14 @@ import re
from http import HTTPStatus from http import HTTPStatus
from typing import Optional from typing import Optional
from fastapi import APIRouter, Depends, Query, Request from fastapi import APIRouter, Depends, HTTPException, Query
from lnbits.core.crud import get_user, get_wallet from lnbits.core.crud import get_user, get_wallet
from lnbits.core.models import WalletTypeInfo from lnbits.core.models import SimpleStatus, WalletTypeInfo
from lnbits.decorators import ( from lnbits.decorators import (
check_admin, check_admin,
require_admin_key, require_admin_key,
require_invoice_key, require_invoice_key,
) )
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl
from starlette.exceptions import HTTPException
from .crud import ( from .crud import (
create_pay_link, create_pay_link,
@ -26,43 +24,29 @@ from .crud import (
update_pay_link, update_pay_link,
) )
from .helpers import parse_nostr_private_key from .helpers import parse_nostr_private_key
from .models import CreatePayLinkData, LnurlpSettings from .models import CreatePayLinkData, LnurlpSettings, PayLink
lnurlp_api_router = APIRouter() lnurlp_api_router = APIRouter()
@lnurlp_api_router.get("/api/v1/links", status_code=HTTPStatus.OK) @lnurlp_api_router.get("/api/v1/links", status_code=HTTPStatus.OK)
async def api_links( async def api_links(
req: Request,
key_info: WalletTypeInfo = Depends(require_invoice_key), key_info: WalletTypeInfo = Depends(require_invoice_key),
all_wallets: bool = Query(False), all_wallets: bool = Query(False),
): ) -> list[PayLink]:
wallet_ids = [key_info.wallet.id] wallet_ids = [key_info.wallet.id]
if all_wallets: if all_wallets:
user = await get_user(key_info.wallet.user) user = await get_user(key_info.wallet.user)
wallet_ids = user.wallet_ids if user else [] wallet_ids = user.wallet_ids if user else []
try: links = await get_pay_links(wallet_ids)
return [ return links
{**link.dict(), "lnurl": link.lnurl(req)}
for link in await get_pay_links(wallet_ids)
]
except LnurlInvalidUrl as exc:
raise HTTPException(
status_code=HTTPStatus.UPGRADE_REQUIRED,
detail=(
"LNURLs need to be delivered over a publicly "
"accessible `https` domain or Tor onion."
),
) from exc
@lnurlp_api_router.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) @lnurlp_api_router.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_retrieve( async def api_link_retrieve(
r: Request, link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key)
): ) -> PayLink:
link = await get_pay_link(link_id) link = await get_pay_link(link_id)
if not link: if not link:
@ -79,8 +63,7 @@ async def api_link_retrieve(
raise HTTPException( raise HTTPException(
detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
) )
return link
return {**link.dict(), **{"lnurl": link.lnurl(r)}}
async def check_username_exists(username: str): async def check_username_exists(username: str):
@ -96,10 +79,9 @@ async def check_username_exists(username: str):
@lnurlp_api_router.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) @lnurlp_api_router.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_create_or_update( async def api_link_create_or_update(
data: CreatePayLinkData, data: CreatePayLinkData,
request: Request,
link_id: Optional[str] = None, link_id: Optional[str] = None,
key_info: WalletTypeInfo = Depends(require_admin_key), key_info: WalletTypeInfo = Depends(require_admin_key),
): ) -> PayLink:
if data.min > data.max: if data.min > data.max:
raise HTTPException( raise HTTPException(
detail="Min is greater than max.", status_code=HTTPStatus.BAD_REQUEST detail="Min is greater than max.", status_code=HTTPStatus.BAD_REQUEST
@ -192,14 +174,13 @@ async def api_link_create_or_update(
link = await create_pay_link(data) link = await create_pay_link(data)
assert link return link
return {**link.dict(), "lnurl": link.lnurl(request)}
@lnurlp_api_router.delete("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) @lnurlp_api_router.delete("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_delete( async def api_link_delete(
link_id: str, key_info: WalletTypeInfo = Depends(require_admin_key) link_id: str, key_info: WalletTypeInfo = Depends(require_admin_key)
): ) -> SimpleStatus:
link = await get_pay_link(link_id) link = await get_pay_link(link_id)
if not link: if not link:
@ -207,7 +188,7 @@ async def api_link_delete(
detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND
) )
# admins are allowed to delete paylinks beloging to regular users # admins are allowed to delete paylinks belonging to regular users
user = await get_user(key_info.wallet.user) user = await get_user(key_info.wallet.user)
admin_user = user.admin if user else False admin_user = user.admin if user else False
if not admin_user and link.wallet != key_info.wallet.id: if not admin_user and link.wallet != key_info.wallet.id:
@ -216,7 +197,7 @@ async def api_link_delete(
) )
await delete_pay_link(link_id) await delete_pay_link(link_id)
return {"success": True} return SimpleStatus(success=True, message="Deleted Pay link")
@lnurlp_api_router.get("/api/v1/settings", dependencies=[Depends(check_admin)]) @lnurlp_api_router.get("/api/v1/settings", dependencies=[Depends(check_admin)])