예제 #1
0
        protected override async Task BuildTransaction(string password, PaymentIntent payments, FeeStrategy feeStrategy, bool allowUnconfirmed = false, IEnumerable <OutPoint> allowedInputs = null)
        {
            BuildTransactionResult result = await Task.Run(() => Wallet.BuildTransaction(Password, payments, feeStrategy, allowUnconfirmed: true, allowedInputs: allowedInputs, GetPayjoinClient()));

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SigningTransaction);
            SmartTransaction signedTransaction = result.Transaction;

            if (Wallet.KeyManager.IsHardwareWallet && !result.Signed)             // If hardware but still has a privkey then it's password, then meh.
            {
                try
                {
                    IsHardwareBusy = true;
                    MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    var client = new HwiClient(Global.Network);

                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                    PSBT signedPsbt = null;
                    try
                    {
                        try
                        {
                            signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                        }
                        catch (PSBTException ex) when(ex.Message.Contains("NullFail"))
                        {
                            NotificationHelpers.Warning("Fall back to Unverified Inputs Mode, trying to sign again.");

                            // Ledger Nano S hackfix https://github.com/MetacoSA/NBitcoin/pull/888

                            var noinputtx = result.Psbt.Clone();

                            foreach (var input in noinputtx.Inputs)
                            {
                                input.NonWitnessUtxo = null;
                            }

                            signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, noinputtx, cts.Token);
                        }
                    }
                    catch (HwiException)
                    {
                        await PinPadViewModel.UnlockAsync();

                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    signedTransaction = signedPsbt.ExtractSmartTransaction(result.Transaction);
                }
                finally
                {
                    MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    IsHardwareBusy = false;
                }
            }

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
            await Task.Run(async() => await Global.TransactionBroadcaster.SendTransactionAsync(signedTransaction));

            ResetUi();
        }
예제 #2
0
        protected override async Task DoAfterBuildTransaction(BuildTransactionResult result)
        {
            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SigningTransaction);
            SmartTransaction signedTransaction = result.Transaction;

            if (Wallet.KeyManager.IsHardwareWallet && !result.Signed)             // If hardware but still has a privkey then it's password, then meh.
            {
                try
                {
                    IsHardwareBusy = true;
                    MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    var client = new HwiClient(Global.Network);

                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                    PSBT signedPsbt = null;
                    try
                    {
                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    catch (HwiException)
                    {
                        await PinPadViewModel.UnlockAsync();

                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    signedTransaction = signedPsbt.ExtractSmartTransaction(result.Transaction);
                }
                catch (Exception ex)
                {
                    NotificationHelpers.Error(ex.ToUserFriendlyString());
                    return;
                }
                finally
                {
                    MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    IsHardwareBusy = false;
                }
            }

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
            await Task.Run(async() => await Global.TransactionBroadcaster.SendTransactionAsync(signedTransaction));

            ResetUi();
        }
예제 #3
0
        protected override async Task BuildTransaction(string password, PaymentIntent payments, FeeStrategy feeStrategy, bool allowUnconfirmed = false, IEnumerable <OutPoint> allowedInputs = null)
        {
            BuildTransactionResult result = await Task.Run(() => Wallet.BuildTransaction(Password, payments, feeStrategy, allowUnconfirmed: true, allowedInputs: allowedInputs, GetPayjoinClient()));

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SigningTransaction);
            SmartTransaction signedTransaction = result.Transaction;

            if (Wallet.KeyManager.IsHardwareWallet && !result.Signed)             // If hardware but still has a privkey then it's password, then meh.
            {
                try
                {
                    IsHardwareBusy = true;
                    MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    var client = new HwiClient(Global.Network);

                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                    PSBT signedPsbt = null;
                    try
                    {
                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    catch (HwiException)
                    {
                        await PinPadViewModel.UnlockAsync();

                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    signedTransaction = signedPsbt.ExtractSmartTransaction(result.Transaction);
                }
                finally
                {
                    MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    IsHardwareBusy = false;
                }
            }

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
            await Task.Run(async() => await Global.TransactionBroadcaster.SendTransactionAsync(signedTransaction));

            ResetUi();
        }
예제 #4
0
        public ReceiveTabViewModel(WalletViewModel walletViewModel)
            : base("Receive", walletViewModel)
        {
            _addresses = new ObservableCollection <AddressViewModel>();
            Label      = "";

            InitializeAddresses();

            GenerateCommand = ReactiveCommand.Create(() =>
            {
                var label = new SmartLabel(Label);
                Label     = label.ToString();
                if (label.IsEmpty)
                {
                    LabelRequiredNotificationVisible = true;
                    LabelRequiredNotificationOpacity = 1;

                    Dispatcher.UIThread.PostLogException(async() =>
                    {
                        await Task.Delay(TimeSpan.FromSeconds(4));
                        LabelRequiredNotificationOpacity = 0;
                    });

                    return;
                }

                Dispatcher.UIThread.PostLogException(() =>
                {
                    HdPubKey newKey = Global.WalletService.GetReceiveKey(new SmartLabel(Label), Addresses.Select(x => x.Model).Take(7));                                     // Never touch the first 7 keys.

                    AddressViewModel found = Addresses.FirstOrDefault(x => x.Model == newKey);
                    if (found != default)
                    {
                        Addresses.Remove(found);
                    }

                    var newAddress = new AddressViewModel(newKey, Global);

                    Addresses.Insert(0, newAddress);

                    SelectedAddress = newAddress;

                    Label = "";
                });
            });

            this.WhenAnyValue(x => x.Label).Subscribe(UpdateSuggestions);

            this.WhenAnyValue(x => x.SelectedAddress).Subscribe(async address =>
            {
                if (Global.UiConfig?.Autocopy is false || address is null)
                {
                    return;
                }

                await address.TryCopyToClipboardAsync();
            });

            var isCoinListItemSelected = this.WhenAnyValue(x => x.SelectedAddress).Select(coin => coin != null);

            CopyAddress = ReactiveCommand.CreateFromTask(async() =>
            {
                if (SelectedAddress is null)
                {
                    return;
                }

                await SelectedAddress.TryCopyToClipboardAsync();
            },
                                                         isCoinListItemSelected);

            CopyLabel = ReactiveCommand.CreateFromTask(async() =>
            {
                try
                {
                    await Application.Current.Clipboard.SetTextAsync(SelectedAddress.Label ?? string.Empty);
                }
                catch (Exception)
                { }
            },
                                                       isCoinListItemSelected);

            ToggleQrCode = ReactiveCommand.Create(() =>
            {
                try
                {
                    SelectedAddress.IsExpanded = !SelectedAddress.IsExpanded;
                }
                catch (Exception)
                { }
            },
                                                  isCoinListItemSelected);

#pragma warning disable IDE0053 // Use expression body for lambda expressions
            ChangeLabelCommand = ReactiveCommand.Create(() => { SelectedAddress.InEditMode = true; });
#pragma warning restore IDE0053 // Use expression body for lambda expressions

            DisplayAddressOnHwCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                var client    = new HwiClient(Global.Network);
                using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
                try
                {
                    await client.DisplayAddressAsync(KeyManager.MasterFingerprint.Value, SelectedAddress.Model.FullKeyPath, cts.Token);
                }
                catch (HwiException)
                {
                    await PinPadViewModel.UnlockAsync(Global);
                    await client.DisplayAddressAsync(KeyManager.MasterFingerprint.Value, SelectedAddress.Model.FullKeyPath, cts.Token);
                }
            });

            _suggestions = new ObservableCollection <SuggestionViewModel>();
        }