Skip to content

Commit 6b585c2

Browse files
Support async payments in BOLT 12.
1 parent eb30b0b commit 6b585c2

File tree

3 files changed

+98
-15
lines changed

3 files changed

+98
-15
lines changed

04-onion-routing.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]
213213
1. type: 18 (`total_amount_msat`)
214214
2. data:
215215
* [`tu64`:`total_msat`]
216+
1. type: 5482373484 (`keysend_payment_preimage`)
217+
2. data:
218+
* [`32*byte`:`payment_preimage`]
216219

217220
`short_channel_id` is the ID of the outgoing channel used to route the
218221
message; the receiving peer should operate the other end of this channel.
@@ -239,6 +242,10 @@ The requirements ensure consistency in responding to an unexpected
239242
`outgoing_cltv_value`, whether it is the final node or not, to avoid
240243
leaking its position in the route.
241244

245+
`keysend_payment_preimage` is the payment preimage provided by the sender in the
246+
case that the recipient is often-offline and another node provided a keysend
247+
BOLT 12 invoice on their behalf.
248+
242249
### Requirements
243250

244251
The creator of `encrypted_recipient_data` (usually, the recipient of payment):
@@ -269,6 +276,12 @@ The writer of the TLV `payload`:
269276
- MUST use the current block height as a baseline value.
270277
- if a [random offset](07-routing-gossip.md#recommendations-for-routing) was added to improve privacy:
271278
- SHOULD add the offset to the baseline value.
279+
- if paying to a keysend invoice:
280+
- MUST set `keysend_payment_preimage` to randomly generated unique bytes.
281+
- MUST set `update_add_htlc.payment_hash` to match the SHA256 hash of
282+
`keysend_payment_preimage`.
283+
- otherwise:
284+
- MUST NOT set `keysend_payment_preimage`.
272285
- MUST NOT include any other tlv field.
273286
- For every node outside of a blinded route:
274287
- MUST include `amt_to_forward` and `outgoing_cltv_value`.
@@ -319,6 +332,7 @@ The reader:
319332
- MUST return an error if `amt_to_forward` is below what it expects for the payment.
320333
- MUST return an error if incoming `cltv_expiry` < `outgoing_cltv_value`.
321334
- MUST return an error if incoming `cltv_expiry` < `current_block_height` + `min_final_cltv_expiry_delta`.
335+
- MUST use `keysend_payment_preimage` when claiming the HTLC, if present
322336
- Otherwise (it is not part of a blinded route):
323337
- MUST return an error if `blinding_point` is set in the incoming `update_add_htlc` or `current_blinding_point` is present.
324338
- MUST return an error if `amt_to_forward` or `outgoing_cltv_value` are not present.

09-features.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,16 @@ The Context column decodes as follows:
5151
| 48/49 | `option_payment_metadata` | Payment metadata in tlv record | 9 | | [BOLT #11](11-payment-encoding.md#tagged-fields) |
5252
| 50/51 | `option_zeroconf` | Understands zeroconf channel types | IN | `option_scid_alias` | [BOLT #2][bolt02-channel-ready] |
5353
| 52/53 | `option_htlc_hold` | Hold HTLCs and forward on receipt of an onion message | IN | `option_onion_messages` |
54+
| 53/54 | `option_om_mailbox` | Store-and-forward onion messages for often-offline peers | IN | `option_onion_messages` | |
5455

5556
## Definitions
5657

5758
We define `option_anchors` as `option_anchor_outputs || option_anchors_zero_fee_htlc_tx`.
5859

60+
We define `option_om_mailbox` as the ability to store an onion message on behalf
61+
of an offline peer, and forward it once the peer comes online (subject to rate
62+
limiting).
63+
5964
## Requirements
6065

6166
The origin node:

12-offer-encoding.md

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Here we use "user" as shorthand for the individual user's lightning
4242
node and "merchant" as the shorthand for the node of someone who is
4343
selling or has sold something.
4444

45-
There are two basic payment flows supported by BOLT 12:
45+
There are three basic payment flows supported by BOLT 12:
4646

4747
The general user-pays-merchant flow is:
4848
1. A merchant publishes an *offer*, such as on a web page or a QR code.
@@ -59,6 +59,19 @@ The merchant-pays-user flow (e.g. ATM or refund):
5959
3. The merchant confirms the *invoice_node_id* to ensure it's about to pay the correct
6060
person, and makes a payment to the invoice.
6161

62+
The pay-mobile-user flow (e.g. paying a friend back to their mobile node):
63+
1. The mobile user supplies some always-online node with a static keysend (i.e.
64+
`payment_hash`-less) invoice to return on its behalf. This always-online node
65+
may be the mobile user's channel counterparty, wallet vendor, or another node
66+
on the network that it has an out-of-band relationship with.
67+
2. The mobile user publishes an offer that contains blinded paths that terminate
68+
at the always-online node.
69+
3. The payer sends an `invoice_request` to the always-online node, who replies
70+
with the static keysend invoice previously provided by the mobile user if the
71+
mobile user is offline. If they are online, the `invoice_request` is forwarded
72+
to the mobile user as usual.
73+
4. The payer makes a payment to the mobile user as indicated by the invoice.
74+
6275
## Payment Proofs and Payer Proofs
6376

6477
Note that the normal lightning "proof of payment" can only demonstrate that an
@@ -71,6 +84,9 @@ to request the invoice. In addition, the Merkle construction of the BOLT 12
7184
invoice signature allows the user to reveal invoice fields in case
7285
of a dispute selectively.
7386

87+
Payers will not get proofs in the case that they received a static keysend
88+
invoice from the payee, see the pay-mobile-user flow above.
89+
7490
# Encoding
7591

7692
Each of the forms documented here are in
@@ -224,6 +240,17 @@ The human-readable prefix for offers is `lno`.
224240
2. data:
225241
* [`point`:`node_id`]
226242

243+
## Offer Features
244+
245+
| Bits | Description | Name |
246+
|------|----------------------------------|--------------------------|
247+
| 0 | Async payment receive support | async_receive/compulsory |
248+
| 1 | Async payment receive support | async_receive/optional |
249+
250+
Indicates that the payee is often offline and the invoice MUST (0) or MAY (1) be
251+
paid asynchronously if the payee is offline at the time of payment, i.e. via the
252+
`held_htlc_available` onion message flow.
253+
227254
## Requirements For Offers
228255

229256
A writer of an offer:
@@ -255,8 +282,9 @@ A writer of an offer:
255282
after midnight 1 January 1970, UTC that invoice_request should not be
256283
attempted.
257284
- if it is connected only by private channels:
258-
- MUST include `offer_paths` containing one or more paths to the node from
259-
publicly reachable nodes.
285+
- MUST include `offer_paths` containing one or more paths to the node
286+
that will reply to the `invoice_request`, using introduction nodes that are
287+
publicly reachable.
260288
- otherwise:
261289
- MAY include `offer_paths`.
262290
- if it includes `offer_paths`:
@@ -409,6 +437,20 @@ for [Signature Calculation](#signature-calculation).
409437
2. data:
410438
* [`bip340sig`:`sig`]
411439

440+
## Invoice Request Features
441+
442+
| Bits | Description | Name |
443+
|------|----------------------------------|------------------|
444+
| 1 | Supports paying keysend invoices | keysend/optional |
445+
446+
Setting `keysend` indicates that the payer supports receiving a
447+
`payment_hash`-less invoice in response to their `invoice_request`, and
448+
subsequently setting `keysend_payment_preimage` in their payment onion.
449+
450+
Useful if the payee is often offline and the invoice is being returned on
451+
their behalf by another node, to avoid trusting that other node to not reuse a
452+
`payment_hash`.
453+
412454
## Requirements for Invoice Requests
413455

414456
The writer:
@@ -486,7 +528,14 @@ The reader:
486528
- MUST fail the request if bitcoin is not a supported chain.
487529
- otherwise:
488530
- MUST fail the request if `invreq_chain`.`chain` is not a supported chain.
489-
531+
- if `offer_features` supports `async_receive`:
532+
- if the payee is online:
533+
- MUST forward the `invoice_request` to the payee
534+
- otherwise (payee is offline):
535+
- if `invreq_features` supports `keysend`:
536+
- MUST reply with the static keysend invoice previously provided by the payee
537+
- otherwise:
538+
- MUST reply with `invoice_error`
490539

491540
## Rationale
492541

@@ -515,10 +564,11 @@ informative for the payer to know how the sender claims
515564

516565
# Invoices
517566

518-
Invoices are a payment request, and when the payment is made,
519-
it can be combined with the invoice to form a cryptographic receipt.
567+
Invoices are a payment request. If `invoice_payment_hash` is set, then when the
568+
payment is made, the payment preimage can be combined with the invoice to form a
569+
cryptographic receipt.
520570

521-
The recipient sends an `invoice` in response to an `invoice_request` using
571+
The recipient creates an `invoice` for responding to an `invoice_request` using
522572
the `onion_message` `invoice` field.
523573

524574
1. `tlv_stream`: `invoice`
@@ -604,6 +654,9 @@ the `onion_message` `invoice` field.
604654
1. type: 176 (`invoice_node_id`)
605655
2. data:
606656
* [`point`:`node_id`]
657+
1. type: 178 (`invoice_message_paths`)
658+
2. data:
659+
* [`...*blinded_path`:`paths`]
607660
1. type: 240 (`signature`)
608661
2. data:
609662
* [`bip340sig`:`sig`]
@@ -645,18 +698,24 @@ A writer of an invoice:
645698
- MUST set `invoice_amount` to the minimum amount it will accept, in units of
646699
the minimal lightning-payable unit (e.g. milli-satoshis for bitcoin) for
647700
`invreq_chain`.
648-
- if the invoice is in response to an `invoice_request`:
701+
- if `invoice_payment_hash` is set and the invoice is in response to an `invoice_request`:
649702
- MUST copy all non-signature fields from the `invoice_request` (including unknown fields).
650703
- if `invreq_amount` is present:
651704
- MUST set `invoice_amount` to `invreq_amount`
652705
- otherwise:
653706
- MUST set `invoice_amount` to the *expected amount*.
654-
- otherwise (invoice not requested, e.g. for user to scan directly):
707+
- otherwise if the invoice was not requested (e.g. for user to scan directly):
655708
- MUST set `invreq_chain` as it would for an invoice_request.
656709
- MUST set `offer_description` as it would for an offer.
657710
- MUST NOT set `invreq_payer_id` or `offer_node_id`.
658-
- MUST set `invoice_payment_hash` to the SHA256 hash of the
659-
`payment_preimage` that will be given in return for payment.
711+
- if the invoice is intended to be provided by a node other than the recipient:
712+
- MUST set `invreq_chain` as it would for an invoice_request.
713+
- MUST NOT set `invoice_payment_hash`.
714+
- MUST include `invoice_message_paths` containing at least two paths to
715+
the recipient, where the penultimate hop supports `option_om_mailbox`.
716+
- otherwise:
717+
- MUST set `invoice_payment_hash` to the SHA256 hash of the
718+
`payment_preimage` that will be given in return for payment.
660719
- if `offer_node_id` is present:
661720
- MUST set `invoice_node_id` to `offer_node_id`.
662721
- otherwise:
@@ -682,15 +741,16 @@ A writer of an invoice:
682741
- MUST include `invoice_blindedpay` with exactly one `blinded_payinfo` for each `blinded_path` in `paths`, in order.
683742
- MUST set `features` in each `blinded_payinfo` to match `encrypted_data_tlv`.`allowed_features` (or empty, if no `allowed_features`).
684743
- SHOULD ignore any payment which does not use one of the paths.
685-
- if `offer_node_id` is present, and `invreq_payer_id` is identical to a previous `invoice_request`:
686-
- MAY simply reuse the previous invoice.
744+
- if `offer_node_id` is present, and `invreq_payer_id` is identical to a previous `invoice_request`, or if providing invoices on behalf of an often offline recipient:
745+
- MAY reuse the previous invoice.
687746
- otherwise:
688747
- MUST NOT reuse a previous invoice.
689748

690749
A reader of an invoice:
691750
- MUST reject the invoice if `invoice_amount` is not present.
692751
- MUST reject the invoice if `invoice_created_at` is not present.
693-
- MUST reject the invoice if `invoice_payment_hash` is not present.
752+
- if keysend was not supported in `invreq_features`:
753+
- MUST reject the invoice if `invoice_payment_hash` is not present.
694754
- MUST reject the invoice if `invoice_node_id` is not present.
695755
- if `invoice_features` contains unknown _odd_ bits that are non-zero:
696756
- MUST ignore the bit.
@@ -706,8 +766,9 @@ A reader of an invoice:
706766
- For each `invoice_blindedpay`.`payinfo`:
707767
- MUST NOT use the corresponding `invoice_paths`.`path` if `payinfo`.`features` has any unknown even bits set.
708768
- MUST reject the invoice if this leaves no usable paths.
709-
- if the invoice is a response to an `invoice_request`:
769+
- if `invoice_payment_hash` is set and the invoice is a response to an `invoice_request`:
710770
- MUST reject the invoice if all fields less than type 160 do not exactly match the `invoice_request`.
771+
- else if the invoice is a response to an `invoice_request`:
711772
- if `offer_node_id` is present (invoice_request for an offer):
712773
- MUST reject the invoice if `invoice_node_id` is not equal to `offer_node_id`.
713774
- otherwise (invoice_request without an offer):
@@ -727,6 +788,9 @@ A reader of an invoice:
727788
- MUST ignore any `fallback_address` for which `version` is greater than 16.
728789
- MUST ignore any `fallback_address` for which `address` is less than 2 or greater than 40 bytes.
729790
- MUST ignore any `fallback_address` for which `address` does not meet known requirements for the given `version`
791+
- if `invoice_payment_hash` is unset:
792+
- MUST pay asynchronously using the `held_htlc_available` onion message
793+
flow, where the onion message is sent over `invoice_message_paths`
730794

731795
## Rationale
732796

0 commit comments

Comments
 (0)