mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Merge pull request #1609 from NicolasDorier/pj3
Adapt PJ implementation to latest BIP
This commit is contained in:
commit
47baa219fd
2 changed files with 14 additions and 24 deletions
|
@ -127,6 +127,10 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
decimal minfeerate = -1.0m,
|
decimal minfeerate = -1.0m,
|
||||||
int v = 1)
|
int v = 1)
|
||||||
{
|
{
|
||||||
|
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||||
|
if (network == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
if (v != 1)
|
if (v != 1)
|
||||||
{
|
{
|
||||||
return BadRequest(new JObject
|
return BadRequest(new JObject
|
||||||
|
@ -137,11 +141,6 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
|
||||||
if (network == null)
|
|
||||||
{
|
|
||||||
return BadRequest(CreatePayjoinError("invalid-network", "Incorrect network"));
|
|
||||||
}
|
|
||||||
await using var ctx = new PayjoinReceiverContext(_invoiceRepository, _explorerClientProvider.GetExplorerClient(network), _payJoinRepository);
|
await using var ctx = new PayjoinReceiverContext(_invoiceRepository, _explorerClientProvider.GetExplorerClient(network), _payJoinRepository);
|
||||||
ObjectResult CreatePayjoinErrorAndLog(int httpCode, PayjoinReceiverWellknownErrors err, string debug)
|
ObjectResult CreatePayjoinErrorAndLog(int httpCode, PayjoinReceiverWellknownErrors err, string debug)
|
||||||
{
|
{
|
||||||
|
@ -174,7 +173,7 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
if (PSBT.TryParse(rawBody, network.NBitcoinNetwork, out var psbt))
|
if (PSBT.TryParse(rawBody, network.NBitcoinNetwork, out var psbt))
|
||||||
{
|
{
|
||||||
if (!psbt.IsAllFinalized())
|
if (!psbt.IsAllFinalized())
|
||||||
return BadRequest(CreatePayjoinError("psbt-not-finalized", "The PSBT should be finalized"));
|
return BadRequest(CreatePayjoinError("original-psbt-rejected", "The PSBT should be finalized"));
|
||||||
ctx.OriginalTransaction = psbt.ExtractTransaction();
|
ctx.OriginalTransaction = psbt.ExtractTransaction();
|
||||||
}
|
}
|
||||||
// BTCPay Server implementation support a transaction instead of PSBT
|
// BTCPay Server implementation support a transaction instead of PSBT
|
||||||
|
@ -182,7 +181,7 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
{
|
{
|
||||||
psbtFormat = false;
|
psbtFormat = false;
|
||||||
if (!Transaction.TryParse(rawBody, network.NBitcoinNetwork, out var tx))
|
if (!Transaction.TryParse(rawBody, network.NBitcoinNetwork, out var tx))
|
||||||
return BadRequest(CreatePayjoinError("invalid-format", "invalid transaction or psbt"));
|
return BadRequest(CreatePayjoinError("original-psbt-rejected", "invalid transaction or psbt"));
|
||||||
ctx.OriginalTransaction = tx;
|
ctx.OriginalTransaction = tx;
|
||||||
psbt = PSBT.FromTransaction(tx, network.NBitcoinNetwork);
|
psbt = PSBT.FromTransaction(tx, network.NBitcoinNetwork);
|
||||||
psbt = (await explorer.UpdatePSBTAsync(new UpdatePSBTRequest() { PSBT = psbt })).PSBT;
|
psbt = (await explorer.UpdatePSBTAsync(new UpdatePSBTRequest() { PSBT = psbt })).PSBT;
|
||||||
|
@ -200,11 +199,11 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
var sendersInputType = psbt.GetInputsScriptPubKeyType();
|
var sendersInputType = psbt.GetInputsScriptPubKeyType();
|
||||||
if (psbt.CheckSanity() is var errors && errors.Count != 0)
|
if (psbt.CheckSanity() is var errors && errors.Count != 0)
|
||||||
{
|
{
|
||||||
return BadRequest(CreatePayjoinError("insane-psbt", $"This PSBT is insane ({errors[0]})"));
|
return BadRequest(CreatePayjoinError("original-psbt-rejected", $"This PSBT is insane ({errors[0]})"));
|
||||||
}
|
}
|
||||||
if (!psbt.TryGetEstimatedFeeRate(out originalFeeRate))
|
if (!psbt.TryGetEstimatedFeeRate(out originalFeeRate))
|
||||||
{
|
{
|
||||||
return BadRequest(CreatePayjoinError("need-utxo-information",
|
return BadRequest(CreatePayjoinError("original-psbt-rejected",
|
||||||
"You need to provide Witness UTXO information to the PSBT."));
|
"You need to provide Witness UTXO information to the PSBT."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,19 +211,19 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
// to leak global xpubs
|
// to leak global xpubs
|
||||||
if (psbt.GlobalXPubs.Any())
|
if (psbt.GlobalXPubs.Any())
|
||||||
{
|
{
|
||||||
return BadRequest(CreatePayjoinError("leaking-data",
|
return BadRequest(CreatePayjoinError("original-psbt-rejected",
|
||||||
"GlobalXPubs should not be included in the PSBT"));
|
"GlobalXPubs should not be included in the PSBT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psbt.Outputs.Any(o => o.HDKeyPaths.Count != 0) || psbt.Inputs.Any(o => o.HDKeyPaths.Count != 0))
|
if (psbt.Outputs.Any(o => o.HDKeyPaths.Count != 0) || psbt.Inputs.Any(o => o.HDKeyPaths.Count != 0))
|
||||||
{
|
{
|
||||||
return BadRequest(CreatePayjoinError("leaking-data",
|
return BadRequest(CreatePayjoinError("original-psbt-rejected",
|
||||||
"Keypath information should not be included in the PSBT"));
|
"Keypath information should not be included in the PSBT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psbt.Inputs.Any(o => !o.IsFinalized()))
|
if (psbt.Inputs.Any(o => !o.IsFinalized()))
|
||||||
{
|
{
|
||||||
return BadRequest(CreatePayjoinError("psbt-not-finalized", "The PSBT Should be finalized"));
|
return BadRequest(CreatePayjoinError("original-psbt-rejected", "The PSBT Should be finalized"));
|
||||||
}
|
}
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
|
@ -232,7 +231,7 @@ namespace BTCPayServer.Payments.PayJoin
|
||||||
if (!mempool.Success)
|
if (!mempool.Success)
|
||||||
{
|
{
|
||||||
ctx.DoNotBroadcast();
|
ctx.DoNotBroadcast();
|
||||||
return BadRequest(CreatePayjoinError("invalid-transaction",
|
return BadRequest(CreatePayjoinError("original-psbt-rejected",
|
||||||
$"Provided transaction isn't mempool eligible {mempool.RPCCodeMessage}"));
|
$"Provided transaction isn't mempool eligible {mempool.RPCCodeMessage}"));
|
||||||
}
|
}
|
||||||
var enforcedLowR = ctx.OriginalTransaction.Inputs.All(IsLowR);
|
var enforcedLowR = ctx.OriginalTransaction.Inputs.All(IsLowR);
|
||||||
|
|
|
@ -293,28 +293,19 @@ namespace BTCPayServer.Services
|
||||||
|
|
||||||
public enum PayjoinReceiverWellknownErrors
|
public enum PayjoinReceiverWellknownErrors
|
||||||
{
|
{
|
||||||
LeakingData,
|
|
||||||
PSBTNotFinalized,
|
|
||||||
Unavailable,
|
Unavailable,
|
||||||
OutOfUTXOS,
|
|
||||||
NotEnoughMoney,
|
NotEnoughMoney,
|
||||||
InsanePSBT,
|
|
||||||
VersionUnsupported,
|
VersionUnsupported,
|
||||||
NeedUTXOInformation,
|
OriginalPSBTRejected
|
||||||
InvalidTransaction
|
|
||||||
}
|
}
|
||||||
public class PayjoinReceiverHelper
|
public class PayjoinReceiverHelper
|
||||||
{
|
{
|
||||||
static IEnumerable<(PayjoinReceiverWellknownErrors EnumValue, string ErrorCode, string Message)> Get()
|
static IEnumerable<(PayjoinReceiverWellknownErrors EnumValue, string ErrorCode, string Message)> Get()
|
||||||
{
|
{
|
||||||
yield return (PayjoinReceiverWellknownErrors.LeakingData, "leaking-data", "Key path information or GlobalXPubs should not be included in the original PSBT.");
|
|
||||||
yield return (PayjoinReceiverWellknownErrors.PSBTNotFinalized, "psbt-not-finalized", "The original PSBT must be finalized.");
|
|
||||||
yield return (PayjoinReceiverWellknownErrors.Unavailable, "unavailable", "The payjoin endpoint is not available for now.");
|
yield return (PayjoinReceiverWellknownErrors.Unavailable, "unavailable", "The payjoin endpoint is not available for now.");
|
||||||
yield return (PayjoinReceiverWellknownErrors.NotEnoughMoney, "not-enough-money", "The receiver added some inputs but could not bump the fee of the payjoin proposal.");
|
yield return (PayjoinReceiverWellknownErrors.NotEnoughMoney, "not-enough-money", "The receiver added some inputs but could not bump the fee of the payjoin proposal.");
|
||||||
yield return (PayjoinReceiverWellknownErrors.InsanePSBT, "insane-psbt", "Some consistency check on the PSBT failed.");
|
|
||||||
yield return (PayjoinReceiverWellknownErrors.VersionUnsupported, "version-unsupported", "This version of payjoin is not supported.");
|
yield return (PayjoinReceiverWellknownErrors.VersionUnsupported, "version-unsupported", "This version of payjoin is not supported.");
|
||||||
yield return (PayjoinReceiverWellknownErrors.NeedUTXOInformation, "need-utxo-information", "The witness UTXO or non witness UTXO is missing.");
|
yield return (PayjoinReceiverWellknownErrors.OriginalPSBTRejected, "original-psbt-rejected", "The receiver rejected the original PSBT.");
|
||||||
yield return (PayjoinReceiverWellknownErrors.InvalidTransaction, "invalid-transaction", "The original transaction is invalid for payjoin");
|
|
||||||
}
|
}
|
||||||
public static string GetErrorCode(PayjoinReceiverWellknownErrors err)
|
public static string GetErrorCode(PayjoinReceiverWellknownErrors err)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue