Skip to content

Commit d706683

Browse files
Support async payments in BOLT 12.
This builds on prior commits by adding the ability to fetch an invoice from an always-online node on behalf of an often-offline recipient, e.g. a mobile node. The idea is that often-offline recipients will supply some always-online node such as their wallet vendor with a static (i.e. `payment_hash`-less) invoice to return on its behalf. The recipient will then publish an offer containing blinded paths that terminate at this always-online node, who payers can request the invoice from if the recipient is offline at the time. After receiving the static invoice, payers will commence the protocol outlined in [1] to send the HTLC asynchronously. [1]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307.html
1 parent c7aafa3 commit d706683

File tree

2 files changed

+74
-19
lines changed

2 files changed

+74
-19
lines changed

04-onion-routing.md

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

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

246+
`sender_provided_payment_preimage` is set in the case that the recipient is
247+
often-offline and another node provided a static BOLT 12 invoice on their behalf.
248+
243249
### Requirements
244250

245251
The creator of `encrypted_recipient_data` (usually, the recipient of payment):
@@ -273,6 +279,12 @@ The writer of the TLV `payload`:
273279
- MUST use the current block height as a baseline value.
274280
- if a [random offset](07-routing-gossip.md#recommendations-for-routing) was added to improve privacy:
275281
- SHOULD add the offset to the baseline value.
282+
- if paying to a static BOLT 12 invoice:
283+
- MUST set `sender_provided_payment_preimage` to randomly generated unique bytes.
284+
- MUST set `update_add_htlc.payment_hash` to match the SHA256 hash of
285+
`sender_provided_payment_preimage`.
286+
- otherwise:
287+
- MUST NOT set `sender_provided_payment_preimage`.
276288
- MUST NOT include any other tlv field.
277289
- For every node outside of a blinded route:
278290
- MUST include `amt_to_forward` and `outgoing_cltv_value`.
@@ -324,6 +336,7 @@ The reader:
324336
- MUST return an error if `amt_to_forward` is below what it expects for the payment.
325337
- MUST return an error if incoming `cltv_expiry` < `outgoing_cltv_value`.
326338
- MUST return an error if incoming `cltv_expiry` < `current_block_height` + `min_final_cltv_expiry_delta`.
339+
- MUST use `sender_provided_payment_preimage` when claiming the HTLC, if present
327340
- Otherwise (it is not part of a blinded route):
328341
- MUST return an error if `path_key` is set in the incoming `update_add_htlc` or `current_path_key` is present.
329342
- MUST return an error if `amt_to_forward` or `outgoing_cltv_value` are not present.
@@ -1519,6 +1532,9 @@ even, of course!).
15191532
1. type: 68 (`invoice_error`)
15201533
2. data:
15211534
* [`tlv_invoice_error`:`inverr`]
1535+
1. type: 70 (`static_invoice`)
1536+
2. data:
1537+
* [`tlv_static_invoice`:`static_inv`]
15221538

15231539
#### Requirements
15241540

12-offer-encoding.md

Lines changed: 58 additions & 19 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.
@@ -58,6 +58,18 @@ The merchant-pays-user flow (e.g. ATM or refund):
5858
3. The merchant confirms the *invoice_node_id* to ensure it's about to pay the correct
5959
person, and makes a payment to the invoice.
6060

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

6375
Note that the normal lightning "proof of payment" can only demonstrate that an
@@ -70,6 +82,9 @@ to request the invoice. In addition, the Merkle construction of the BOLT 12
7082
invoice signature allows the user to reveal invoice fields in case
7183
of a dispute selectively.
7284

85+
Payers will not get proofs in the case that they received a static invoice from the
86+
payee, see the pay-mobile-user flow above.
87+
7388
# Encoding
7489

7590
Each of the forms documented here are in
@@ -126,7 +141,7 @@ Each form is signed using one or more *signature TLV elements*: TLV
126141
types 240 through 1000 (inclusive). For these,
127142
the tag is "lightning" || `messagename` || `fieldname`, and `msg` is the
128143
Merkle-root; "lightning" is the literal 9-byte ASCII string,
129-
`messagename` is the name of the TLV stream being signed (i.e. "invoice_request" or "invoice") and the `fieldname` is the TLV field containing the
144+
`messagename` is the name of the TLV stream being signed (i.e. "invoice_request", "invoice", or "static_invoice") and the `fieldname` is the TLV field containing the
130145
signature (e.g. "signature").
131146

132147
The formulation of the Merkle tree is similar to that proposed in
@@ -261,8 +276,9 @@ A writer of an offer:
261276
after midnight 1 January 1970, UTC that invoice_request should not be
262277
attempted.
263278
- if it is connected only by private channels:
264-
- MUST include `offer_paths` containing one or more paths to the node from
265-
publicly reachable nodes.
279+
- MUST include `offer_paths` containing one or more paths to the node
280+
that will reply to the `invoice_request`, using introduction nodes that are
281+
publicly reachable.
266282
- otherwise:
267283
- MAY include `offer_paths`.
268284
- if it includes `offer_paths`:
@@ -282,6 +298,8 @@ A writer of an offer:
282298
- MUST set `offer_quantity_max` to 0.
283299
- otherwise:
284300
- MUST NOT set `offer_quantity_max`.
301+
- if it is often-offline and the invoice may be provided by another node on their behalf:
302+
- MUST NOT include more than 1 chain in `offer_chains`.
285303

286304
A reader of an offer:
287305
- if the offer contains any TLV fields outside the inclusive ranges: 1 to 79 and 1000000000 to 1999999999:
@@ -543,6 +561,9 @@ The reader:
543561
- if `invreq_bip_353_name` is present:
544562
- MUST reject the invoice request if `name` or `domain` contain any bytes which are not
545563
`0`-`9`, `a`-`z`, `A`-`Z`, `-`, `_` or `.`.
564+
- if receiving the `invoice_request` on behalf of an often-offline payee:
565+
- SHOULD forward the `invoice_request` to the payee
566+
- SHOULD reply with the static invoice previously provided by the payee
546567

547568
## Rationale
548569

@@ -573,10 +594,11 @@ The requirement to use `offer_paths` if present, ensures a node does not reveal
573594

574595
# Invoices
575596

576-
Invoices are a payment request, and when the payment is made,
577-
the payment preimage can be combined with the invoice to form a cryptographic receipt.
597+
Invoices are a payment request. If `invoice_payment_hash` is set, then when the
598+
payment is made, the payment preimage can be combined with the invoice to form a
599+
cryptographic receipt.
578600

579-
The recipient sends an `invoice` in response to an `invoice_request` using
601+
The recipient creates an `invoice` for responding to an `invoice_request` using
580602
the `onion_message` `invoice` field.
581603

582604
1. `tlv_stream`: `invoice`
@@ -671,6 +693,9 @@ the `onion_message` `invoice` field.
671693
1. type: 176 (`invoice_node_id`)
672694
2. data:
673695
* [`point`:`node_id`]
696+
1. type: 178 (`static_invoice_message_paths`)
697+
2. data:
698+
* [`...*blinded_path`:`paths`]
674699
1. type: 240 (`signature`)
675700
2. data:
676701
* [`bip340sig`:`sig`]
@@ -709,17 +734,28 @@ may (due to capacity limits on a single channel) require it.
709734
A writer of an invoice:
710735
- MUST set `invoice_created_at` to the number of seconds since Midnight 1
711736
January 1970, UTC when the invoice was created.
712-
- MUST set `invoice_amount` to the minimum amount it will accept, in units of
713-
the minimal lightning-payable unit (e.g. milli-satoshis for bitcoin) for
714-
`invreq_chain`.
715-
- if the invoice is in response to an `invoice_request`:
737+
- if `invoice_payment_hash` is set and the invoice is in response to an `invoice_request`:
716738
- MUST copy all non-signature fields from the invoice request (including unknown fields).
717739
- if `invreq_amount` is present:
718740
- MUST set `invoice_amount` to `invreq_amount`
719741
- otherwise:
720742
- MUST set `invoice_amount` to the *expected amount*.
721-
- MUST set `invoice_payment_hash` to the SHA256 hash of the
722-
`payment_preimage` that will be given in return for payment.
743+
- if the expiry for accepting payment is not 7200 seconds after `invoice_created_at`:
744+
- MUST set `invoice_relative_expiry`.`seconds_from_creation` to the number of
745+
seconds after `invoice_created_at` that payment of this invoice should not be attempted.
746+
- if the invoice is intended to be provided by a node other than the recipient (i.e. a static
747+
invoice):
748+
- MUST NOT set `invoice_payment_hash`.
749+
- MUST NOT set `invoice_amount`.
750+
- MUST include `static_invoice_message_paths` containing at least two paths to
751+
the recipient.
752+
- MUST NOT set any `invoice_request` TLV fields
753+
- if the expiry for accepting payment is not 2 weeks after `invoice_created_at`:
754+
- MUST set `invoice_relative_expiry`.`seconds_from_creation` to the number of
755+
seconds after `invoice_created_at` that payment of this invoice should not be attempted.
756+
- otherwise:
757+
- MUST set `invoice_payment_hash` to the SHA256 hash of the
758+
`payment_preimage` that will be given in return for payment.
723759
- if `offer_issuer_id` is present:
724760
- MUST set `invoice_node_id` to the `offer_issuer_id`
725761
- otherwise, if `offer_paths` is present:
@@ -730,9 +766,6 @@ A writer of an invoice:
730766
- MUST set `invoice_features`.`features` bit `MPP/compulsory`
731767
- or if it allows multiple parts to pay the invoice:
732768
- MUST set `invoice_features`.`features` bit `MPP/optional`
733-
- if the expiry for accepting payment is not 7200 seconds after `invoice_created_at`:
734-
- MUST set `invoice_relative_expiry`.`seconds_from_creation` to the number of
735-
seconds after `invoice_created_at` that payment of this invoice should not be attempted.
736769
- if it accepts onchain payments:
737770
- MAY specify `invoice_fallbacks`
738771
- SHOULD specify `invoice_fallbacks` in order of most-preferred to least-preferred
@@ -745,11 +778,11 @@ A writer of an invoice:
745778
- MUST include `invoice_blindedpay` with exactly one `blinded_payinfo` for each `blinded_path` in `paths`, in order.
746779
- MUST set `features` in each `blinded_payinfo` to match `encrypted_data_tlv`.`allowed_features` (or empty, if no `allowed_features`).
747780
- SHOULD ignore any payment which does not use one of the paths.
781+
- if providing invoices on behalf of an often offline recipient:
782+
- MAY reuse the previous invoice.
748783

749784
A reader of an invoice:
750-
- MUST reject the invoice if `invoice_amount` is not present.
751785
- MUST reject the invoice if `invoice_created_at` is not present.
752-
- MUST reject the invoice if `invoice_payment_hash` is not present.
753786
- MUST reject the invoice if `invoice_node_id` is not present.
754787
- if `invreq_chain` is not present:
755788
- MUST reject the invoice if bitcoin is not a supported chain.
@@ -771,7 +804,9 @@ A reader of an invoice:
771804
- MUST NOT use the corresponding `invoice_paths`.`path` if `payinfo`.`features` has any unknown even bits set.
772805
- MUST reject the invoice if this leaves no usable paths.
773806
- if the invoice is a response to an `invoice_request`:
774-
- MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the invoice request.
807+
- if `invoice_payment_hash` is set:
808+
- MUST reject the invoice if `invoice_amount` is not present.
809+
- MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the invoice request.
775810
- if `offer_issuer_id` is present (invoice_request for an offer):
776811
- MUST reject the invoice if `invoice_node_id` is not equal to `offer_issuer_id`
777812
- otherwise, if `offer_paths` is present (invoice_request for an offer without id):
@@ -800,6 +835,10 @@ A reader of an invoice:
800835
- MUST reject the invoice if it arrived via a blinded path.
801836
- otherwise (derived from an offer):
802837
- MUST reject the invoice if it did not arrive via invoice request `onionmsg_tlv` `reply_path`.
838+
- if `invoice_payment_hash` is unset:
839+
- MUST reject the invoice if `static_invoice_message_paths` is not present or is empty.
840+
- MUST pay asynchronously using the `held_htlc_available` onion message
841+
flow, where the onion message is sent over `static_invoice_message_paths`.
803842

804843
## Rationale
805844

0 commit comments

Comments
 (0)