From rusty at rustcorp.com.au Thu Nov 15 03:56:31 2018 From: rusty at rustcorp.com.au (Rusty Russell) Date: Thu, 15 Nov 2018 14:26:31 +1030 Subject: [Lightning-dev] Strawman BOLT11 static "offer" format using probes. Message-ID: <87k1lfc7tc.fsf@rustcorp.com.au> Hi all, I want to propose a method of having reusable BOLT11 "offers" which provide almost-spontaneous payments as well as not requiring generating a BOLT11 invoice for each potential sale. An "offer" has a `p` field of 26 bytes (128 bits assuming top two are 0) (which is ignored by existing nodes). The payer uses a new lightning probe message using the current onion format we use for HTLCs to retreive the complete invoice. The format of the final-hop lightning onion would contain: [whatever-marker-we-need?][128-bit-`p`-field][[type,len,data]+] We would probably define a few optional types to start: 1. quantity: for ordering multiple of an item, default 1. 2. delivery-address: steal from https://www.w3.org/TR/vcard-rdf/#Delivery_Addressing_Properties ? 3. signature: basically a blob so payer can prove it was them. The return lightning message would contain a new bolt11 invoice (perhaps we optimize some fields by copying from the bolt11 offer if they don't appear?), and an additional field: `m` (27) `data_length` 52. Merkle hash of fields payer provided in onion msg above, and the offer `p` value. The payer checks the signature is correct, `m` is correct, and uses the invoice to pay as normal. The bolt11 offer + fields-from-onion + bolt11 invoice + preimage is the complete proof of payment. Refinements ----------- We can generate alternate leaves for the merkle tree (using SHA256(shared-secret | leafnum)) so revealing the `m` value doesn't risk revealing your delivery-address for example. The return needs to list the fields it *didn't* include in the merkle because it didn't accept them (the merchant doesn't want to be bound to conditions it doesn't understand!). We could add a `k` field to the bolt11 offer to allow the final invoice to delegated to a separate key. The default `x` (expiry) field for an offer which does not have an old-style 53-byte `p` field (ie. a "pure" offer) could be infinite. We could merkelize the delivery-address too :) I've handwaved a bit over the detailed format, because there are other things we want to put in the onion padding, and because the return is similar to the "soft-error"/"partial payment ack" proposals. Results ------- This gives us static invoicing, and a single static invoice (without an amount field) can thus be used to approximate "spontaneous" donations, while still providing proof of payment; indeed, providing non-transferrable proof-of-payment since the invoice now commits to the payer-provided signature. It also provides a platform for recurring payments: while we can do this with preimage-is-next-payment_hash, that requires pre-generation and isn't compatible with static invoices. I apologize that this wasn't fleshed out before the summit, but I overestimated the power of Scriptless Scripts so had mentally deferred this. Thanks! Rusty.