From 7e5d269c396b597eba3b08608490db3dda042eeb Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Mon, 25 May 2020 07:41:30 +0900 Subject: [PATCH] Remove LedgerWallet direct integration --- BTCPayServer.Tests/PSBTTests.cs | 5 - BTCPayServer/BTCPayServer.csproj | 4 - .../Controllers/StoresController.BTCLike.cs | 77 --------- BTCPayServer/Controllers/VaultController.cs | 1 - .../Controllers/WalletsController.PSBT.cs | 2 - BTCPayServer/Controllers/WalletsController.cs | 156 ----------------- .../WalletViewModels/WalletSendLedgerModel.cs | 13 -- .../Services/HardwareWalletService.cs | 77 --------- .../Services/LedgerHardwareWalletService.cs | 157 ------------------ .../Views/Stores/AddDerivationScheme.cshtml | 8 +- ...vationSchemes_HardwareWalletDialogs.cshtml | 54 ------ .../Views/Wallets/WalletSendLedger.cshtml | 48 ------ .../Views/Wallets/WalletSigningMenu.cshtml | 7 +- .../wwwroot/js/StoreAddDerivationScheme.js | 106 +----------- BTCPayServer/wwwroot/js/WalletSendLedger.js | 95 ----------- BTCPayServer/wwwroot/js/ledgerwebsocket.js | 7 - BTCPayServer/wwwroot/main/site.css | 4 - 17 files changed, 7 insertions(+), 814 deletions(-) delete mode 100644 BTCPayServer/Models/WalletViewModels/WalletSendLedgerModel.cs delete mode 100644 BTCPayServer/Services/HardwareWalletService.cs delete mode 100644 BTCPayServer/Services/LedgerHardwareWalletService.cs delete mode 100644 BTCPayServer/Views/Wallets/WalletSendLedger.cshtml delete mode 100644 BTCPayServer/wwwroot/js/WalletSendLedger.js delete mode 100644 BTCPayServer/wwwroot/js/ledgerwebsocket.js diff --git a/BTCPayServer.Tests/PSBTTests.cs b/BTCPayServer.Tests/PSBTTests.cs index e97a7ec76..b735ef508 100644 --- a/BTCPayServer.Tests/PSBTTests.cs +++ b/BTCPayServer.Tests/PSBTTests.cs @@ -66,10 +66,6 @@ namespace BTCPayServer.Tests FeeSatoshiPerByte = 1, CurrentBalance = 1.5m }; - var vmLedger = await walletController.WalletSend(walletId, sendModel, command: "ledger").AssertViewModelAsync(); - PSBT.Parse(vmLedger.SigningContext.PSBT, user.SupportedNetwork.NBitcoinNetwork); - BitcoinAddress.Create(vmLedger.SigningContext.ChangeAddress, user.SupportedNetwork.NBitcoinNetwork); - Assert.NotNull(vmLedger.WebsocketPath); string redirectedPSBT = AssertRedirectedPSBT(await walletController.WalletSend(walletId, sendModel, command: "analyze-psbt"), nameof(walletController.WalletPSBT)); var vmPSBT = await walletController.WalletPSBT(walletId, new WalletPSBTViewModel() { PSBT = redirectedPSBT }).AssertViewModelAsync(); @@ -79,7 +75,6 @@ namespace BTCPayServer.Tests var filePSBT = (FileContentResult)(await walletController.WalletPSBT(walletId, vmPSBT, "save-psbt")); PSBT.Load(filePSBT.FileContents, user.SupportedNetwork.NBitcoinNetwork); - await walletController.WalletPSBT(walletId, vmPSBT, "ledger").AssertViewModelAsync(); var vmPSBT2 = await walletController.WalletPSBTReady(walletId, new WalletPSBTReadyViewModel() { SigningContext = new SigningContextModel() diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj index 85ddd87be..c848dfba2 100644 --- a/BTCPayServer/BTCPayServer.csproj +++ b/BTCPayServer/BTCPayServer.csproj @@ -36,7 +36,6 @@ - all @@ -205,9 +204,6 @@ $(IncludeRazorContentInPack) - - $(IncludeRazorContentInPack) - $(IncludeRazorContentInPack) diff --git a/BTCPayServer/Controllers/StoresController.BTCLike.cs b/BTCPayServer/Controllers/StoresController.BTCLike.cs index 9d49bca49..7fd83cf65 100644 --- a/BTCPayServer/Controllers/StoresController.BTCLike.cs +++ b/BTCPayServer/Controllers/StoresController.BTCLike.cs @@ -15,7 +15,6 @@ using BTCPayServer.Models; using BTCPayServer.Models.StoreViewModels; using BTCPayServer.Payments; using BTCPayServer.Services; -using LedgerWallet; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using NBitcoin; @@ -61,82 +60,6 @@ namespace BTCPayServer.Controllers return View(vm); } - class GetXPubs - { - public BitcoinExtPubKey ExtPubKey { get; set; } - public DerivationStrategyBase DerivationScheme { get; set; } - public HDFingerprint RootFingerprint { get; set; } - public string Source { get; set; } - } - - [HttpGet] - [Route("{storeId}/derivations/{cryptoCode}/ledger/ws")] - public async Task AddDerivationSchemeLedger( - string storeId, - string cryptoCode, - string command, - string keyPath = "") - { - if (!HttpContext.WebSockets.IsWebSocketRequest) - return NotFound(); - - var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - var hw = new LedgerHardwareWalletService(webSocket); - object result = null; - var network = _NetworkProvider.GetNetwork(cryptoCode); - - using (var normalOperationTimeout = new CancellationTokenSource()) - { - normalOperationTimeout.CancelAfter(TimeSpan.FromMinutes(30)); - try - { - if (command == "test") - { - result = await hw.Test(normalOperationTimeout.Token); - } - if (command == "getxpub") - { - var k = KeyPath.Parse(keyPath); - if (k.Indexes.Length == 0) - throw new FormatException("Invalid key path"); - - var getxpubResult = new GetXPubs(); - getxpubResult.ExtPubKey = await hw.GetExtPubKey(network, k, normalOperationTimeout.Token); - var segwit = network.NBitcoinNetwork.Consensus.SupportSegwit; - var derivation = network.NBXplorerNetwork.DerivationStrategyFactory.CreateDirectDerivationStrategy(getxpubResult.ExtPubKey, new DerivationStrategyOptions() - { - ScriptPubKeyType = segwit ? ScriptPubKeyType.SegwitP2SH : ScriptPubKeyType.Legacy - }); - getxpubResult.DerivationScheme = derivation; - getxpubResult.RootFingerprint = (await hw.GetExtPubKey(network, new KeyPath(), normalOperationTimeout.Token)).ExtPubKey.PubKey.GetHDFingerPrint(); - getxpubResult.Source = hw.Device; - result = getxpubResult; - } - } - catch (OperationCanceledException) - { result = new LedgerTestResult() { Success = false, Error = "Timeout" }; } - catch (Exception ex) - { result = new LedgerTestResult() { Success = false, Error = ex.Message }; } - finally { hw.Dispose(); } - try - { - if (result != null) - { - UTF8Encoding UTF8NOBOM = new UTF8Encoding(false); - var bytes = UTF8NOBOM.GetBytes(JsonConvert.SerializeObject(result, network.NBXplorerNetwork.JsonSerializerSettings)); - using var cts = new CancellationTokenSource(2000); - await webSocket.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, cts.Token); - } - } - catch { } - finally - { - await webSocket.CloseSocket(); - } - } - return new EmptyResult(); - } - private DerivationSchemeSettings GetExistingDerivationStrategy(string cryptoCode, StoreData store) { var id = new PaymentMethodId(cryptoCode, PaymentTypes.BTCLike); diff --git a/BTCPayServer/Controllers/VaultController.cs b/BTCPayServer/Controllers/VaultController.cs index c07c59794..2054fb50f 100644 --- a/BTCPayServer/Controllers/VaultController.cs +++ b/BTCPayServer/Controllers/VaultController.cs @@ -16,7 +16,6 @@ using BTCPayServer.Models.StoreViewModels; using BTCPayServer.Payments; using BTCPayServer.Security; using BTCPayServer.Services; -using LedgerWallet; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/BTCPayServer/Controllers/WalletsController.PSBT.cs b/BTCPayServer/Controllers/WalletsController.PSBT.cs index 1c04977f3..7009697a4 100644 --- a/BTCPayServer/Controllers/WalletsController.PSBT.cs +++ b/BTCPayServer/Controllers/WalletsController.PSBT.cs @@ -479,8 +479,6 @@ namespace BTCPayServer.Controllers { case "vault": return ViewVault(walletId, signingContext); - case "ledger": - return ViewWalletSendLedger(walletId, signingContext); case "seed": return SignWithSeed(walletId, signingContext); case "nbx-seed": diff --git a/BTCPayServer/Controllers/WalletsController.cs b/BTCPayServer/Controllers/WalletsController.cs index 34f1b5cae..53a6c0f8f 100644 --- a/BTCPayServer/Controllers/WalletsController.cs +++ b/BTCPayServer/Controllers/WalletsController.cs @@ -803,49 +803,6 @@ namespace BTCPayServer.Controllers return View("PostRedirect", redirectVm); } - void SetAmbientPSBT(string psbt) - { - if (psbt != null) - TempData["AmbientPSBT"] = psbt; - else - TempData.Remove("AmbientPSBT"); - } - PSBT GetAmbientPSBT(Network network, bool peek) - { - if (network == null) - throw new ArgumentNullException(nameof(network)); - if ((peek ? TempData.Peek("AmbientPSBT") : TempData["AmbientPSBT"]) is string str) - { - try - { - return PSBT.Parse(str, network); - } - catch { } - } - return null; - } - - private ViewResult ViewWalletSendLedger(WalletId walletId, SigningContextModel signingContext) - { - SetAmbientPSBT(signingContext.PSBT); - return View("WalletSendLedger", new WalletSendLedgerModel() - { - SigningContext = signingContext, - WebsocketPath = this.Url.Action(nameof(LedgerConnection), new { walletId = walletId.ToString() }) - }); - } - - [HttpPost] - [Route("{walletId}/ledger")] - public IActionResult SubmitLedger([ModelBinder(typeof(WalletIdModelBinder))] - WalletId walletId, WalletSendLedgerModel model) - { - return RedirectToWalletPSBTReady(new WalletPSBTReadyViewModel() - { - SigningContext = model.SigningContext - }); - } - [HttpGet("{walletId}/psbt/seed")] public IActionResult SignWithSeed([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, SigningContextModel signingContext) @@ -1074,119 +1031,6 @@ namespace BTCPayServer.Controllers return _userManager.GetUserId(User); } - [HttpGet] - [Route("{walletId}/send/ledger/ws")] - public async Task LedgerConnection( - [ModelBinder(typeof(WalletIdModelBinder))] - WalletId walletId, - string command, - // getinfo - // getxpub - int account = 0, - // sendtoaddress - string hintChange = null - ) - { - if (!HttpContext.WebSockets.IsWebSocketRequest) - return NotFound(); - var storeData = CurrentStore; - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); - if (network == null) - throw new FormatException("Invalid value for crypto code"); - PSBT psbt = GetAmbientPSBT(network.NBitcoinNetwork, true); - var derivationSettings = GetDerivationSchemeSettings(walletId); - - var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - - using (var normalOperationTimeout = new CancellationTokenSource()) - using (var signTimeout = new CancellationTokenSource()) - { - normalOperationTimeout.CancelAfter(TimeSpan.FromMinutes(30)); - var hw = new LedgerHardwareWalletService(webSocket); - object result = null; - try - { - if (command == "test") - { - result = await hw.Test(normalOperationTimeout.Token); - } - if (command == "sendtoaddress") - { - if (!_dashboard.IsFullySynched(network.CryptoCode, out var summary)) - throw new Exception($"{network.CryptoCode}: not started or fully synched"); - - var accountKey = derivationSettings.GetSigningAccountKeySettings(); - // Some deployment does not have the AccountKeyPath set, let's fix this... - if (accountKey.AccountKeyPath == null) - { - // If the saved wallet key path is not present or incorrect, let's scan the wallet to see if it can sign strategy - var foundKeyPath = await hw.FindKeyPathFromDerivation(network, - derivationSettings.AccountDerivation, - normalOperationTimeout.Token); - accountKey.AccountKeyPath = foundKeyPath ?? throw new HardwareWalletException($"This store is not configured to use this ledger"); - storeData.SetSupportedPaymentMethod(derivationSettings); - await Repository.UpdateStore(storeData); - } - // If it has already the AccountKeyPath, we did not looked up for it, so we need to check if we are on the right ledger - else - { - // Checking if ledger is right with the RootFingerprint is faster as it does not need to make a query to the parent xpub, - // but some deployment does not have it, so let's use AccountKeyPath instead - if (accountKey.RootFingerprint == null) - { - - var actualPubKey = await hw.GetExtPubKey(network, accountKey.AccountKeyPath, normalOperationTimeout.Token); - if (!derivationSettings.AccountDerivation.GetExtPubKeys().Any(p => p.GetPublicKey() == actualPubKey.GetPublicKey())) - throw new HardwareWalletException($"This store is not configured to use this ledger"); - } - // We have the root fingerprint, we can check the root from it - else - { - var actualPubKey = await hw.GetPubKey(network, new KeyPath(), normalOperationTimeout.Token); - if (actualPubKey.GetHDFingerPrint() != accountKey.RootFingerprint.Value) - throw new HardwareWalletException($"This store is not configured to use this ledger"); - } - } - - // Some deployment does not have the RootFingerprint set, let's fix this... - if (accountKey.RootFingerprint == null) - { - accountKey.RootFingerprint = (await hw.GetPubKey(network, new KeyPath(), normalOperationTimeout.Token)).GetHDFingerPrint(); - storeData.SetSupportedPaymentMethod(derivationSettings); - await Repository.UpdateStore(storeData); - } - - derivationSettings.RebaseKeyPaths(psbt); - var changeAddress = string.IsNullOrEmpty(hintChange) ? null : BitcoinAddress.Create(hintChange, network.NBitcoinNetwork); - signTimeout.CancelAfter(TimeSpan.FromMinutes(5)); - psbt = await hw.SignTransactionAsync(psbt, accountKey.GetRootedKeyPath(), accountKey.AccountKey, changeAddress?.ScriptPubKey, signTimeout.Token); - SetAmbientPSBT(null); - result = new SendToAddressResult() { PSBT = psbt.ToBase64() }; - } - } - catch (OperationCanceledException) - { result = new LedgerTestResult() { Success = false, Error = "Timeout" }; } - catch (Exception ex) - { result = new LedgerTestResult() { Success = false, Error = ex.Message }; } - finally { hw.Dispose(); } - try - { - if (result != null) - { - UTF8Encoding UTF8NOBOM = new UTF8Encoding(false); - var bytes = UTF8NOBOM.GetBytes(JsonConvert.SerializeObject(result, _serializerSettings)); - await webSocket.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, new CancellationTokenSource(2000).Token); - } - } - catch { } - finally - { - await webSocket.CloseSocket(); - } - } - return new EmptyResult(); - } - [Route("{walletId}/settings")] public async Task WalletSettings( [ModelBinder(typeof(WalletIdModelBinder))] diff --git a/BTCPayServer/Models/WalletViewModels/WalletSendLedgerModel.cs b/BTCPayServer/Models/WalletViewModels/WalletSendLedgerModel.cs deleted file mode 100644 index 2e4576119..000000000 --- a/BTCPayServer/Models/WalletViewModels/WalletSendLedgerModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace BTCPayServer.Models.WalletViewModels -{ - public class WalletSendLedgerModel - { - public string WebsocketPath { get; set; } - public SigningContextModel SigningContext { get; set; } - } -} diff --git a/BTCPayServer/Services/HardwareWalletService.cs b/BTCPayServer/Services/HardwareWalletService.cs deleted file mode 100644 index 58c8608f4..000000000 --- a/BTCPayServer/Services/HardwareWalletService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Linq; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; -using BTCPayServer.Services.Wallets; -using LedgerWallet; -using NBitcoin; -using NBXplorer.DerivationStrategy; -using Newtonsoft.Json; - -namespace BTCPayServer.Services -{ - - public class HardwareWalletException : Exception - { - public HardwareWalletException() { } - public HardwareWalletException(string message) : base(message) { } - public HardwareWalletException(string message, Exception inner) : base(message, inner) { } - } - public abstract class HardwareWalletService : IDisposable - { - public abstract string Device { get; } - public abstract Task Test(CancellationToken cancellation); - - public abstract Task GetExtPubKey(BTCPayNetwork network, KeyPath keyPath, CancellationToken cancellation); - public virtual async Task GetPubKey(BTCPayNetwork network, KeyPath keyPath, CancellationToken cancellation) - { - return (await GetExtPubKey(network, keyPath, cancellation)).GetPublicKey(); - } - - public async Task FindKeyPathFromDerivation(BTCPayNetwork network, DerivationStrategyBase derivationScheme, CancellationToken cancellation) - { - var pubKeys = derivationScheme.GetExtPubKeys().Select(k => k.GetPublicKey()).ToArray(); - var derivation = derivationScheme.GetDerivation(new KeyPath(0)); - List derivations = new List(); - if (network.NBitcoinNetwork.Consensus.SupportSegwit) - { - if (derivation.Redeem?.IsScriptType(ScriptType.Witness) is true || - derivation.ScriptPubKey.IsScriptType(ScriptType.Witness)) // Native or p2sh segwit - derivations.Add(new KeyPath("49'")); - if (derivation.Redeem == null && derivation.ScriptPubKey.IsScriptType(ScriptType.Witness)) // Native segwit - derivations.Add(new KeyPath("84'")); - } - derivations.Add(new KeyPath("44'")); - KeyPath foundKeyPath = null; - foreach (var account in - derivations - .Select(purpose => purpose.Derive(network.CoinType)) - .SelectMany(coinType => Enumerable.Range(0, 5).Select(i => coinType.Derive(i, true)))) - { - var pubkey = await GetPubKey(network, account, cancellation); - if (pubKeys.Contains(pubkey)) - { - foundKeyPath = account; - break; - } - } - - return foundKeyPath; - } - - public abstract Task SignTransactionAsync(PSBT psbt, RootedKeyPath accountKeyPath, BitcoinExtPubKey accountKey, Script changeHint, CancellationToken cancellationToken); - - public virtual void Dispose() - { - } - } - - public class LedgerTestResult - { - public bool Success { get; set; } - public string Error { get; set; } - } -} diff --git a/BTCPayServer/Services/LedgerHardwareWalletService.cs b/BTCPayServer/Services/LedgerHardwareWalletService.cs deleted file mode 100644 index dea683799..000000000 --- a/BTCPayServer/Services/LedgerHardwareWalletService.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; -using LedgerWallet; -using NBitcoin; - -namespace BTCPayServer.Services -{ - public class LedgerHardwareWalletService : HardwareWalletService - { - class WebSocketTransport : LedgerWallet.Transports.ILedgerTransport, IDisposable - { - private readonly WebSocket webSocket; - - public WebSocketTransport(System.Net.WebSockets.WebSocket webSocket) - { - if (webSocket == null) - throw new ArgumentNullException(nameof(webSocket)); - this.webSocket = webSocket; - } - - SemaphoreSlim _Semaphore = new SemaphoreSlim(1, 1); - public async Task Exchange(byte[][] apdus, CancellationToken cancellationToken) - { - await _Semaphore.WaitAsync(); - List responses = new List(); - try - { - foreach (var apdu in apdus) - { - await this.webSocket.SendAsync(new ArraySegment(apdu), WebSocketMessageType.Binary, true, cancellationToken); - } - foreach (var apdu in apdus) - { - byte[] response = new byte[300]; - var result = await this.webSocket.ReceiveAsync(new ArraySegment(response), cancellationToken); - Array.Resize(ref response, result.Count); - responses.Add(response); - } - } - finally - { - _Semaphore.Release(); - } - return responses.ToArray(); - } - - public void Dispose() - { - _Semaphore.Dispose(); - } - } - - private readonly LedgerClient _Ledger; - public LedgerClient Ledger - { - get - { - return _Ledger; - } - } - - public override string Device => "Ledger wallet"; - - WebSocketTransport _Transport = null; - public LedgerHardwareWalletService(System.Net.WebSockets.WebSocket ledgerWallet) - { - if (ledgerWallet == null) - throw new ArgumentNullException(nameof(ledgerWallet)); - _Transport = new WebSocketTransport(ledgerWallet); - _Ledger = new LedgerClient(_Transport); - _Ledger.MaxAPDUSize = 90; - } - - public override async Task Test(CancellationToken cancellation) - { - var version = await Ledger.GetFirmwareVersionAsync(cancellation); - return new LedgerTestResult() { Success = true }; - } - - public override async Task GetExtPubKey(BTCPayNetwork network, KeyPath keyPath, CancellationToken cancellation) - { - if (network == null) - throw new ArgumentNullException(nameof(network)); - return await GetExtPubKey(network, keyPath, false, cancellation); - } - public override async Task GetPubKey(BTCPayNetwork network, KeyPath keyPath, CancellationToken cancellation) - { - if (network == null) - throw new ArgumentNullException(nameof(network)); - return (await GetExtPubKey(network, keyPath, false, cancellation)).GetPublicKey(); - } - - private async Task GetExtPubKey(BTCPayNetwork network, KeyPath account, bool onlyChaincode, CancellationToken cancellation) - { - var pubKey = await Ledger.GetWalletPubKeyAsync(account, cancellation: cancellation); - try - { - pubKey.GetAddress(network.NBitcoinNetwork); - } - catch - { - if (network.NBitcoinNetwork.NetworkType == NetworkType.Mainnet) - throw new HardwareWalletException($"The opened ledger app does not seems to support {network.NBitcoinNetwork.Name}."); - } - var parentFP = onlyChaincode || account.Indexes.Length == 0 ? default : (await Ledger.GetWalletPubKeyAsync(account.Parent, cancellation: cancellation)).UncompressedPublicKey.Compress().GetHDFingerPrint(); - var extpubkey = new ExtPubKey(pubKey.UncompressedPublicKey.Compress(), - pubKey.ChainCode, - (byte)account.Indexes.Length, - parentFP, - account.Indexes.Length == 0 ? 0 : account.Indexes.Last()).GetWif(network.NBitcoinNetwork); - return extpubkey; - } - - public override async Task SignTransactionAsync(PSBT psbt, RootedKeyPath accountKeyPath, BitcoinExtPubKey accountKey, Script changeHint, CancellationToken cancellationToken) - { - var unsigned = psbt.GetGlobalTransaction(); - var changeKeyPath = psbt.Outputs.HDKeysFor(accountKey, accountKeyPath) - .Where(o => changeHint == null ? true : changeHint == o.Coin.ScriptPubKey) - .Select(o => o.RootedKeyPath.KeyPath) - .FirstOrDefault(); - var signatureRequests = psbt - .Inputs - .HDKeysFor(accountKey, accountKeyPath) - .Where(hd => !hd.Coin.PartialSigs.ContainsKey(hd.PubKey)) // Don't want to sign something twice - .GroupBy(hd => hd.Coin.PrevOut, hd => hd) - .Select(i => new SignatureRequest() - { - InputCoin = i.First().Coin.GetSignableCoin(), - InputTransaction = i.First().Coin.NonWitnessUtxo, - KeyPath = i.First().RootedKeyPath.KeyPath, - PubKey = i.First().PubKey - }).ToArray(); - await Ledger.SignTransactionAsync(signatureRequests, unsigned, changeKeyPath, cancellationToken); - psbt = psbt.Clone(); - foreach (var signature in signatureRequests) - { - if (signature.Signature == null) - continue; - var input = psbt.Inputs.FindIndexedInput(signature.InputCoin.Outpoint); - if (input == null) - continue; - input.PartialSigs.Add(signature.PubKey, signature.Signature); - } - return psbt; - } - - public override void Dispose() - { - if (_Transport != null) - _Transport.Dispose(); - } - } -} diff --git a/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml b/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml index c91ad5f20..66315de6d 100644 --- a/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml +++ b/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml @@ -81,16 +81,15 @@ Import from... @@ -209,7 +208,6 @@ @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") - diff --git a/BTCPayServer/Views/Stores/AddDerivationSchemes_HardwareWalletDialogs.cshtml b/BTCPayServer/Views/Stores/AddDerivationSchemes_HardwareWalletDialogs.cshtml index 8d47923ee..603a92d64 100644 --- a/BTCPayServer/Views/Stores/AddDerivationSchemes_HardwareWalletDialogs.cshtml +++ b/BTCPayServer/Views/Stores/AddDerivationSchemes_HardwareWalletDialogs.cshtml @@ -6,61 +6,7 @@ } -