You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: bip-0078.mediawiki
+26-7Lines changed: 26 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ Other than that, our proposal is very similar.
64
64
65
65
In a payjoin payment, the following steps happen:
66
66
67
-
* The receiver of the payment, presents a [[bip-021.mediawiki|BIP 21 URI]] to the sender with a parameter <code>pj</code> describing a payjoin endpoint.
67
+
* The receiver of the payment, presents a [[bip-021.mediawiki|BIP 21 URI]] to the sender with a parameter <code>pj=</code> describing a payjoin endpoint.
68
68
* The sender creates a signed, finalized PSBT with witness UTXO or previous transactions of the inputs. We call this PSBT the <code>original</code>.
69
69
* The receiver replies back with a signed PSBT containing his own signed inputs/outputs and those of the sender. We call this PSBT <code>Payjoin proposal</code>.
70
70
* The sender verifies the proposal, re-signs his inputs and broadcasts the transaction to the Bitcoin network. We call this transaction <code>Payjoin transaction</code>.
@@ -118,6 +118,12 @@ The payjoin proposal MAY:
118
118
The payjoin proposal MUST NOT:
119
119
* Shuffle the order of inputs or outputs, the additional outputs or additional inputs must be inserted at a random index.
120
120
121
+
===BIP21 payjoin parameters===
122
+
123
+
This proposal is defining the following new [[bip-021.mediawiki|BIP 21 URI]] parameters:
124
+
* <code>pj=</code>: Represents an http(s) endpoint which the sender can POST the original PSBT.
125
+
* <code>pjos=0</code>: Signal to the sender that they MUST disallow [[#output-substitution|payment output substitution]]. (See [[#unsecured-payjoin|Unsecured payjoin server]])
When the payjoin sender posts the original PSBT to the receiver, he can optionally specify the following HTTP query string parameters:
@@ -242,7 +248,8 @@ The receiver needs to do some check on the original PSBT before proceeding:
242
248
===Sender's payjoin proposal checklist===
243
249
244
250
The sender should check the payjoin proposal before signing it to prevent a malicious receiver from stealing money.
245
-
251
+
252
+
* If the receiver's BIP21 signalled <code>pjos=0</code>, disable payment output substitution.
246
253
* Verify that the transaction version, and the nLockTime are unchanged.
247
254
* Check that the sender's inputs' sequence numbers are unchanged.
248
255
* For each inputs in the proposal:
@@ -264,7 +271,7 @@ The sender should check the payjoin proposal before signing it to prevent a mali
264
271
*** The amount that was substracted from the output's value is less or equal to <code>maxadditionalfeecontribution</code>. Let's call this amount <code>actual contribution</code>.
265
272
*** Make sure the actual contribution is only paying fee: The <code>actual contribution</code> is less or equals to the difference of absolute fee between the payjoin proposal and the original PSBT.
266
273
*** Make sure the actual contribution is only paying for fee incurred by additional inputs: <code>actual contribution</code> is less or equals to <code>originalPSBTFeeRate * vsize(sender_input_type) * (count(original_psbt_inputs) - count(payjoin_proposal_inputs))</code>. (see [[#fee-output|Fee output]] section)
267
-
** If the output is the payment output and <code>disableoutputsubstitution=</code> is <code>false</code or not specified
274
+
** If the output is the payment output and payment output substitution is disabled.
268
275
*** Do not make any check
269
276
** Else
270
277
*** Make sure the output's value did not changed.
@@ -274,7 +281,7 @@ The sender should check the payjoin proposal before signing it to prevent a mali
274
281
The sender must be careful to only sign the inputs that were present in the original PSBT and nothing else.
275
282
276
283
Note:
277
-
* The sender must allow the receiver to add/remove or modify the receiver's own outputs (Except if explicitly disabled via the optional parameter <code>disableoutputsubstitution=</code>)
284
+
* The sender must allow the receiver to add/remove or modify the receiver's own outputs (if [[#output-substitution|payment output substitution]], the payment's output should not be modified)
278
285
* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the paymout output scriptPubKey type.
279
286
* If no input have been added, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface.
280
287
@@ -335,6 +342,13 @@ On top of this the receiver can poison analysis by randomly faking a round amoun
335
342
The receiver is free to change the output paying to himself.
336
343
For example, if the sender's scriptPubKey type is P2WPKH while the receiver's payment output in the original PSBT is P2SH, then the receiver can substitute the payment output to be P2WPKH to match the sender's scriptPubKey type.
A receiver might run the payment server (generating the BIP21 invoice) on a different server than the payjoin server, which could be less trusted than the payment server.
348
+
349
+
In such case, the payment server can signal to the sender, via the BIP21 parameter <code>pjos=0</code>, that they MUST disallow [[#output-substitution|payment output substitution]].
350
+
A compromised payjoin server could still the hot wallet outputs of the receiver, but would not be able to re-route payment to himself.
351
+
338
352
===Impacted heuristics===
339
353
340
354
Our proposal of payjoin is breaking the following blockchain heuristics:
@@ -382,7 +396,7 @@ The sender's software wallet can verify that the payjoin proposal is legitimate
382
396
However, a hardware wallet can't verify that this is indeed the case. This means that the security guarantee of the hardware wallet is decreased. If the sender's software is compromised, the hardware wallet would sign two valid transactions, thus sending two payments.
383
397
384
398
Without payjoin, the maximum amount of money that could be lost by a compromised software is equal to one payment (via [[#output-substitution|payment output substitution]]).
385
-
Note that the sender can opt out payment output substitution my using the optional parameter <code>disableoutputsubstitution=true</code>.
399
+
Note that the sender can disallow [[#output-substitution|payment output substitution]] by using the optional parameter <code>disableoutputsubstitution=true</code>.
386
400
387
401
With payjoin, the maximum amount of money that can be lost is equal to two payments.
388
402
@@ -412,6 +426,11 @@ public async Task<PSBT> RequestPayjoin(
412
426
throw new InvalidOperationException("The original PSBT should not be finalized.");
0 commit comments