lightning-bolt12

v2026.09.24

BOLT12 offers: reusable invoices, blinded paths, recurring payments, multi-asset (Taproot Assets layered). Replaces BOLT11 for many use cases. USE WHEN: implementing/integrating offers, designing recurring payments, evaluating BOLT11 vs BOLT12 trade-offs.

GitHub
Install command
npx skhub add claude-dev-suite/lightning-bolt12
Markdown
SKILL.md

BOLT12 Offers

BOLT12 is a flexible payment protocol that addresses BOLT11's limitations:

  • BOLT11 invoices are single-use and expire.
  • BOLT11 reveals destination pubkey.
  • BOLT11 has no built-in support for recurring payments or refunds.

BOLT12 offers a static, reusable identifier (the "offer") that lets payers fetch a fresh invoice each payment via Lightning's onion message system.

Three message types

  1. Offer (lno1...) — long-lived, signed by recipient. Encodes:
    • Description, amount (or "any"), expiry (or none).
    • Issuer pubkey (potentially blinded).
    • Allowed currencies / quantities.
  2. Invoice request (lnr1...) — payer sends via onion message, asks for an invoice for this offer.
  3. Invoice (lni1...) — receiver responds with one-time invoice. Standard payment proceeds.

Bech32 encoding

All three types use the BOLT11-style bech32 encoding with lno1, lnr1, lni1 prefixes (no chain prefix; chain encoded in TLV).

TLV-only

Unlike BOLT11's tag/data tuples, BOLT12 uses pure TLV everywhere. Future-proof; new fields don't break old parsers.

Blinded paths

Offers can include blinded paths — partial routes that hide the recipient's node id. The offer is signed by an "introduction node" + blinded route data; recipient is anonymous to the payer.

Recurring payments

Offers can specify recurrence:

quantity_min: 1, quantity_max: 100
recurrence: monthly for 12 months

Same offer used for subscription: payer fetches a fresh invoice each month.

Multi-asset (Taproot Assets layered)

BOLT12 + Taproot Assets together enable invoices priced in non-BTC assets routed over LN. Recipient gets BTC amounts; payer pays in asset terms; intermediate hops handle conversion.

Handing out an offer: BIP 353 and bLIP-42

An lno1... string is too long to read aloud or type. Two specs turn it into a human-readable identity; a third identifies the payer instead:

  • BIP 353 "DNS Payment Instructions" — status Complete in the BIPs repo as of September 2026. Publishes a BIP 21 URI, usually just bitcoin:?lno=<offer>, in a DNSSEC-signed TXT record at <user>.user._bitcoin-payment.<domain>, displayed as ₿user@domain. No HTTP endpoint in the path, unlike LNURL-pay / LUD-16; see the lightning-address skill.
  • bLIP-32 "Onion Message DNS Resolution" — status Active in lightning/blips as of September 2026. Lets a client that cannot validate DNSSEC itself ask a node over onion messages: dnssec_query (type 65536) → dnssec_proof (65538), or dnssec_error (65550).
  • bLIP-42 "Bolt 12 Contacts" (Bastien Teinturier, created 2024-07-19) — status Active in lightning/blips as of September 2026. Adds optional invoice_request TLVs that let a payment identify its payer: invreq_contact_secret (2000001729), plus either invreq_payer_offer (2000001731) or invreq_payer_bip_353_name (2000001733) with invreq_payer_bip_353_signature (2000001735) proving control of the offer behind that name. The recipient can then add the payer as a contact and pay them back with no extra round trip.

Use cases vs BOLT11

Use caseBOLT11BOLT12
One-time payment with known amountyesyes
Static "donate to me" QR codehacky (LNURL-pay)native
Recurring subscriptionmanualnative
Refund flownoyes
Hidden destinationnoyes (blinded paths)
Multi-assetno (need TAP/RGB)yes

Implementation status (late 2025)

ImplementationSendReceiveRecurring
CLNyesyesyes
LDKyesyespartial
LNDpartialpartialno
Eclairyesyespartial
phoenixdyes (receive especially)yespartial

Common bugs

  • Treating lno1... as a single-use invoice → it's not, can be reused.
  • Failing to fetch invoice via onion message → expecting BOLT11 flow.
  • Caching invoice from offer → invoices are one-shot; fetch fresh each payment.
  • Missing onion-message support (option_onion_messages feature bit) → can't fetch invoice request response.
  • Under bLIP-42, accepting invreq_payer_offer / invreq_payer_bip_353_name from a payer you already hold a contact_secret for → the spec says ignore them for known contacts, so a leaked secret can't redirect your future payments to an impostor's offer.

See also

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/bitcoin/lightning/bolt12

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1