Keysend / Spontaneous Payments
Keysend lets the sender pay a destination by node pubkey without the receiver issuing a BOLT11 invoice first. The sender includes the preimage as a TLV record in the onion; receiver extracts and fulfills.
Mechanism
Sender:
preimage_random = random(32 bytes)
payment_hash = SHA256(preimage_random)
Build onion with TLV record:
type 5482373484 ("keysend"): preimage_random
HTLC for amount → forwarded via onion routing → arrives at destination.
Receiver:
Receives HTLC with payment_hash.
Sees TLV type 5482373484 in onion payload.
Extracts preimage. Verifies SHA256(preimage) == payment_hash.
If matches, fulfill HTLC immediately.
Why custom record number 5482373484?
Per BOLT 1: custom records ≥ 65536 are reserved for proprietary use. The keysend type was chosen by Lightning Labs as a (large) sentinel.
Limitations of bare keysend
- No proof of payment: receiver gets the preimage but sender never receives a signed invoice. Some compliance / accounting flows fail.
- No metadata: receiver doesn't know what the payment is for.
Custom records (e.g., pubky podcast app) extend with
text/plaintype for memos. - Non-standard: not in BOLT mainline. Different impls vary in feature support.
Spontaneous payments + AMP
AMP-keysend combines AMP's per-part nonces with keysend's preimage-in- onion mechanism. Each part contributes a Shamir share; receiver reassembles preimage. Used by some podcast apps for streaming sats.
Use cases
- Lightning tips:
boostorvalue4valueapps. - Streaming sats: podcast apps, video streaming apps that send sats per minute.
- Direct messaging payments: Sphinx Chat, Damus zaps.
- Mempool.space accelerator for LN-paid mempool acceleration (some impls).
Custom records (extend keysend)
Common custom record types:
34349334: keysend message text.7629169: pubky / podcast-index sender info.133773310: app-specific.
These are app-defined; no global registry. Risk of conflicts; check app docs.
Implementation status
| Impl | Keysend send | Keysend receive |
|---|---|---|
| LND | yes | yes |
| CLN | yes (via plugin) | yes |
| LDK | yes | yes |
| Eclair | yes | yes |
| Phoenix | partial | yes |
BOLT12 keysend equivalent
BOLT12 supports an "offer" that allows arbitrary amount payments WITHOUT pre-issued per-payment invoices, but with proper proof of payment (signed by recipient).
For new builds, prefer BOLT12 keysend over bare keysend where implementation supports it.
Common bugs
- Receiver doesn't have keysend enabled → HTLC fails with "incorrect_payment_details".
- Sender forgets to include the keysend custom record → receiver treats as unknown payment_hash.
- Custom records exceed onion size budget (1300 bytes) → onion rejected at routing.
- Multi-hop keysend with custom records → some forwarders strip unknown TLVs (they shouldn't but happens).