Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support async payments in BOLT 12 #1149

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

valentinewallace
Copy link
Contributor

@valentinewallace valentinewallace commented Mar 19, 2024

This builds on #989 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 keysend (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 keysend invoice, payers will commence the protocol outlined in
1 to send the HTLC asynchronously.

Some context on the top commit where we include the invoice request in the payment onion:
This definitely warrants discussion, but the idea is that this field may be useful for often-offline recipients who did not receive the invoice request when it was originally sent. Recipients may want to verify the invreq or be provided some other relevant data about the payment, while keeping the payment stateless until an HTLC is actually received. For example, future extensions have been proposed 2 that require the recipient to know a unique token for a payment, and this field would provide that to them.

Seeking conceptual feedback! I'm also working on the implementation in LDK.

Based on #798 and #989.

TheBlueMatt and others added 15 commits February 23, 2024 16:21
This is an incredibly simple first start towards the protocol
sketched out at [1]. It adds the ability to have a counteraprty
hold an HTLC before forwarding it.

Specifically, the HTLC sender sets a required TLV on the
`update_add_htlc` message and sends an onion message to the final
recipient. From there, the final recipient uses the included
`reply_path` to notify the sender's counterparty that they're
online and ready to receive the HTLC.

In order to fully flesh out the protocol as sketched, we'll need
to add an onion message mailbox service (which should be as simple
as a new feature bit), add PTLCs, and extensions to BOLT 12 to
allow signaling that the final recipient is often-offline. While
we could add such signaling to BOLT 11, there's not a whole lot of
reason to - if the recipient is able to provide an invoice,
they're currently online!

[1] https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307.html
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
It's far easier to validate these on parsing than to hand-validate them
elsewhere.

I didn't turn `alias` or `error` into this, though they're similar
(`alias` can have a nul terminator).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
A BOLT11 "invoice" has proven too low-level for human use in many
scenarios.  Efforts like lnurl have covered the gap, but integrating
some of such higher layers into the lightning protocol itself has many
advantages.

This draft defines three new things:

1. A new invoice format.  I know, this is painful, but it maps almost
   1:1 to the current format (though signatures are very different),
   is easier to implement, and easier to send via the lightning
   network itself.

2. Formats for an "offer", which for all intents and purposes serves
   as the new, persistent invoice for users.

3. Format for an "invoice_request": this is a message sent via the
   lightning network itself to receive the real invoice, or can
   be used directly in a send-money scenario (e.g. ATM).

The offer (for accepting payments) or invoice_request (for sending
payments) are usually presented via a QR code or similar, the replies
are sent using onion messages.  Each copies fields from the prior so
it stands alone, to allow statelessness.

Features which have been deliberately omitted for the initial version:
- Recurrence.
- Invoice replacement ("don't accept that old payment!")
- Payer proof for refunds.

I need to thank everyone who gave detailed feedback, particularly:

1. Thomas H of ACINQ (https://github.com/thomash-acinq)
2. Joost Jager (https://github.com/joostjager)
3. Aditya Sharma (https://github.com/adi2011)
4. Rene Pickhardt (https://github.com/renepickhardt)
5. Bastien Teinturier (https://github.com/t-bast)
6. Valentine Wallace of LDK (https://github.com/valentinewallace)
7. Matt Corallo of LDK (https://github.com/BlueMatt)
8. Jeffrey Czyz of Square Crypto (https://github.com/jkczyz)

Also @bjarnemagnussen, @ellemouton, @animatedbarber, @617a7a,
@instagibbs, and @eupn.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Regenerated bolt12/signature-test.json; for some reason jq reordered a
few fields, but it now shows the complete signature.
bolt12/format-string-test.json is now a valid offer.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Offers may contain blinded paths to allow for greater recipient privacy.
However, they come at a cost of increased QR code size as each hop
requires a 33-byte `point` for the `next_node_id`. Allow using
`short_channel_id` instead, which only requires 8 bytes.

Still allow for use of `next_node_id` for cases where the blinded path
may not involve channel counterparties or for long-lived offers, which
may outlive the given channels.
Offers may contain blinded paths to allow for greater recipient privacy.
However, they come at a cost of increased QR code size as the
introduction node requires a 33-byte `point`.

Define a new `sciddir_or_pubkey` fundamental type such that either a point or a
reference to one in a `channel_announcement` can be used. This is
backwards compatible with `point`.

Use this new type for the `blinded_path` subtype's `first_node_id`.
This field may be useful for often-offline recipients who did not receive the
invreq when it was originally sent, due to another node providing a keysend
invoice on their behalf.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants