mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Include XPubs in PSBTs for multi sig (#6696)
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -19,7 +18,7 @@ namespace BTCPayServer.Blazor.VaultBridge;
|
|||||||
|
|
||||||
public abstract class HWIController : VaultController
|
public abstract class HWIController : VaultController
|
||||||
{
|
{
|
||||||
override protected string VaultUri => "http://127.0.0.1:65092/hwi-bridge/v1";
|
protected override string VaultUri => "http://127.0.0.1:65092/hwi-bridge/v1";
|
||||||
public string CryptoCode { get; set; }
|
public string CryptoCode { get; set; }
|
||||||
|
|
||||||
private static bool IsTrezorT(HwiEnumerateEntry deviceEntry)
|
private static bool IsTrezorT(HwiEnumerateEntry deviceEntry)
|
||||||
@@ -41,7 +40,7 @@ public abstract class HWIController : VaultController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var network = networkProviders.GetNetwork<BTCPayNetwork>(CryptoCode);
|
var network = networkProviders.GetNetwork<BTCPayNetwork>(CryptoCode);
|
||||||
var hwi = new Hwi.HwiClient(network.NBitcoinNetwork)
|
var hwi = new HwiClient(network.NBitcoinNetwork)
|
||||||
{
|
{
|
||||||
Transport = new VaultHWITransport(vaultClient), IgnoreInvalidNetwork = network.NBitcoinNetwork.ChainName != ChainName.Mainnet
|
Transport = new VaultHWITransport(vaultClient), IgnoreInvalidNetwork = network.NBitcoinNetwork.ChainName != ChainName.Mainnet
|
||||||
};
|
};
|
||||||
@@ -206,7 +205,6 @@ public class SignHWIController : HWIController
|
|||||||
ui.ShowRetry();
|
ui.ShowRetry();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
derivationSettings.RebaseKeyPaths(psbt);
|
derivationSettings.RebaseKeyPaths(psbt);
|
||||||
// otherwise, let the device check if it can sign anything
|
// otherwise, let the device check if it can sign anything
|
||||||
var signableInputs = psbt.Inputs
|
var signableInputs = psbt.Inputs
|
||||||
@@ -227,7 +225,7 @@ public class SignHWIController : HWIController
|
|||||||
if (derivationSettings.IsMultiSigOnServer)
|
if (derivationSettings.IsMultiSigOnServer)
|
||||||
{
|
{
|
||||||
var alreadySigned = psbt.Inputs.Any(a =>
|
var alreadySigned = psbt.Inputs.Any(a =>
|
||||||
a.PartialSigs.Any(a => a.Key == actualPubKey));
|
a.PartialSigs.Any(o => o.Key == actualPubKey));
|
||||||
if (alreadySigned)
|
if (alreadySigned)
|
||||||
{
|
{
|
||||||
ui.ShowFeedback(FeedbackType.Failed, ui.StringLocalizer["This device already signed PSBT."]);
|
ui.ShowFeedback(FeedbackType.Failed, ui.StringLocalizer["This device already signed PSBT."]);
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
SelectedInputs = request.SelectedInputs?.Select(point => point.ToString()),
|
SelectedInputs = request.SelectedInputs?.Select(point => point.ToString()),
|
||||||
Outputs = outputs,
|
Outputs = outputs,
|
||||||
AlwaysIncludeNonWitnessUTXO = true,
|
AlwaysIncludeNonWitnessUTXO = derivationScheme.DefaultIncludeNonWitnessUtxo,
|
||||||
InputSelection = request.SelectedInputs?.Any() is true,
|
InputSelection = request.SelectedInputs?.Any() is true,
|
||||||
FeeSatoshiPerByte = request.FeeRate?.SatoshiPerByte,
|
FeeSatoshiPerByte = request.FeeRate?.SatoshiPerByte,
|
||||||
NoChange = request.NoChange
|
NoChange = request.NoChange
|
||||||
|
|||||||
@@ -27,7 +27,12 @@ namespace BTCPayServer.Controllers
|
|||||||
public async Task<CreatePSBTResponse> CreatePSBT(BTCPayNetwork network, DerivationSchemeSettings derivationSettings, WalletSendModel sendModel, CancellationToken cancellationToken)
|
public async Task<CreatePSBTResponse> CreatePSBT(BTCPayNetwork network, DerivationSchemeSettings derivationSettings, WalletSendModel sendModel, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var nbx = ExplorerClientProvider.GetExplorerClient(network);
|
var nbx = ExplorerClientProvider.GetExplorerClient(network);
|
||||||
CreatePSBTRequest psbtRequest = new();
|
var psbtRequest = new CreatePSBTRequest()
|
||||||
|
{
|
||||||
|
RBF = network.SupportRBF ? true : null,
|
||||||
|
AlwaysIncludeNonWitnessUTXO = sendModel.AlwaysIncludeNonWitnessUTXO,
|
||||||
|
IncludeGlobalXPub = derivationSettings.IsMultiSigOnServer,
|
||||||
|
};
|
||||||
if (sendModel.InputSelection)
|
if (sendModel.InputSelection)
|
||||||
{
|
{
|
||||||
psbtRequest.IncludeOnlyOutpoints = sendModel.SelectedInputs?.Select(OutPoint.Parse).ToList() ?? new List<OutPoint>();
|
psbtRequest.IncludeOnlyOutpoints = sendModel.SelectedInputs?.Select(OutPoint.Parse).ToList() ?? new List<OutPoint>();
|
||||||
@@ -40,8 +45,6 @@ namespace BTCPayServer.Controllers
|
|||||||
psbtDestination.Amount = Money.Coins(transactionOutput.Amount ?? 0.0m);
|
psbtDestination.Amount = Money.Coins(transactionOutput.Amount ?? 0.0m);
|
||||||
psbtDestination.SubstractFees = transactionOutput.SubtractFeesFromOutput;
|
psbtDestination.SubstractFees = transactionOutput.SubtractFeesFromOutput;
|
||||||
}
|
}
|
||||||
psbtRequest.RBF = network.SupportRBF ? true : null;
|
|
||||||
psbtRequest.AlwaysIncludeNonWitnessUTXO = sendModel.AlwaysIncludeNonWitnessUTXO;
|
|
||||||
|
|
||||||
psbtRequest.FeePreference = new FeePreference();
|
psbtRequest.FeePreference = new FeePreference();
|
||||||
if (sendModel.FeeSatoshiPerByte is decimal v and > decimal.Zero)
|
if (sendModel.FeeSatoshiPerByte is decimal v and > decimal.Zero)
|
||||||
@@ -56,8 +59,7 @@ namespace BTCPayServer.Controllers
|
|||||||
var psbt = (await nbx.CreatePSBTAsync(derivationSettings.AccountDerivation, psbtRequest, cancellationToken));
|
var psbt = (await nbx.CreatePSBTAsync(derivationSettings.AccountDerivation, psbtRequest, cancellationToken));
|
||||||
if (psbt == null)
|
if (psbt == null)
|
||||||
throw new NotSupportedException(StringLocalizer["You need to update your version of NBXplorer"]);
|
throw new NotSupportedException(StringLocalizer["You need to update your version of NBXplorer"]);
|
||||||
// Not supported by coldcard, remove when they do support it
|
|
||||||
psbt.PSBT.GlobalXPubs.Clear();
|
|
||||||
return psbt;
|
return psbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
RBF = true,
|
RBF = true,
|
||||||
AlwaysIncludeNonWitnessUTXO = paymentMethod.DefaultIncludeNonWitnessUtxo,
|
AlwaysIncludeNonWitnessUTXO = paymentMethod.DefaultIncludeNonWitnessUtxo,
|
||||||
|
IncludeGlobalXPub = paymentMethod.IsMultiSigOnServer,
|
||||||
IncludeOnlyOutpoints = bumpableUTXOs,
|
IncludeOnlyOutpoints = bumpableUTXOs,
|
||||||
SpendAllMatchingOutpoints = true,
|
SpendAllMatchingOutpoints = true,
|
||||||
FeePreference = new FeePreference()
|
FeePreference = new FeePreference()
|
||||||
@@ -369,6 +370,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
RBF = true,
|
RBF = true,
|
||||||
AlwaysIncludeNonWitnessUTXO = paymentMethod.DefaultIncludeNonWitnessUtxo,
|
AlwaysIncludeNonWitnessUTXO = paymentMethod.DefaultIncludeNonWitnessUtxo,
|
||||||
|
IncludeGlobalXPub = paymentMethod.IsMultiSigOnServer,
|
||||||
IncludeOnlyOutpoints = tx.Transaction.Inputs.Select(i => i.PrevOut).ToList(),
|
IncludeOnlyOutpoints = tx.Transaction.Inputs.Select(i => i.PrevOut).ToList(),
|
||||||
SpendAllMatchingOutpoints = true,
|
SpendAllMatchingOutpoints = true,
|
||||||
DisableFingerprintRandomization = true,
|
DisableFingerprintRandomization = true,
|
||||||
@@ -1329,6 +1331,7 @@ namespace BTCPayServer.Controllers
|
|||||||
public async Task<IActionResult> WalletSendVault([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
|
public async Task<IActionResult> WalletSendVault([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
|
||||||
WalletSendVaultModel model)
|
WalletSendVaultModel model)
|
||||||
{
|
{
|
||||||
|
TempData.SetStatusSuccess(StringLocalizer["Transaction successfully signed"].Value);
|
||||||
return await RedirectToWalletPSBTReady(walletId, new WalletPSBTReadyViewModel
|
return await RedirectToWalletPSBTReady(walletId, new WalletPSBTReadyViewModel
|
||||||
{
|
{
|
||||||
SigningContext = model.SigningContext,
|
SigningContext = model.SigningContext,
|
||||||
|
|||||||
@@ -554,7 +554,8 @@ namespace BTCPayServer
|
|||||||
{
|
{
|
||||||
PSBT = psbt,
|
PSBT = psbt,
|
||||||
DerivationScheme = derivationSchemeSettings.AccountDerivation,
|
DerivationScheme = derivationSchemeSettings.AccountDerivation,
|
||||||
AlwaysIncludeNonWitnessUTXO = true
|
AlwaysIncludeNonWitnessUTXO = true,
|
||||||
|
IncludeGlobalXPub = derivationSchemeSettings.IsMultiSigOnServer
|
||||||
});
|
});
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1610,6 +1610,7 @@ namespace BTCPayServer.Services
|
|||||||
"Transaction fee rate:": "",
|
"Transaction fee rate:": "",
|
||||||
"Transaction Id": "",
|
"Transaction Id": "",
|
||||||
"Transaction signed successfully, proceeding to review...": "",
|
"Transaction signed successfully, proceeding to review...": "",
|
||||||
|
"Transaction successfully signed": "",
|
||||||
"transactions": "",
|
"transactions": "",
|
||||||
"Translations": "",
|
"Translations": "",
|
||||||
"Translations are formatted as JSON; for example, <b>{0}</b> translates <b>{1}</b> to <b>{2}</b>.": "",
|
"Translations are formatted as JSON; for example, <b>{0}</b> translates <b>{1}</b> to <b>{2}</b>.": "",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HWI/@EntryIndexedValue">HWI</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LNURL/@EntryIndexedValue">LNURL</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LNURL/@EntryIndexedValue">LNURL</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NB/@EntryIndexedValue">NBX</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NB/@EntryIndexedValue">NBX</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NBXplorer/@EntryIndexedValue">NBXplorer</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NBXplorer/@EntryIndexedValue">NBXplorer</s:String>
|
||||||
|
|||||||
Reference in New Issue
Block a user