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); } }
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); } }
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; } } }