Finally designing payer proofs, thanks for prompt nostr:nprofile1qqsr6tj32zrfn7v0pu4aheaytdnnc6rluepq73ndc2tdjzus34gat9qpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhswulwwv! This proves that the invoice was requested by you, and paid, in a nice standard format. Fields which aren't needed are omitted, but you can still verify the signature. Was a design aim for BOLT12, but now time to bring it into the world...
We produce the signed invoice (proving the node gave the invoice), and the pre image (proving it was paid). It also contains the (made up) key of the person who requested the invoice. We now need to sign something transient with that key to show we own it. I think it needs to be a simple string, because there are many cases: 1. I might want to link it to my nostr/Twitter handle or wherever I'm publishing my proof. 2. I might want to link it to my real name. 3. I might want to link it to a block hash to prove it was after some time? Then I can time-stamp pincer with opentimestamps to prove a time range of creation. 4. I may just want to attach a random snarky comment.
I wonder if the initiating app in BIP 21-replacement should be able to specify that string? Probably…
Maybe with some fixed prefix though.
This is for refunds? I think that's a different case, and should be baked into offers explicitly. Payer proofs are generally for blame and bragging...
No no, for offers. Imagine Nostr app wants to zap using BOLT 12. It does a system open for bitcoin:?lno=lnoffer&pop=proofcallback, but it ultimately needs the proof to include “Bob zapped with emoji🫠”. So either the proofcallback has to include the private key or that original URI has to include the string to sign.
I tried to make zaps a bolt12 thing at the start but I couldn’t figure this part out
Better late than never. See the Proof of Payment section at https://github.com/bitcoin/bips/pull/1555/files
I don’t see how web clients could fetch offer invoices though, would have to use lnsocket/lnmessage and websocket proxies. With lnurl it’s much easier for web apps to fetch invoices.
The web client shouldn’t be fetching the invoice, it just passes the whole offer on to the wallet and asks it to pay. When the wallet completes it does a callback to the initiating app.
Admittedly I wasn’t really thinking about web apps in the above design though. Nothing specific shouldn’t work except that the spec explicitly says wallets can’t open a callback URI that has a scheme of http(s). I was worried about it being a way for a payee to discover the payers IP, but I think maybe it doesn’t matter.
Yep, came back after rereading to correct my mis-assumption. Nonce could be implied or explicit here. You could use URL itself (or its hash) but good luck with canonicalizationissues :( Not entirely sure *payer* proof is required here, but it's good practice.
I think it’s required. If we’re flipping it to have the nostr zapper broadcast the zap (which we should) you need to cryptographically tie the nostr zapper to the payment proof somehow. I can see the argument for returning the key explicitly (it’s simple, the initiating app is the payer, kinda), but it feels pretty gross (two copies of a key always bad if you can only have one). Seems cleaner to just pass the message in the original URI?