Sending Zaps
As an open protocol, Zapf extends standard NIP-57 ↗ and LUD-16 payment flows with a permissionless identity resolution step. This lets your wallet or app route funds to user-friendly identifiers like discord:username#1234 or email:user@example.com.
The Sender Flow
As an integrator (wallet developer or app builder), implementing the Zapf sending flow involves 4 steps:
1. Resolve the Identity
When a user enters a legacy identifier into your UI, your client needs to discover the corresponding LNURL endpoint.
By default, the zapf.app LNURL server supports resolving any supported Web Identity platform string natively:
# Format: <connection_key>@<zsp_domain>
# Where connection_key is the SHA256 hash of: SHA256(platform_name:stable_id) e.g. SHA256(discord:1254093577051574374)
a1b2c3d4e5f6g7h8...@zapf.app
2. Fetch the LNURL Metadata (LUD-16)
Perform a standard GET request to the .well-known endpoint of the LNURL server domain using the derived connection key:
curl https://zapf.app/.well-known/lnurlp/a1b2c3d4e5f6g7h8...
The LNURL server will return a standard LNURL payload. Key fields include:
callback: The URL to request the final Lightning invoice.minSendable/maxSendable: The payment boundaries (in millisats).allowsNostr:true(indicating you should generate an AltZap Request).nostrPubkey: The LNURL server's pubkey (for verifying the eventual receipt).
3. Generate an AltZap Request (Kind 9520)
Instead of a standard Kind 9734 ↗ zap request, generate a Kind 9520 event.
Sign the event with the sender's Nostr private key. The p tag must contain the recipient's target (either their Nostr pubkey if known, or the SHA-256 hash of the platform:identifier string). If this is a proxy zap from a bot, you will use Kind 9523.
URL-encode the JSON string representation of this signed event.
4. Fetch the Invoice and Pay
Make a request to the callback URL you received in Step 2, appending the amount (in millisats) and the URL-encoded nostr parameter containing your Kind 9520:
curl "https://zapf.app/api/lnurl/cb/a1b2c3d4e5f6g7h8...?amount=1000000&nostr=%7B%22kind%22%3A9520..."
The LNURL server will respond with a pr containing a BOLT11 Lightning Invoice. Your client can now pay this invoice via its connected Lightning node or wallet.
The Receipt
Once the payment settles, the LNURL server will automatically publish an AltZap Receipt to the relays specified in your original Kind 9520 or Kind 9523 request.
Your client can listen on those relays to instantly update the UI with a "Payment Confirmed" state, verifying the receipt signature against the nostrPubkey provided in Step 2.