diff --git a/README.md b/README.md index 602b3c7..cedf039 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,4 @@ For more detail on the process, please read [bLIP-0001](./blip-0001.md) and | [17](./blip-0017.md) | Hosted Channels | Anton Kumaigorodskiy | Active | | [25](./blip-0025.md) | Forward less than onion value | Valentine Wallace | Active | | [32](./blip-0032.md) | Onion Message DNS Resolution | Matt Corallo | Active | +| [42](./blip-0042.md) | Bolt 12 Contacts | Bastien Teinturier | Active | \ No newline at end of file diff --git a/blip-0042.md b/blip-0042.md new file mode 100644 index 0000000..f24b539 --- /dev/null +++ b/blip-0042.md @@ -0,0 +1,71 @@ +``` +bLIP: 42 +Title: Bolt 12 Contacts +Status: Active +Author: Bastien Teinturier +Created: 2024-07-19 +License: CC0 +``` + +## Abstract + +Bolt 12 introduces offers, which are static lightning "addresses". An offer can +be stored and reused to pay the same node many times. It then becomes natural to +associate Bolt 12 offers to your friends and contacts. + +When sending payments to contacts, you may want them to know that the payment +came from you. We propose a scheme to deterministically derive the `payer_key` +used in the `invoice_request` based on the payer and payee's offers. Nodes +receiving payments can match the `payer_id` with their contact list to see if +the payment came from one of their contacts. + +## Copyright + +This bLIP is licensed under the CC0 license. + +## Motivation + +This feature provides a better UX for lightning wallets, by making payments +between trusted contacts look very similar to fiat payment applications. + +## Specification + +Payers derive a deterministic `payer_key` based on one of their offers, that +they expect the recipient to have in their contacts list, and the offer that +they are paying. + +### Requirements + +A node sending `invoice_request` for a given `offer`: + +- If it wants to use a deterministic `payer_key`: + - MUST compute the following tweak: + - `tweak = SHA256("blip42_bolt12_contacts" || offer.offer_id)`. + - MUST choose one of its own offers that the recipient may know: + - MUST multiply the private key used to sign invoices for this offer with `tweak`. + - MUST use the resulting private key as `payer_key` to sign the `invoice_request`. +- Otherwise: + - SHOULD use a random `payer_key`. + +A node receiving `invoice_request`: + +- For each `offer` from its trusted contacts: + - SHOULD compute the deterministic `payer_id` associated with that `offer`: + - `tweak = SHA256("blip42_bolt12_contacts" || invoice_request.offer)`. + - `payer_id = tweak * offer.node_id`. + - SHOULD compare that `payer_id` with the `invoice_request`'s `payer_id`. + - If they match: + - SHOULD mark the payment as coming from this contact. + - SHOULD display the `payer_note` contained in the `invoice_request`. + +### Rationale + +Nodes may compute their contacts' `payer_id`s once and store it along with that +contact instead of recomputing them on-the-fly whenever a payment is received. + +When a payment comes from a trust contact, it is safe to display the payment's +`payer_note`: otherwise it may contain spam or phishing. + +## Reference Implementations + +- lightning-kmp: