BOLT 12: remove send_invoice offer, use a straight invoice_request.#11
BOLT 12: remove send_invoice offer, use a straight invoice_request.#11rustyrussell wants to merge 3 commits intomatt-modificationsfrom
send_invoice offer, use a straight invoice_request.#11Conversation
valentinewallace
left a comment
There was a problem hiding this comment.
Looks reasonable to me! send_invoice did previously feel a little shoved in, it feels more fleshed out this way? Would need Jeff's take for which is more encoding-friendly.
|
After giving this another glance, my one doubt is that it seems like |
IIUC, the QR code would be for the |
Hmm ok, looking in more detail it seems like it depends how you implement it. So you could leave Sorry I can't paste this with formatting but here's how I drew out the fields: |
That's a good point. May be useful to calculate how large a typical |
|
|
||
| The reader: | ||
| - MUST fail the request if `invoice_request_payer_key` is not present. | ||
| - MUST fail the request if `invoice_request_payer_id` is not present. |
There was a problem hiding this comment.
@rustyrussell This shouldn't hold if the invoice is in response to an inv_req QR, right? I believe the invoice_request_payer_id is optional in that case since there's no signature (assuming blinded paths are present)?
@jkczyz if this is correct, then I think the resolution of #11 (comment) is that we'll never set these fields for QRs and always just set offer_metadata, so invoice_request ends up being a bit smaller than offer_send_invoices but comparable
There was a problem hiding this comment.
I ended up dropping the whole "node_id is optional if you use a blinded path and don't have a real node id" since it just made this complicated. So that would apply here too, and it might be important later if you want to later prove your id? It's certainly harmless to include one.
There was a problem hiding this comment.
Hmmm, aren't we trying to save bits on the QR code here? If I'm missing something, though, I think the requirements for the writer need updating for this in the QR case
There was a problem hiding this comment.
Once you have blinded paths in the QR code, it's hard to argue that saving 35 bytes is a big win. It's possible to allow this case later, but for now we have more than enough complexity :(
There was a problem hiding this comment.
35 bytes is pretty significant in a QR code, plus even a single 2-hop blinded path can add a lot of privacy so I'm not convinced that "blinded paths == we should give up entirely on the QR case" IMHO.
Not gonna die on this hill but wanted to put out those points :p it's true we can add it later as you say
There was a problem hiding this comment.
FWIW, it's actually 56 bytes after bech32 encoding, IIUC.
| 2. The user sends an *invoice* for the amount in the *offer* | ||
| 3. The merchant makes a payment to the user indicated by the invoice. | ||
| 1. The merchant publishes an *invoice_request* which contains offer fields | ||
| which refer to its attempt to send money, including an amount. |
Instead of a kind of dummy offer which asks you to send an invoice, use a dummy invoice request, since it now contains all the offer fields anyway. It simplifies things a little, but there's the following fallout: 1. We use the presence of `offer_node_id` to distinguish invoice-request-for-offer and invoice-request-no-offer, which makes sense, since the vendor doesn't know that. 2. We rename `invoice_request_payer_key` to `invoice_request_payer_id`. In the case of a public node making a non-offer invoice_request, it's their id (as they are the payer), but it can omitted using blinded paths (like the offer_node_id in offer). 3. The invoice_request has no signature if it's not an offer response. This is makes them as small like the old send_invoice offer. 4. We don't allow invoice_request in other currencies (could in future): must specify in msats (this issue is expanded in the error section). 5. Actually tell them they're supposed to request an invoice when they receive an `invoice_request` for an offer! (They don't have to if it's a non-offer one, they would be expected to check with user). 6. No signatures on invoices if they're non-offer, but allow a verification code. If the user presents an offer to the ATM in the first place, this can be skipped, but requires it have a camera, and more interaction. Here are examples of the offer-request-invoice flow, and the request-invoice flow: ### offer-request-invoice: Rusty buys a coffee from Starblocks 1. Scans lno... * offer_description: 1 cup coffee. * offer_amount: 1000000msat * offer_issuer: Starblocks starblocks.acinq.co * offer_node_id: starblocks-nodeid 2. Rusty sends onionmessage to starblocks-nodeid with reply_path back Rusty, and invoice_request: * invoice_request_metadata: 23456... * offer_description: 1 cup coffee. * offer_amount: 1000000msat * offer_issuer: Starblocks starblocks.acinq.co * offer_node_id: starblocks-nodeid * invoice_request_payer_id: rusty-tmpkey * invoice_request_payer_note: love that coffee! * signature: SIG(^^, rusty-tmpkey) 3. Starblocks replies with invoice: * invoice_request_metadata: 23456... * offer_description: 1 cup coffee. * offer_amount: 1000000msat * offer_issuer: Starblocks starblocks.acinq.co * offer_node_id: starblocks-nodeid * invoice_request_payer_id: rusty-tmpkey * invoice_request_payer_note: love that coffee! * invoice_paths: 1 dummy-path * invoice_blindedpay: 1 dummy-payinfo * invoice_created_at: now * invoice_payment_hash: 34567... * signature: SIG(^^, offer_node_id) ### request-invoice: Rusty buys 1000 sats from Matt 1. Matt generates invoice request (lnr...) * offer_description: 25c worth of bitcoin * offer_issuer: BlueMatt * invoice_request_payer_id: matt-nodeid 2. Rusty scans this, sends onionmessage to matt-nodeid... with reply_path back Rusty (for errors). App shows the random invoice code for validation. * offer_description: 25c worth of bitcoin * offer_issuer: BlueMatt * invoice_request_payer_id: matt-nodeid * invoice_paths: At least 1 path * invoice_blindedpay: As many payinfo as invoice_path * invoice_created_at: now * invoice_payment_hash: 34567... * invoice_code: AV2PEE 3. Matt doesn't bother checking the invoice code and just hits "OK pay", because Rusty's right next to him and he assumes nobody intercepted the QR code. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Most confusingly, the "if `offer_amount` is present" case was exactly backwards, which doesn't make sense at all. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
100c819 to
7019d66
Compare
|
Merged into bolt12 PR. Thanks! |

Instead of a kind of dummy offer which asks you to send an invoice,
use a dummy invoice request, since it now contains all the offer
fields anyway. It simplifies things a little, but there's the
following fallout:
offer_node_idto distinguishinvoice-request-for-offer and invoice-request-no-offer, which makes
sense, since the vendor doesn't know that.
invoice_request_payer_keytoinvoice_request_payer_id. Inthe case of a public node making a non-offer invoice_request, it's
their id (as they are the payer), but it can omitted using blinded
paths (like the offer_node_id in offer).
This is makes them as small like the old send_invoice offer.
must specify in msats (this issue is expanded in the error section).
receive an
invoice_requestfor an offer! (They don't have to if it'sa non-offer one, they would be expected to check with user).
code. If the user presents an offer to the ATM in the first place, this
can be skipped, but requires it have a camera, and more interaction.
Here are examples of the offer-request-invoice flow, and the
request-invoice flow:
offer-request-invoice: Rusty buys a coffee from Starblocks
Scans lno...
Rusty sends onionmessage to starblocks-nodeid with reply_path back Rusty, and
invoice_request:
Starblocks replies with invoice:
request-invoice: Rusty buys 1000 sats from Matt
Matt generates invoice request (lnr...)
Rusty scans this, sends onionmessage to matt-nodeid... with reply_path back Rusty (for errors). App shows the random invoice code for validation.
Matt doesn't bother checking the invoice code and just hits "OK
pay", because Rusty's right next to him and he assumes nobody
intercepted the QR code.
Signed-off-by: Rusty Russell rusty@rustcorp.com.au