LNURL Integration
AltZap implements the open LUD-06 and LUD-16 standards to bridge Lightning Network wallets with Nostr identity resolution. The protocol rules — chain advertisement and the callback — are in NIP-AZ; this page is how Zapf applies them.
LUD-16: Internet Identifiers
LUD-16 allows Lightning wallets to resolve human-readable identifiers formatted like email addresses (e.g., user@example.com). Any compliant service can expose its identity graph to standard Lightning wallets through this mechanism. Because LNURL servers generate on-the-fly Lightning invoices for legacy accounts on behalf of users, standard wallets (like Phoenix or Wallet of Satoshi) can unknowingly pay a Discord user by resolving a Lightning Address.
Identifier Resolution
The username portion of the LUD-16 address can be one of three things, resolved in priority order:
| Priority | Type | Example | How it resolves |
|---|---|---|---|
| 1 | NIP-05 ↗ handle | alice@example.com | Looked up in the identity store by name |
| 2 | ConnectionKey hash | a1b2c3...@example.com (64-char hex) | Looked up in the connection store by hash |
| 3 | Raw pubkey | <hex_pubkey>@example.com (64-char hex) | Used directly as the recipient pubkey |
For social Web Identity connections (Discord, GitHub, etc.), the identifier is the connectionKey hash — SHA256(platform_name:platform_id). Clients never expose the raw platform username in the LNURL path.
GET https://example.com/.well-known/lnurlp/<connectionKey>
The Callback Response
The service resolves the identifier via the priority table above, then responds with a standard LNURL payload:
{
"callback": "https://example.com/lnurl/callback/<connectionKey>",
"maxSendable": 100000000,
"minSendable": 1000,
"metadata": "[[\"text/plain\",\"Zap <connectionKey>@example.com\"],[\"text/identifier\",\"<connectionKey>@example.com\"],[\"chain/flokicoin\",\"loki\"]]",
"tag": "payRequest",
"commentAllowed": 205,
"allowsNostr": true,
"nostrPubkey": "<recipient_or_server_pubkey>"
}
Nostr Extensions
allowsNostr: truemeans, as in NIP-57 ↗, that the callback accepts a signed event in itsnostrparameter. With at least onechain/<name>metadata entry, it means the endpoint accepts kind 9520 and kind 9523 AltZap Requests.nostrPubkeyis the key that signs the resulting kind 9521 receipt: the LNURL server's own key.
Invoice Generation (Callback)
When the client accesses the callback URL (e.g., GET https://example.com/lnurl/callback/...&amount=10000&nostr=<url_encoded_kind_9520_or_9523>), the server executes the following logic:
- Validation: Check the request's signature first, then that its
pis this address, itsamountequals theamountparameter, and itschainis one this endpoint lists. The invoice's description hash is the SHA-256 of the request exactly as received. - Target Resolution: Is the target a registered user with a connected NWC wallet?
- Yes (Direct): The server acts as a passthrough, retrieving an invoice directly from the user's NWC node.
- No (Custodial): The server generates an invoice from its own Master Node (the Fallback Lightning Address flow).
- Invoice Response: The server returns the generated
pr(payment request) to the client.
{
"pr": "lnfc10n1...",
"routes": []
}
Multi-Chain Support
The LUD-06/LUD-16 metadata (a JSON-encoded string of entries) is extended with chain tags to signal which Lightning Network chains and denominations the service accepts. This is a backward-compatible extension — existing Bitcoin-only wallets simply ignore unknown metadata entries and continue to function normally.
Chain Metadata Tags
Chain support is declared via optional entries in the metadata JSON array using the format chain/<chain_name>:
| Tag | Denomination | Description |
|---|---|---|
chain/flokicoin | loki | Flokicoin Lightning Network |
If no chain entry is present, the endpoint settles on Bitcoin only and is a plain NIP-57 endpoint: clients send it a kind 9734 zap request, never an AltZap request. If at least one is present, only the listed chains are supported.
Example: Flokicoin Service
A service operating on the Flokicoin Lightning Network includes the chain/flokicoin metadata tag with the loki denomination:
["chain/flokicoin", "loki"]
Amounts in minSendable and maxSendable are denominated in the smallest sub-unit of the declared chain, and the returned pr invoice conforms to the respective chain's Lightning invoice format.
| Chain | Unit Name | Example |
|---|---|---|
chain/flokicoin | milliloki (mloki) | 1000 = 1 loki |
chain/bitcoin | millisatoshi (msats) | 1000 = 1 sat |
Flokicoin Wallet Compatibility
Standard Lightning wallets that do not understand chain/flokicoin will silently ignore the tag and attempt to pay the returned invoice. This will fail at the protocol level because the invoice belongs to a different chain — no funds are lost, no cross-chain confusion is possible. The wallet simply rejects the invoice as unpayable.
A service supporting several chains lists each; the request's chain tag says which one a zap settles on.