Privately sending payments while offline with BOLT12

Overview

I have an idea for devices to authorize payments from their remote online node while the device authorizing the payment has no direct internet connection. The receiver needs their node to be online though. I think we would need a slight adjustment to the BOLT12 invoice for this approach to be secure.

I’d appreciate any thoughts and criticism you may have!

Consider this scenario

  1. Buyer is at home with their phone phone connected to the internet (say it is running a Zeus wallet connected to a remote node).
  2. Buyer requests many invreq_payer_id and invreq_paths to be pre-computed on the node and stores them on the phone along with the secret keys corresponding to all of the invreq_payer_id. Each invreq_payer_id is assigned a validity time and budget and can be manually revoked later (in case the phone gets stolen).
  3. Buyer leaves home with their phone.
  4. Buyer’s node remains at home connected to the internet.
  5. Buyer arrives in a foreign land and can no longer connect to the internet.
  6. Buyer gets hungry
  7. Buyer finds a seller of food.
  8. Buyer needs to make payment for the food.
  9. Seller’s point of sale device wants to accept payment and has an internet connection.
  10. Buyer’s node back at home still has an internet connection.
  11. Seller’s point of sale provides a BOLT12 offer over NFC or QR.
  12. Buyer’s device reads the offer and responds with a signed invoice_request over NFC, QR, or bluetooth using some of the invreq_payer_id and invreq_paths it pre-computed before leaving home. It ignores the offer_paths or offer_issuer_id fields of the offer since it is not sending the reply as an onion message. It also sends a reply_path for sending an invoice back as an onion message.
  13. Seller’s point of sale device receives the invoice_request.
  14. Seller’s point of sale device responds with an onion message invoice back to the buyer’s node over the internet.
  15. Buyer’s node back at home receives the onion message invoice and pays the invoice.
  16. Seller’s point of sale device receives the payment and seller provides food.
  17. Buyer eats.

Changes to BOLT12 needed

The main flaw I see here is that when the buyer’s node receives the invoice, they have no way to check the invoice matches the invoice_request they authorized. In BOLT12, it seems to be the sender’s job to check all the fields in the invoice that they match their original invoice_request before paying. Could the signature in field 240 in the invoice_request be copied over to the invoice to field 239 so that the payer can verify they trust the invoice they received? It seems like this could also add to a lot of scalability and performance advantages for node implementations because they won’t have to keep track of all the outstanding invoice_requests that they have sent out (and periodically garbage collect them), they will just have to keep a list of invreq_payer_id. The logic here is that the sender’s node should be able to trust the signature from the invreq_payer_id it pre-generated for the buyer before the buyer went offline.

Workflow Advantages

1 Like

I have a long-ago tweet with a similar idea, i.e. the payer sends encrypted data to the payee, plus an onion-message path to its LSP or its high-uptime node.

Note that an LSP (instead of a high-uptime remote-controlled node) can be used here if the mobile phone of the payer is the client of that LSP. We only need to send the necessary messages (update_add_htlc et al) over onion-message instead of normal BOLT8 tunnel. Thus, I propose:

  1. Have some standard by which a remote control can talk to a high-uptime home node via BOLT8.
  2. Have a separate other standard by which a high-uptime payee can create a “BOLT8 tunnel” over onion messages, so that the payee can assist the payer in contacting either its LSP or its high-uptime home node. The LSP or the high-uptime home node then translates the onion messages to BOLT8 messages and treats them as another BOLT8 tunnel.

This expands the usability of the scheme to allow for both remote-controlled home nodes and mobile phone-with-LSP nodes to be the payer here.

You are talking about a custodial or non-custodial LSP?

That was exactly the goal of bLIP-0028: Paratonnerre by t-bast · Pull Request #28 · lightning/blips · GitHub, which can provide good security by pairing your remote node with a hardware wallet (e.g. Ledger or Coldcard). I still thinks it would be very useful to standardize the control messages in this bLIP.

Does bLIP-0028 do any onion messaging?

Also, at a high level, how does bLIP-0028 differ from what https://vls.tech/ attempts to do?

bLIP-0028 looks cool for a lot of use cases, but I’m wondering if it is much more complex in its feature set than what I’ve proposed for simple invoice payment with a merchant.

Related: I’ve discovered that there is a better LNURL solution that uses deterministic rolling withdrawal URI’s with a special NFC chip: Bolt Card · GitHub . The reference above appeared to use static LNURL withdrawal links, which seemed mostly insecure to me. The Bolt Card solution seems “okay” (despite all the architectural drawbacks of LNURL and the fact that you can’t pre-authorize exact amounts).