@@ -62,10 +62,20 @@ to allow contacts to pay them back:
62
62
63
63
#### Requirements
64
64
65
- The writer of ` invoice_request ` , when paying one of their contacts:
66
-
67
- - If it wants the payer to be able to identify who paid them:
68
- - MUST include the ` invreq_contact_secret ` associated with that contact.
65
+ The writer of ` invoice_request ` :
66
+
67
+ - If they want the recipient to be able to identify who paid them:
68
+ - If the recipient is not yet part of their contacts list:
69
+ - If they have previously received a payment from this recipient including
70
+ the ` invreq_contact_secret ` field:
71
+ - MUST associate the received ` invreq_contact_secret ` with this contact.
72
+ - MUST include this ` invreq_contact_secret ` whenever paying this contact.
73
+ - Otherwise:
74
+ - MUST generate a unique ` invreq_contact_secret ` for that contact.
75
+ - MUST associate this ` invreq_contact_secret ` with this contact.
76
+ - MUST include this ` invreq_contact_secret ` whenever paying this contact.
77
+ - Otherwise:
78
+ - MUST include the ` invreq_contact_secret ` associated with this contact.
69
79
- MUST include either ` invreq_payer_offer ` or ` invreq_payer_bip_353_name ` .
70
80
- If it includes ` invreq_payer_bip_353_name ` :
71
81
- MUST set ` name ` to the post-₿, pre-@ part of the BIP 353 HRN.
@@ -84,21 +94,27 @@ The reader of `invoice_request`:
84
94
- MUST send back an ` invoice ` including the ` invoice_request ` contact fields
85
95
provided by the sender, as specified in Bolt 12.
86
96
- After the invoice has been paid, if ` invreq_contact_secret ` was included:
87
- - If it matches one of its contacts:
97
+ - If it matches one of their contacts:
88
98
- SHOULD display the ` invreq_payer_note ` , if one is provided.
99
+ - MUST ignore ` invreq_payer_offer ` and ` invreq_bip_353_name ` .
89
100
- Otherwise:
90
101
- MAY use the ` contact_secret ` , ` payer_offer ` and ` payer_bip_353_name ` to
91
- create a new contact.
92
- - If it creates a new contact based on this received payment, the
93
- received ` contact_secret ` MUST be used when paying that contact.
94
- - MAY associate the received ` contact_secret ` with an existing contact.
95
- - MUST ignore ` invreq_payer_offer ` and ` invreq_bip_353_name ` if it already
96
- has an offer for this contact.
102
+ create a new contact. If they do:
103
+ - MUST use the received ` contact_secret ` whenever paying that contact.
104
+ - MUST use the received ` payer_offer ` whenever paying that contact.
105
+ - If ` payer_bip_353_name ` was included:
106
+ - MUST use it to fetch a ` payer_offer ` if none was included.
107
+ - MUST use it to refresh the ` payer_offer ` when it expires.
108
+ - MAY use it to refresh the ` payer_offer ` periodically.
109
+ - MAY manually associate the received ` contact_secret ` with an existing
110
+ contact, if the user verified that the payment came from this contact.
97
111
98
112
#### Rationale
99
113
100
- The ` contact_secret ` field is used for mutual identification: its usage is
101
- detailed in the [ Contact Secrets] ( #contact-secrets ) section below.
114
+ The ` contact_secret ` field is used for mutual identification: it is set by the
115
+ node sending the first payment and must be reused by the recipient when sending
116
+ payments in the other direction. Its usage and edge cases are detailed in the
117
+ [ Contact Secrets] ( #contact-secrets ) section below.
102
118
103
119
Nodes generally don't store every ` invoice_request ` they receive, because that
104
120
would expose them to DoS. They instead include the fields they would like to
@@ -123,18 +139,23 @@ own offers.
123
139
124
140
The main mechanism of this proposal is the exchange of ` contact_secret ` s.
125
141
This section details various scenarios that may occur and how to correctly
126
- deal with each of them.
142
+ deal with each of them, along with a recommended UX .
127
143
128
144
#### Adding contacts
129
145
130
- When Alice adds Bob to her contacts list from an offer she received from Bob,
131
- she generates a random ` contact_secret ` . For all future payments made to Bob
132
- where she wants to reveal that she's the payer, Alice will include this same
133
- ` contact_secret ` .
134
-
135
- Once Bob has received a payment that includes a ` contact_secret ` , he may add
136
- the payer to its own contacts list. If he knows that this payment came from
137
- Alice, he's able to add Alice to his contacts and pay her back using the
146
+ When Alice wants to pay Bob, her wallet should offer an option to add him to
147
+ her contacts list (using a checkbox or a dedicated button). If she chooses
148
+ that option, she generates a random ` contact_secret ` . For all future payments
149
+ made to Bob where she wants to reveal that she's the payer, Alice will include
150
+ this same ` contact_secret ` . Wallets should always offer the option to pay a
151
+ contact privately, in which case the ` contact_secret ` and payer information
152
+ will not be included in the ` invoice_request ` .
153
+
154
+ Once Bob has received a payment that includes a ` contact_secret ` , his wallet
155
+ should display an option to add the payer to its own contacts list (e.g. via
156
+ a dedicated button the received payment page). If he knows that this payment
157
+ came from Alice (because Alice verifiably told him that it indeed came from
158
+ her), he's able to add Alice to his contacts and pay her back using the
138
159
` payer_offer ` or ` payer_bip_353_name ` she provided. For all future payments
139
160
made to Alice where Bob wants to reveal that he's the payer, Bob will include
140
161
the ` contact_secret ` generated by Alice. Note that in this case, Bob doesn't
@@ -148,12 +169,14 @@ than the one used to receive Alice's payment, Bob will generate a different
148
169
random ` contact_secret ` . For all payments made to Alice where he wants to
149
170
reveal that he's the payer, he will use that new ` contact_secret ` . When Alice
150
171
receives those payments, she won't be able to automatically identify that it's
151
- coming from Bob based on the ` contact_secret ` alone. But Alice is usually able
152
- to know that a specific payment came from Bob: she can then detect that Bob
153
- used a different ` contact_secret ` from the one she initially created, and she
154
- can store that additional ` contact_secret ` to the list of secrets Bob may use
155
- when paying her. This action automatically reconciles past and future payments
156
- made from Bob.
172
+ coming from Bob based on the ` contact_secret ` alone, because it is different
173
+ from the one she generated. But if Alice knows that a specific payment came
174
+ from Bob (because he verifiably told her so), her wallet should allow her to
175
+ attribute this payment to an existing contact (e.g. by clicking an "add to
176
+ contacts" button on the received payment and then choosing an "add to existing
177
+ contact" option). Her wallet will then add that additional ` contact_secret ` to
178
+ the list of secrets Bob may use when paying her. This action automatically
179
+ reconciles past and future payments made from Bob.
157
180
158
181
A contact entry thus contains the following information:
159
182
@@ -165,10 +188,6 @@ A contact entry thus contains the following information:
165
188
that our contact may use when paying us, obtained by manually associating
166
189
payments with our existing contact.
167
190
168
- Note that wallets can also automatically reconcile payments when they detect
169
- that the ` payer_offer ` or ` payer_bip_353_name ` received matches an existing
170
- contact but uses a different ` contact_secret ` .
171
-
172
191
#### Leaked contact secrets
173
192
174
193
Contact secrets shouldn't be shared publicly, as that would let other people
0 commit comments