Some checks failed
lint.yml / feat: register transport RPCs over LNbits nostr transport (push) Failing after 0s
Mirrors what aiolabs/withdraw did — hooks lnurlp's existing CRUD into
the LNbits nostr transport layer so an HTTP-allergic client (e.g.
lamassu-next ATM) can manage PayLinks over kind-21000 encrypted
events instead of HTTP.
Extends the existing `lnurlp_start()` lifecycle hook (auto-invoked
by the LNbits extension manager) to import the transport's
`register_rpc` and register five RPCs:
lnurlp_create AUTH_WALLET
lnurlp_get AUTH_WALLET
lnurlp_list AUTH_ACCOUNT
lnurlp_update AUTH_WALLET
lnurlp_delete AUTH_WALLET
All handlers are thin shims around the existing crud.py functions —
no business logic duplication. *_get / *_update / *_delete verify
that the link's stored wallet matches the caller's wallet id.
Also registers a link-owner resolver with the core subscriptions
module (tag "lnurlp", extras-key "link" — the default, matching
where views_lnurl.py:86 stamps the link id on settlement). That lets
clients call `subscribe_payments({tag:"lnurlp", link_id:...})` and
stream real-time pay events without polling, with ownership enforced
server-side.
The transport import is guarded by try/except ImportError so this
extension still loads cleanly against an LNbits build that doesn't
have nostr_transport.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
89 lines
2.6 KiB
Python
89 lines
2.6 KiB
Python
import asyncio
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from .crud import db
|
|
from .tasks import wait_for_paid_invoices
|
|
from .views import lnurlp_generic_router
|
|
from .views_api import lnurlp_api_router
|
|
from .views_lnurl import lnurlp_lnurl_router
|
|
|
|
lnurlp_static_files = [
|
|
{
|
|
"path": "/lnurlp/static",
|
|
"name": "lnurlp_static",
|
|
}
|
|
]
|
|
|
|
lnurlp_redirect_paths = [
|
|
{
|
|
"from_path": "/.well-known/lnurlp",
|
|
"redirect_to_path": "/api/v1/well-known",
|
|
}
|
|
]
|
|
|
|
|
|
lnurlp_ext: APIRouter = APIRouter(prefix="/lnurlp", tags=["lnurlp"])
|
|
lnurlp_ext.include_router(lnurlp_generic_router)
|
|
lnurlp_ext.include_router(lnurlp_api_router)
|
|
lnurlp_ext.include_router(lnurlp_lnurl_router)
|
|
|
|
scheduled_tasks: list[asyncio.Task] = []
|
|
|
|
|
|
def lnurlp_stop():
|
|
for task in scheduled_tasks:
|
|
task.cancel()
|
|
|
|
|
|
def lnurlp_start():
|
|
from lnbits.tasks import create_permanent_unique_task
|
|
|
|
task = create_permanent_unique_task("lnurlp", wait_for_paid_invoices)
|
|
scheduled_tasks.append(task)
|
|
|
|
# Expose lnurlp's CRUD over the LNbits nostr transport so an HTTP-
|
|
# allergic client (e.g. lamassu-next ATM) can manage PayLinks over
|
|
# kind-21000 encrypted events. Also wires the link-owner resolver so
|
|
# `subscribe_payments({tag:"lnurlp", link_id:...})` can verify
|
|
# ownership of the underlying wallet. No-op if the core transport
|
|
# module isn't present in the LNbits build.
|
|
try:
|
|
from lnbits.core.services.nostr_transport.dispatcher import (
|
|
AUTH_ACCOUNT,
|
|
AUTH_WALLET,
|
|
register_rpc,
|
|
)
|
|
from lnbits.core.services.nostr_transport.subscriptions import (
|
|
register_link_owner_resolver,
|
|
)
|
|
except ImportError:
|
|
return
|
|
|
|
from .transport_rpcs import (
|
|
handle_lnurlp_create,
|
|
handle_lnurlp_delete,
|
|
handle_lnurlp_get,
|
|
handle_lnurlp_list,
|
|
handle_lnurlp_update,
|
|
resolve_lnurlp_owner,
|
|
)
|
|
|
|
register_rpc("lnurlp_create", handle_lnurlp_create, AUTH_WALLET)
|
|
register_rpc("lnurlp_get", handle_lnurlp_get, AUTH_WALLET)
|
|
register_rpc("lnurlp_list", handle_lnurlp_list, AUTH_ACCOUNT)
|
|
register_rpc("lnurlp_update", handle_lnurlp_update, AUTH_WALLET)
|
|
register_rpc("lnurlp_delete", handle_lnurlp_delete, AUTH_WALLET)
|
|
# lnurlp stamps `extra["link"] = link.id` on settlement
|
|
# (views_lnurl.py:86), which is the default extras-key, so no override.
|
|
register_link_owner_resolver("lnurlp", resolve_lnurlp_owner)
|
|
|
|
|
|
__all__ = [
|
|
"db",
|
|
"lnurlp_ext",
|
|
"lnurlp_redirect_paths",
|
|
"lnurlp_start",
|
|
"lnurlp_static_files",
|
|
"lnurlp_stop",
|
|
]
|