bolts
bolts copied to clipboard
Offers
Offers are "static invoices", with many more features. This is mostly implemented in c-lightning already, and is now ready for wider testing.
This PR is based on onion messages specified in #759
I have merged the million-fixup-commits into one commit, and trivially rebased onto the updated #759.
The last two commits are new:
- Make spelling happy.
- Add a method to replace invoices; I've not yet implemented this though!
I have a question with respect to replacing invoices and the fact that we can proof if the payee claimed both htlcs:
What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?
The only fix that cryptographically would give us a guarantee to not pay twice that I can think of only seems to shift the problem of stuck payments (and would thus create a burden to the network) and is the following:
- Assume Alice sends out an onion to Bob over some path that gets stuck
- Alice wants to use your replacement mechanism to cancle the payment.
- before (!) sending out a new onion with the new payment hash alice waits for an incoming htlc of the old payment hash (this assumes that Bob after sending out the replacement invoice sets a "reimbursement path" to Alice.
Now we have 2 scenarios:
- The orinal payment times out and gets unstuck. Alice would also cancle the reimbursement payment (of course opening Bob to a stuck payment attack from Alice or actually from anyone else when he sets up the reimbursement path)
- The original onion arrives at Bob. He should fail the onion and if so Alice should fail the reimbursement onion once her initial htlc is withdrawn or if Bob claims the funds Alice can use the preimage on the reimbursement path to claim her money back.
As said initially: I don't think the reimbursement path (which is by the way inspired by the boomerang paper c.f.: https://arxiv.org/abs/1910.01834 ) solves any issue in our case because the reimbursement path is also open to stuck payment attacks and overall we bind liquidity in two directions now.
What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?
Today, the seller can already accept the payment and not deliver the product which is not very different from accepting the payment twice. These real world interactions can't be enforced by cryptography, we need to trust the seller (or the legal system in which the seller operates). The best we can get is a cryptographic proof that the seller misbehaved that can be used so that other people stop trusting this seller (or for prosecuting the seller).
What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?
Today, the seller can already accept the payment and not deliver the product which is not very different from accepting the payment twice. These real world interactions can't be enforced by cryptography, we need to trust the seller (or the legal system in which the seller operates). The best we can get is a cryptographic proof that the seller misbehaved that can be used so that other people stop trusting this seller (or for prosecuting the seller).
Exactly, you still risk paying twice, but you can prove it happened and that they promised it wouldn't. Not perfect, but it's an option.
OK, trivial rebase to fixup, and also new commits:
- signatures on offers are now optional. This makes them much smaller, particularly on mainnet where it's just "node_id", "description" and any optional fields. We might deprecate them altogether?
- @renepickhardt suggested that adding capacities for each blinded path would be a good feature, and as it's completely optional I added it.
- @niftynei suggested a payer note field, where the payer could make some comment. This is particularly useful for tips, and again completely optional to implement, so I added it.
It would be cool, if offers included a standard way to exchange information to comply with the FATF travel rule. VASPs need a way to verify that a customer has control over the wallet where a deposit comes from or a withdrawal goes to. For On-chain this is usually done by either signing a message or executing a micro transaction. Now maybe it is enough to define a workflow to require the customer to put a specific message to the payer_note field. But even if that works out, it might be better to have specific fields and a standardized workflow.
@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey?
Since the signature
on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.
Kudos for doing this btw.
@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey? Since the
signature
on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.Kudos for doing this btw.
Indeed, it's possible to have a "default" offer, where we assume all other fields are absent, and simply try paying it. But it's also trivial to add later, so...
OK, at @t-bast 's suggestion I removed recurrence for now. You're free to implement it, ofc, but don't assume wallets support it yet.
I've also (trivially) rebased on the latest #759 draft.
OK, I fixed the incorrect placement of the offers fields, rebased onto the latest #759 and squashed some fixup commits. It's still more than one commitment because I think it's useful to see the broad changes which have occurred, just not every typo!
I just finished reading up on stateless bolt11 invoices (https://github.com/lightning/bolts/pull/912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the payment_metadata
tlv or are there other considerations?
I just finished reading up on stateless bolt11 invoices (#912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the
payment_metadata
tlv or are there other considerations?
With blinded routes, you can include any payment_metadata
you want in the last blinded payload.
@thomash-acinq: ah yes I just found this comment by @t-bast which mentioned this. neat, thx!
Hey everyone, super pumped for BOLT12. One thing: is there a way we could add a signature to this offer? As an example, I have a website that's presenting a BOLT12 invoice for payment. However, there is a malicious web extension in the browser, which swaps the QR/invoice on the page. User pays the attacker and payment flow gets broken.
Is there a way we can add a recoverable, compressed secp256k1 signature to the offer, as well as a domain? This would (1) allow us to verify public key of the signature with public key available at the domain (whether through DNS or HTTPS, haven't decided yet), letting us put a big green checkmark in the user's wallet to show they're indeed paying the company they want to.
And (2) would then allow us to do info fetching outside payment flow. For example, fetching an image of the company's logo and formatted company name to display in the wallet (which is very useful for UX).
If not and we want to keep this down, that's okay too. We'll likely be looking at building another specification which would incorporate a BOLT12 and other features, and we could add this functionality in there.
Yes, it is optional but the offer can include a signature if you want. However I would expect most offers to not be signed to fit in smaller QR codes. But even if the offer is not signed, the invoice will be, so any check that would have done on the offer can be done on the invoice.
Thanks, this makes a lot of sense. Assuming we don't put a signature in the offer, could we add some sort of domain field then? Actually, rather than adding it directly into BOLT12 which could bloat it, it would probably be optimal to do this in a wrapper protocol, right? Maybe the domain approves a certain list of node IDs that it owns and that is available outside LN.
Submitted a PR to force the use blinded routes when paying: https://github.com/rustyrussell/lightning-rfc/pull/4
New PR to switch to full public keys (like everywhere else in the spec): https://github.com/rustyrussell/lightning-rfc/pull/5 I'll update my code and will post some tests vectors here soon.
I've added some new test vectors: https://github.com/rustyrussell/lightning-rfc/pull/6 They should be up to date with all the recent changes (including mandatory blinded paths and full 33 bytes keys).
@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey? Since the
signature
on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.Kudos for doing this btw.
Yes, this can be done, by convention. Simply define a "default" offer, (e.g. no, or empty description), any anyone can generate that offer given the pubkey. If you want to accept that kind of offer, you generate that locally, and it will Just Work.
I just finished reading up on stateless bolt11 invoices (#912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the
payment_metadata
tlv or are there other considerations?
@thomash-acinq points out that you can do this with blinded paths already, which simply says "put this blob inside the onion"...
Hey everyone, super pumped for BOLT12.
First off, thanks for your spelling review! I applied almost all ("e.g." is used in the style guide, so I left that).
One thing: is there a way we could add a signature to this offer? As an example, I have a website that's presenting a BOLT12 invoice for payment. However, there is a malicious web extension in the browser, which swaps the QR/invoice on the page. User pays the attacker and payment flow gets broken.
The sensitivity here is "is this the right nodeid"? For that, you want something like https://github.com/rustyrussell/bolt12address
And (2) would then allow us to do info fetching outside payment flow. For example, fetching an image of the company's logo and formatted company name to display in the wallet (which is very useful for UX).
Definitely: I would love to add this metadata to the proposal above.
To be clear: I don't want to normalize "your wallet reaches to company X's website when scanning their offer" as it's such a huge privacy leak. Hence having a bundle you can validate yourself, so you can fetch it from anyone...
If not and we want to keep this down, that's okay too. We'll likely be looking at building another specification which would incorporate a BOLT12 and other features, and we could add this functionality in there.
Yeah, I think this is best built on-top, but it is important!
OK, rebased on latest #759 and folded into a single, neat "draft 5" commit.
I've added one commit, which defines our first invoice feature (mpp). Feedback welcome!
Rebased again, with more quantity_max requirement tweaks thanks to @jkczyz
BOLT 12 offers static QR codes for "offers" that won't change. How is it possible for the QR code to be static if a blinded path is used? Since routes are not guaranteed to be static forever, it seems like this is not possible. Or, is the static QR code just not applicable when blinded paths are used?
Since routes are not guaranteed to be static forever, it seems like this is not possible.
I believe you're mostly referring to payment blinded paths which expire quickly (for privacy reasons), but the offer blinded path is used to fetch invoices over onion messages, where you can have blinded paths that don't expire. An offer blinded path will only expire if:
- one of the nodes inside the path has permanently disappeared
- a pair of nodes in the path have no channels between themselves and disabled onion messages relay to non-channel peers
So there are cases where you'll need to refresh the offer's blinded path depending on your use-case, but it shouldn't be that often.
Okay, so choosing a blinded path where all peers in the path have many channels between each other gives me a high likelihood of the path remaining static because (1) if they have a lot of channels between each other that hints to me that they likely won't disappear in the future because they are committed to their presence in the network, and (2) they have lots of channels between each other so if one gets closed for whatever reason there will still be a redundant channel to fall back on to send the invoice request message over?
Also, it's unclear whether I can specify multiple blinded paths in an offer to give even more redundancy over a node in the path permanently disappearing (or if only one blinded path is allowed).
Why do payment blinded paths need to expire quickly for privacy reasons by offer blinded paths don't need to expire quickly for privacy reasons?
Why do payment blinded paths need to expire quickly for privacy reasons by offer blinded paths don't need to expire quickly for privacy reasons?
This is quite technical, have a look at the route blinding PR for that. Long story short is that a payment has many parameters that a sender can tweak, which may lead to different decisions from intermediate nodes, which gives the sender a way to probe and figure out which channels are actually used. Onion messages don't have any of those.
General comment: BOLT 12 seems to rely on changes to other BOLTS for the route blinding and onion messaging features. There doesn't seem to be any revision to a BOLT other than what GIT provides. I'm aware that "The specifications are currently a work-in-progress and currently being drafted.", but it seems if they should remain in an alpha or beta state, there should be some indicator that a major overhaul to a BOLT was made and that a feature in a new BOLT relies on a feature in a heavily revised existing BOLT. It's hard for me to follow where all the stuff advertised on https://bolt12.org/ comes from when reading https://bolt12.org/bolt12.html .
Also, it's unclear whether I can specify multiple blinded paths in an offer to give even more redundancy over a node in the path permanently disappearing (or if only one blinded path is allowed).
The *
in the following notation indicates more than one blinded path can be specified:
[...*blinded_path
:paths
]