Beispiel #1
0
        public async Task <IActionResult> WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId, WalletPSBTViewModel vm)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            vm.CryptoCode = network.CryptoCode;

            var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }

            vm.NBXSeedAvailable = await CanUseHotWallet() && !string.IsNullOrEmpty(await ExplorerClientProvider.GetExplorerClient(network)
                                                                                   .GetMetadataAsync <string>(derivationSchemeSettings.AccountDerivation, WellknownMetadataKeys.Mnemonic));

            if (await vm.GetPSBT(network.NBitcoinNetwork) is PSBT psbt)
            {
                vm.Decoded = psbt.ToString();
                vm.PSBT    = psbt.ToBase64();
                vm.PSBTHex = psbt.ToHex();
            }

            return(View(nameof(WalletPSBT), vm ?? new WalletPSBTViewModel()
            {
                CryptoCode = walletId.CryptoCode
            }));
        }
Beispiel #2
0
        public async Task <IActionResult> WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId, WalletPSBTViewModel vm)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            vm.CryptoCode = network.CryptoCode;

            var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }

            vm.NBXSeedAvailable = await CanUseHotWallet() && derivationSchemeSettings.IsHotWallet;

            if (await vm.GetPSBT(network.NBitcoinNetwork) is PSBT psbt)
            {
                vm.PSBT    = vm.SigningContext.PSBT = psbt.ToBase64();
                vm.PSBTHex = psbt.ToHex();
                vm.Decoded = psbt.ToString();
                await FetchTransactionDetails(derivationSchemeSettings, vm, network);

                return(View("WalletPSBTDecoded", vm));
            }

            return(View(vm));
        }
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command = null)
        {
            var network = NetworkProvider.GetNetwork(walletId.CryptoCode);
            var psbt    = vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt == null)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }

            if (command == null)
            {
                vm.Decoded  = psbt.ToString();
                vm.FileName = string.Empty;
                return(View(vm));
            }
            else if (command == "ledger")
            {
                return(ViewWalletSendLedger(psbt));
            }
            else if (command == "broadcast")
            {
                if (!psbt.IsAllFinalized() && !psbt.TryFinalize(out var errors))
                {
                    return(ViewPSBT(psbt, errors));
                }
                var transaction = psbt.ExtractTransaction();
                try
                {
                    var broadcastResult = await ExplorerClientProvider.GetExplorerClient(network).BroadcastAsync(transaction);

                    if (!broadcastResult.Success)
                    {
                        return(ViewPSBT(psbt, new[] { $"RPC Error while broadcasting: {broadcastResult.RPCCode} {broadcastResult.RPCCodeMessage} {broadcastResult.RPCMessage}" }));
                    }
                }
                catch (Exception ex)
                {
                    return(ViewPSBT(psbt, "Error while broadcasting: " + ex.Message));
                }
                return(await RedirectToWalletTransaction(walletId, transaction));
            }
            else if (command == "combine")
            {
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel()
                {
                    OtherPSBT = psbt.ToBase64()
                }));
            }
            else if (command == "save-psbt")
            {
                return(FilePSBT(psbt, vm.FileName));
            }
            return(View(vm));
        }
Beispiel #4
0
        public IActionResult WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                        WalletId walletId, WalletPSBTViewModel vm)
        {
            var network = NetworkProvider.GetNetwork(walletId.CryptoCode);

            if (vm?.PSBT != null)
            {
                vm.Decoded = vm.GetPSBT(network.NBitcoinNetwork)?.ToString();
            }
            return(View(vm ?? new WalletPSBTViewModel()));
        }
Beispiel #5
0
        public async Task <IActionResult> WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId, WalletPSBTViewModel vm)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            if (await vm.GetPSBT(network.NBitcoinNetwork) is PSBT psbt)
            {
                vm.Decoded = psbt.ToString();
                vm.PSBT    = psbt.ToBase64();
            }
            return(View(vm ?? new WalletPSBTViewModel()));
        }
Beispiel #6
0
        public async Task <IActionResult> WalletSign([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId, WalletPSBTViewModel vm, string returnUrl = null, string command = null)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            if (returnUrl is null)
            {
                returnUrl = Url.Action(nameof(WalletTransactions), new { walletId });
            }
            var psbt = await vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt is null || vm.InvalidPSBT)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View("WalletSigningOptions", new WalletSigningOptionsModel(vm.SigningContext, returnUrl)));
            }
            switch (command)
            {
            case "vault":
                return(ViewVault(walletId, vm.SigningContext));

            case "seed":
                return(SignWithSeed(walletId, vm.SigningContext));

            case "decode":
                return(await WalletPSBT(walletId, vm, "decode"));

            default:
                break;
            }

            if (await CanUseHotWallet())
            {
                var derivationScheme = GetDerivationSchemeSettings(walletId);
                if (derivationScheme.IsHotWallet)
                {
                    var extKey = await ExplorerClientProvider.GetExplorerClient(walletId.CryptoCode)
                                 .GetMetadataAsync <string>(derivationScheme.AccountDerivation,
                                                            WellknownMetadataKeys.MasterHDKey);

                    if (extKey != null)
                    {
                        return(await SignWithSeed(walletId,
                                                  new SignWithSeedViewModel { SeedOrKey = extKey, SigningContext = vm.SigningContext }));
                    }
                }
            }
            return(View("WalletSigningOptions", new WalletSigningOptionsModel(vm.SigningContext, returnUrl)));
        }
Beispiel #7
0
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command = null)
        {
            var network = NetworkProvider.GetNetwork(walletId.CryptoCode);
            var psbt    = await vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt == null)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }
            switch (command)
            {
            case null:
                vm.Decoded = psbt.ToString();
                ModelState.Remove(nameof(vm.PSBT));
                ModelState.Remove(nameof(vm.FileName));
                ModelState.Remove(nameof(vm.UploadedPSBTFile));
                vm.PSBT     = psbt.ToBase64();
                vm.FileName = vm.UploadedPSBTFile?.FileName;
                return(View(vm));

            case "ledger":
                return(ViewWalletSendLedger(psbt));

            case "seed":
                return(SignWithSeed(walletId, psbt.ToBase64()));

            case "broadcast":
            {
                return(await WalletPSBTReady(walletId, psbt.ToBase64()));
            }

            case "combine":
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel()
                {
                    OtherPSBT = psbt.ToBase64()
                }));

            case "save-psbt":
                return(FilePSBT(psbt, vm.FileName));

            default:
                return(View(vm));
            }
        }
Beispiel #8
0
        public async Task <IActionResult> WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);
            var vm      = new WalletPSBTViewModel();

            vm.CryptoCode = network.CryptoCode;

            var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }
            vm.NBXSeedAvailable = await CanUseHotWallet() && derivationSchemeSettings.IsHotWallet;

            return(View(vm));
        }
        public async Task <IActionResult> WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))]
                                                     WalletId walletId, string returnUrl)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);
            var referer = HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath;
            var vm      = new WalletPSBTViewModel
            {
                BackUrl    = string.IsNullOrEmpty(returnUrl) ? null : referer,
                ReturnUrl  = returnUrl ?? referer,
                CryptoCode = network.CryptoCode
            };

            var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }
            vm.NBXSeedAvailable = await CanUseHotWallet() && derivationSchemeSettings.IsHotWallet;

            return(View(vm));
        }
Beispiel #10
0
        public async Task <IActionResult> WalletPSBTReady(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId, WalletPSBTViewModel vm, string command, CancellationToken cancellationToken = default)
        {
            var  network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);
            PSBT psbt    = await vm.GetPSBT(network.NBitcoinNetwork);

            if (vm.InvalidPSBT || psbt is null)
            {
                if (vm.InvalidPSBT)
                {
                    vm.GlobalError = "Invalid PSBT";
                }
                return(View(nameof(WalletPSBT), vm));
            }
            DerivationSchemeSettings derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }

            await FetchTransactionDetails(derivationSchemeSettings, vm, network);

            switch (command)
            {
            case "payjoin":
                string error;
                try
                {
                    var proposedPayjoin = await GetPayjoinProposedTX(new BitcoinUrlBuilder(vm.SigningContext.PayJoinBIP21, network.NBitcoinNetwork), psbt,
                                                                     derivationSchemeSettings, network, cancellationToken);

                    try
                    {
                        proposedPayjoin.Settings.SigningOptions = new SigningOptions
                        {
                            EnforceLowR = !(vm.SigningContext?.EnforceLowR is false)
                        };
                        var extKey = ExtKey.Parse(vm.SigningKey, network.NBitcoinNetwork);
                        proposedPayjoin = proposedPayjoin.SignAll(derivationSchemeSettings.AccountDerivation,
                                                                  extKey,
                                                                  RootedKeyPath.Parse(vm.SigningKeyPath));
                        vm.SigningContext.PSBT         = proposedPayjoin.ToBase64();
                        vm.SigningContext.OriginalPSBT = psbt.ToBase64();
                        proposedPayjoin.Finalize();
                        var hash = proposedPayjoin.ExtractTransaction().GetHash();
                        _EventAggregator.Publish(new UpdateTransactionLabel(walletId, hash, UpdateTransactionLabel.PayjoinLabelTemplate()));
                        TempData.SetStatusMessageModel(new StatusMessageModel
                        {
                            Severity     = StatusMessageModel.StatusSeverity.Success,
                            AllowDismiss = false,
                            Html         = $"The payjoin transaction has been successfully broadcasted ({proposedPayjoin.ExtractTransaction().GetHash()})"
                        });
                        return(await WalletPSBTReady(walletId, vm, "broadcast"));
                    }
                    catch (Exception)
                    {
                        TempData.SetStatusMessageModel(new StatusMessageModel()
                        {
                            Severity     = StatusMessageModel.StatusSeverity.Warning,
                            AllowDismiss = false,
                            Html         =
                                "This transaction has been coordinated between the receiver and you to create a <a href='https://en.bitcoin.it/wiki/PayJoin' target='_blank'>payjoin transaction</a> by adding inputs from the receiver.<br/>" +
                                "The amount being sent may appear higher but is in fact almost same.<br/><br/>" +
                                "If you cancel or refuse to sign this transaction, the payment will proceed without payjoin"
                        });
                        vm.SigningContext.PSBT         = proposedPayjoin.ToBase64();
                        vm.SigningContext.OriginalPSBT = psbt.ToBase64();
                        return(ViewVault(walletId, vm.SigningContext));
                    }
                }
                catch (PayjoinReceiverException ex)
                {
                    error = $"The payjoin receiver could not complete the payjoin: {ex.Message}";
                }
                catch (PayjoinSenderException ex)
                {
                    error = $"We rejected the receiver's payjoin proposal: {ex.Message}";
                }
                catch (Exception ex)
                {
                    error = $"Unexpected payjoin error: {ex.Message}";
                }

                //we possibly exposed the tx to the receiver, so we need to broadcast straight away
                psbt.Finalize();
                TempData.SetStatusMessageModel(new StatusMessageModel
                {
                    Severity     = StatusMessageModel.StatusSeverity.Warning,
                    AllowDismiss = false,
                    Html         = $"The payjoin transaction could not be created.<br/>" +
                                   $"The original transaction was broadcasted instead. ({psbt.ExtractTransaction().GetHash()})<br/><br/>" +
                                   $"{error}"
                });
                return(await WalletPSBTReady(walletId, vm, "broadcast"));

            case "broadcast" when !psbt.IsAllFinalized() && !psbt.TryFinalize(out var errors):
                vm.SetErrors(errors);
                return(View(nameof(WalletPSBT), vm));

            case "broadcast":
            {
                var transaction = psbt.ExtractTransaction();
                try
                {
                    var broadcastResult = await ExplorerClientProvider.GetExplorerClient(network).BroadcastAsync(transaction);

                    if (!broadcastResult.Success)
                    {
                        if (!string.IsNullOrEmpty(vm.SigningContext.OriginalPSBT))
                        {
                            TempData.SetStatusMessageModel(new StatusMessageModel
                                {
                                    Severity     = StatusMessageModel.StatusSeverity.Warning,
                                    AllowDismiss = false,
                                    Html         = $"The payjoin transaction could not be broadcasted.<br/>({broadcastResult.RPCCode} {broadcastResult.RPCCodeMessage} {broadcastResult.RPCMessage}).<br/>The transaction has been reverted back to its original format and has been broadcast."
                                });
                            vm.SigningContext.PSBT         = vm.SigningContext.OriginalPSBT;
                            vm.SigningContext.OriginalPSBT = null;
                            return(await WalletPSBTReady(walletId, vm, "broadcast"));
                        }

                        vm.GlobalError = $"RPC Error while broadcasting: {broadcastResult.RPCCode} {broadcastResult.RPCCodeMessage} {broadcastResult.RPCMessage}";
                        return(View(nameof(WalletPSBT), vm));
                    }
                    else
                    {
                        var wallet             = _walletProvider.GetWallet(network);
                        var derivationSettings = GetDerivationSchemeSettings(walletId);
                        wallet.InvalidateCache(derivationSettings.AccountDerivation);
                    }
                }
                catch (Exception ex)
                {
                    vm.GlobalError = "Error while broadcasting: " + ex.Message;
                    return(View(nameof(WalletPSBT), vm));
                }

                if (!TempData.HasStatusMessage())
                {
                    TempData[WellKnownTempData.SuccessMessage] = $"Transaction broadcasted successfully ({transaction.GetHash()})";
                }
                var returnUrl = this.HttpContext.Request.Query["returnUrl"].FirstOrDefault();
                if (returnUrl is not null)
                {
                    return(Redirect(returnUrl));
                }
                return(RedirectToAction(nameof(WalletTransactions), new { walletId = walletId.ToString() }));
            }

            case "analyze-psbt":
                return(RedirectToWalletPSBT(new WalletPSBTViewModel()
                {
                    PSBT = psbt.ToBase64()
                }));

            case "decode":
                await FetchTransactionDetails(derivationSchemeSettings, vm, network);

                return(View("WalletPSBTDecoded", vm));

            default:
                vm.GlobalError = "Unknown command";
                return(View(nameof(WalletPSBT), vm));
            }
        }
Beispiel #11
0
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            vm.CryptoCode = network.CryptoCode;

            var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);

            if (derivationSchemeSettings == null)
            {
                return(NotFound());
            }

            vm.NBXSeedAvailable = await CanUseHotWallet() && derivationSchemeSettings.IsHotWallet;

            var psbt = await vm.GetPSBT(network.NBitcoinNetwork);

            if (vm.InvalidPSBT)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }
            if (psbt is null)
            {
                return(View("WalletPSBT", vm));
            }
            switch (command)
            {
            case "sign":
                return(await WalletSign(walletId, vm));

            case "decode":
                ModelState.Remove(nameof(vm.PSBT));
                ModelState.Remove(nameof(vm.FileName));
                ModelState.Remove(nameof(vm.UploadedPSBTFile));
                await FetchTransactionDetails(derivationSchemeSettings, vm, network);

                return(View("WalletPSBTDecoded", vm));

            case "save-psbt":
                return(FilePSBT(psbt, vm.FileName));

            case "update":
                psbt = await ExplorerClientProvider.UpdatePSBT(derivationSchemeSettings, psbt);

                if (psbt == null)
                {
                    TempData[WellKnownTempData.ErrorMessage] = "You need to update your version of NBXplorer";
                    return(View(vm));
                }
                TempData[WellKnownTempData.SuccessMessage] = "PSBT updated!";
                return(RedirectToWalletPSBT(new WalletPSBTViewModel
                {
                    PSBT = psbt.ToBase64(),
                    FileName = vm.FileName
                }));

            case "combine":
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel {
                    OtherPSBT = psbt.ToBase64()
                }));

            case "broadcast":
            {
                return(RedirectToWalletPSBTReady(new WalletPSBTReadyViewModel
                    {
                        SigningContext = new SigningContextModel(psbt)
                    }));
            }

            default:
                return(View("WalletPSBTDecoded", vm));
            }
        }
Beispiel #12
0
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command = null)
        {
            if (command == null)
            {
                return(await WalletPSBT(walletId, vm));
            }
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            vm.CryptoCode = network.CryptoCode;
            var psbt = await vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt == null)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }
            switch (command)
            {
            case "decode":
                vm.Decoded = psbt.ToString();
                ModelState.Remove(nameof(vm.PSBT));
                ModelState.Remove(nameof(vm.FileName));
                ModelState.Remove(nameof(vm.UploadedPSBTFile));
                vm.PSBT     = psbt.ToBase64();
                vm.FileName = vm.UploadedPSBTFile?.FileName;
                return(View(vm));

            case "vault":
                return(ViewVault(walletId, psbt));

            case "ledger":
                return(ViewWalletSendLedger(walletId, psbt));

            case "update":
                var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);
                psbt = await UpdatePSBT(derivationSchemeSettings, psbt, network);

                if (psbt == null)
                {
                    ModelState.AddModelError(nameof(vm.PSBT), "You need to update your version of NBXplorer");
                    return(View(vm));
                }
                TempData[WellKnownTempData.SuccessMessage] = "PSBT updated!";
                return(RedirectToWalletPSBT(walletId, psbt, vm.FileName));

            case "seed":
                return(SignWithSeed(walletId, psbt.ToBase64()));

            case "nbx-seed":
                var derivationScheme = GetDerivationSchemeSettings(walletId);
                var extKey           = await ExplorerClientProvider.GetExplorerClient(network)
                                       .GetMetadataAsync <string>(derivationScheme.AccountDerivation, WellknownMetadataKeys.MasterHDKey);

                return(await SignWithSeed(walletId, new SignWithSeedViewModel()
                {
                    SeedOrKey = extKey,
                    PSBT = psbt.ToBase64()
                }));

            case "broadcast":
            {
                return(await WalletPSBTReady(walletId, psbt.ToBase64()));
            }

            case "combine":
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel()
                {
                    OtherPSBT = psbt.ToBase64()
                }));

            case "save-psbt":
                return(FilePSBT(psbt, vm.FileName));

            default:
                return(View(vm));
            }
        }
Beispiel #13
0
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command = null)
        {
            if (command == null)
            {
                return(await WalletPSBT(walletId, vm));
            }
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);

            vm.CryptoCode       = network.CryptoCode;
            vm.NBXSeedAvailable = await CanUseHotWallet() && !string.IsNullOrEmpty(await ExplorerClientProvider.GetExplorerClient(network)
                                                                                   .GetMetadataAsync <string>(GetDerivationSchemeSettings(walletId).AccountDerivation,
                                                                                                              WellknownMetadataKeys.Mnemonic));

            var psbt = await vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt == null)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }
            var res = await TryHandleSigningCommands(walletId, psbt, command, new SigningContextModel(psbt));

            if (res != null)
            {
                return(res);
            }
            switch (command)
            {
            case "decode":
                vm.Decoded = psbt.ToString();
                ModelState.Remove(nameof(vm.PSBT));
                ModelState.Remove(nameof(vm.FileName));
                ModelState.Remove(nameof(vm.UploadedPSBTFile));
                vm.PSBT     = psbt.ToBase64();
                vm.FileName = vm.UploadedPSBTFile?.FileName;
                return(View(vm));

            case "update":
                var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);
                psbt = await ExplorerClientProvider.UpdatePSBT(derivationSchemeSettings, psbt);

                if (psbt == null)
                {
                    ModelState.AddModelError(nameof(vm.PSBT), "You need to update your version of NBXplorer");
                    return(View(vm));
                }
                TempData[WellKnownTempData.SuccessMessage] = "PSBT updated!";
                return(RedirectToWalletPSBT(new WalletPSBTViewModel()
                {
                    PSBT = psbt.ToBase64(),
                    FileName = vm.FileName
                }));

            case "broadcast":
            {
                return(RedirectToWalletPSBTReady(new WalletPSBTReadyViewModel()
                    {
                        SigningContext = new SigningContextModel(psbt)
                    }));
            }

            case "combine":
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel()
                {
                    OtherPSBT = psbt.ToBase64()
                }));

            case "save-psbt":
                return(FilePSBT(psbt, vm.FileName));

            default:
                return(View(vm));
            }
        }
Beispiel #14
0
        public async Task <IActionResult> WalletPSBT(
            [ModelBinder(typeof(WalletIdModelBinder))]
            WalletId walletId,
            WalletPSBTViewModel vm, string command = null)
        {
            var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode);
            var psbt    = await vm.GetPSBT(network.NBitcoinNetwork);

            if (psbt == null)
            {
                ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
                return(View(vm));
            }
            switch (command)
            {
            case null:
                vm.Decoded = psbt.ToString();
                ModelState.Remove(nameof(vm.PSBT));
                ModelState.Remove(nameof(vm.FileName));
                ModelState.Remove(nameof(vm.UploadedPSBTFile));
                vm.PSBT     = psbt.ToBase64();
                vm.FileName = vm.UploadedPSBTFile?.FileName;
                return(View(vm));

            case "ledger":
                return(ViewWalletSendLedger(psbt));

            case "update":
                var derivationSchemeSettings = await GetDerivationSchemeSettings(walletId);

                psbt = await UpdatePSBT(derivationSchemeSettings, psbt, network);

                if (psbt == null)
                {
                    ModelState.AddModelError(nameof(vm.PSBT), "You need to update your version of NBXplorer");
                    return(View(vm));
                }
                StatusMessage = "PSBT updated!";
                return(RedirectToAction(nameof(WalletPSBT), new { walletId = walletId, psbt = psbt.ToBase64(), FileName = vm.FileName }));

            case "seed":
                return(SignWithSeed(walletId, psbt.ToBase64()));

            case "broadcast":
            {
                return(await WalletPSBTReady(walletId, psbt.ToBase64()));
            }

            case "combine":
                ModelState.Remove(nameof(vm.PSBT));
                return(View(nameof(WalletPSBTCombine), new WalletPSBTCombineViewModel()
                {
                    OtherPSBT = psbt.ToBase64()
                }));

            case "save-psbt":
                return(FilePSBT(psbt, vm.FileName));

            default:
                return(View(vm));
            }
        }