Skip to main content

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 Zap Settlement Provider supports resolving any supported LIDP string natively:

# Format: <connection_key>@<zsp_domain>
# Where connection_key is the SHA256 hash of the LIDP string: SHA256(discord:some_user#1234)
a1b2c3d4e5f6g7h8...@zapf.app

2. Fetch the LNURL Metadata (LUD-16)

Perform a standard GET request to the .well-known endpoint of the Zap Settlement Provider domain using the derived connection key:

curl https://zapf.app/.well-known/lnurlp/a1b2c3d4e5f6g7h8...

The ZSP 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 a Zap Request).
  • nostrPubkey: The ZSP's pubkey (for verifying the eventual receipt).

3. Generate a Zap Request (Kind 5520)

Instead of a standard Kind 9734 ↗ Zap Request, generate a Kind 5520 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 lidp:identifier string). If this is a proxy zap from a bot, you will use Kind 5523.

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 5520:

curl "https://zapf.app/api/lnurl/cb/a1b2c3d4e5f6g7h8...?amount=1000000&nostr=%7B%22kind%22%3A5520..."

The ZSP 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 ZSP will automatically publish a Zap Receipt to the relays specified in your original Kind 5520 or Kind 5523 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.