Some checks failed
lint.yml / feat: lnurlw_list_links + lnurlw_unique_hashes transport RPCs (push) Failing after 0s
Two additions surface withdraw-extension capabilities the ATM use case in aiolabs/lamassu-next (issues #24, #25) needs but couldn't reach over the nostr transport before: ## lnurlw_list_links (AUTH_ACCOUNT) Enumerate withdraw links across all wallets owned by the calling account, with `limit`/`offset` pagination matching the existing HTTP `/api/v1/links`. Lets an ATM (or any client) re-discover its links after a reconnect without having to keep its own index. If `request.wallet_id` is supplied and matches one of the account's wallets, narrows the listing to just that wallet — mirrors lnurlp's list semantics. Returns `{data: [...links], total: <int>}`. ## lnurlw_unique_hashes (AUTH_WALLET) For an `is_unique=True` link, return the per-use `id_unique_hash` values derived from each unredeemed slot in `link.usescsv`. Mirrors the formula in `helpers.py:create_lnurl:13`: id_unique_hash = shortuuid.uuid(name=link.id + link.unique_hash + index) Without this RPC an ATM that wants to generate distinct QR codes per use (lamassu-next #25) had to reimplement the derivation client-side — fragile if the extension's hash format ever changes upstream. With this RPC the ATM asks the server for the canonical list of unredeemed hashes; each one becomes the trailing path component of `/withdraw/api/v1/lnurl/<unique_hash>/<id_unique_hash>`. `is_unique=False` links return an empty `unredeemed_hashes` list; the base `unique_hash` alone identifies the callback path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
from fastapi import APIRouter
|
|
|
|
from .crud import db
|
|
from .views import withdraw_ext_generic
|
|
from .views_api import withdraw_ext_api
|
|
from .views_lnurl import withdraw_ext_lnurl
|
|
|
|
withdraw_static_files = [
|
|
{
|
|
"path": "/withdraw/static",
|
|
"name": "withdraw_static",
|
|
}
|
|
]
|
|
|
|
withdraw_ext: APIRouter = APIRouter(prefix="/withdraw", tags=["withdraw"])
|
|
withdraw_ext.include_router(withdraw_ext_generic)
|
|
withdraw_ext.include_router(withdraw_ext_api)
|
|
withdraw_ext.include_router(withdraw_ext_lnurl)
|
|
|
|
|
|
def withdraw_start() -> None:
|
|
"""
|
|
Register this extension's RPCs with the LNbits nostr transport so an
|
|
HTTP-allergic client (e.g. lamassu-next ATM) can manage LNURL-withdraw
|
|
links without touching the HTTP API. Also wires the link-owner
|
|
resolver so subscribe_payments({tag:"withdraw", link_id:...}) can
|
|
verify ownership.
|
|
|
|
No-op if the core transport module isn't present in the LNbits build.
|
|
No runtime `if nostr_transport_enabled` guard is needed — when
|
|
disabled, the relay pool never publishes, so registered RPCs are
|
|
simply unreachable.
|
|
"""
|
|
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_lnurlw_create_link,
|
|
handle_lnurlw_delete_link,
|
|
handle_lnurlw_get_link,
|
|
handle_lnurlw_list_links,
|
|
handle_lnurlw_unique_hashes,
|
|
handle_lnurlw_update_link,
|
|
resolve_withdraw_owner,
|
|
)
|
|
|
|
register_rpc("lnurlw_create_link", handle_lnurlw_create_link, AUTH_WALLET)
|
|
register_rpc("lnurlw_get_link", handle_lnurlw_get_link, AUTH_WALLET)
|
|
register_rpc("lnurlw_list_links", handle_lnurlw_list_links, AUTH_ACCOUNT)
|
|
register_rpc("lnurlw_unique_hashes", handle_lnurlw_unique_hashes, AUTH_WALLET)
|
|
register_rpc("lnurlw_update_link", handle_lnurlw_update_link, AUTH_WALLET)
|
|
register_rpc("lnurlw_delete_link", handle_lnurlw_delete_link, AUTH_WALLET)
|
|
register_link_owner_resolver(
|
|
"withdraw", resolve_withdraw_owner, link_extra_key="withdrawal_link_id"
|
|
)
|
|
|
|
|
|
__all__ = ["db", "withdraw_ext", "withdraw_start", "withdraw_static_files"]
|