예제 #1
0
        private void SignTransaction(bool publish)
        {
            var outputs = PendingOutputs.Select(po =>
            {
                var script = po.BuildOutputScript().Script;
                return(new Transaction.Output(po.OutputAmount, Transaction.Output.LatestPkScriptVersion, script));
            }).ToArray();
            var shell = ViewModelLocator.ShellViewModel as ShellViewModel;

            if (shell != null)
            {
                Func <string, Task> action = (passphrase) => SignTransactionWithPassphrase(passphrase, outputs, publish);
                shell.VisibleDialogContent = new PassphraseDialogViewModel(shell, "Enter passphrase to sign transaction", "Sign", action);
            }
        }
예제 #2
0
 private void FinishCreateTransactionAction()
 {
     try
     {
         if (SignTransaction)
         {
             var outputs = PendingOutputs.Select(po => new Transaction.Output(po.OutputAmount, po.BuildOutputScript().Script)).ToArray();
             var shell   = (ShellViewModel)_parentViewModel;
             Func <string, Task> action = (passphrase) => SignTransactionWithPassphrase(passphrase, outputs, PublishTransaction);
             var dialog = new PassphraseDialogViewModel(shell, "Enter passphrase to sign transaction", "Sign", action);
             PostMessage(new OpenDialogMessage(dialog));
         }
         else
         {
             ShowUnsignedTransaction();
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }
예제 #3
0
        private async Task RecalculatePendingTransaction()
        {
            if (PendingOutputs.Count == 0 || PendingOutputs.Any(x => !x.IsValid))
            {
                UnsetPendingTransaction();
                return;
            }

            var walletClient = App.Current.Synchronizer?.WalletRpcClient;

            var outputs = PendingOutputs.Select(po =>
            {
                var amount = po.OutputAmount;
                var script = po.BuildOutputScript().Script;
                return(new Transaction.Output(amount, Transaction.Output.LatestPkScriptVersion, script));
            }).ToArray();

            TransactionAuthor.InputSource inputSource = async targetAmount =>
            {
                var inputs = new Transaction.Input[0];
                // TODO: don't hardcode confs
                var funding = await walletClient.FundTransactionAsync(SelectedAccount.Account, targetAmount, 1);

                if (funding.Item2 >= targetAmount)
                {
                    inputs = funding.Item1.Select(o =>
                                                  Transaction.Input.CreateFromPrefix(new Transaction.OutPoint(o.TransactionHash, o.OutputIndex, o.Tree),
                                                                                     TransactionRules.MaxInputSequence)).ToArray();
                }
                return(Tuple.Create(funding.Item2, inputs));
            };
            TransactionAuthor.ChangeSource changeSource = async() =>
            {
                // Use cached change script if one has already been generated for this account.
                var          selectedAccount = SelectedAccount.Account;
                OutputScript cachedScript;
                if (_unusedChangeScripts.TryGetValue(selectedAccount, out cachedScript))
                {
                    return(cachedScript);
                }

                var changeAddress = await walletClient.NextInternalAddressAsync(SelectedAccount.Account);

                var changeScript = Address.Decode(changeAddress).BuildScript();
                _unusedChangeScripts[selectedAccount] = changeScript;
                return(changeScript);
            };

            try
            {
                var r = await TransactionAuthor.BuildUnsignedTransaction(outputs, TransactionFees.DefaultFeePerKb, inputSource, changeSource);

                Amount totalAccountBalance;
                using (var walletGuard = await App.Current.Synchronizer.WalletMutex.LockAsync())
                {
                    totalAccountBalance = walletGuard.Instance.LookupAccountProperties(SelectedAccount.Account).TotalBalance;
                }
                SetPendingTransaction(totalAccountBalance, r.Item1, r.Item2, outputs.Sum(o => o.Amount));
            }
            catch (Exception ex)
            {
                UnsetPendingTransaction();

                // Insufficient funds will need a nicer error displayed somehow.  For now, hide it
                // while disabling the UI to create the transaction.  All other errors are unexpected.
                if (!(ex is InsufficientFundsException))
                {
                    throw;
                }
            }
        }