/// <inheritdoc /> public void SaveToFile(Wallet wallet) { File.WriteAllText(wallet.WalletFilePath, JsonConvert.SerializeObject(wallet, Formatting.Indented)); }
/// <inheritdoc /> public (string hex, uint256 transactionId, Money fee) BuildTransaction(string walletName, string accountName, CoinType coinType, string password, string destinationAddress, Money amount, string feeType, bool allowUnconfirmed) { if (amount == Money.Zero) { throw new Exception($"Cannot send transaction with 0 {this.coinType}"); } // get the wallet and the account Wallet wallet = this.GetWalletByName(walletName); HdAccount account = wallet.AccountsRoot.Single(a => a.CoinType == coinType).GetAccountByName(accountName); // get a list of transactions outputs that have not been spent IEnumerable <TransactionData> spendableTransactions = account.GetSpendableTransactions(); // get total spendable balance in the account. var balance = spendableTransactions.Sum(t => t.Amount); // make sure we have enough funds if (balance < amount) { throw new Exception("Not enough funds."); } // calculate which addresses needs to be used as well as the fee to be charged var calculationResult = this.CalculateFees(spendableTransactions, amount); // get extended private key var privateKey = Key.Parse(wallet.EncryptedSeed, password, wallet.Network); var seedExtKey = new ExtKey(privateKey, wallet.ChainCode); var signingKeys = new HashSet <ISecret>(); var coins = new List <Coin>(); foreach (var transactionToUse in calculationResult.transactionsToUse) { var address = account.FindAddressesForTransaction(t => t.Id == transactionToUse.Id && t.Index == transactionToUse.Index && t.Amount > 0).Single(); ExtKey addressExtKey = seedExtKey.Derive(new KeyPath(address.HdPath)); BitcoinExtKey addressPrivateKey = addressExtKey.GetWif(wallet.Network); signingKeys.Add(addressPrivateKey); coins.Add(new Coin(transactionToUse.Id, (uint)transactionToUse.Index, transactionToUse.Amount, transactionToUse.ScriptPubKey)); } // get address to send the change to var changeAddress = account.GetFirstUnusedChangeAddress(); // get script destination address Script destinationScript = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(new BitcoinPubKeyAddress(destinationAddress, wallet.Network)); // build transaction var builder = new TransactionBuilder(); Transaction tx = builder .AddCoins(coins) .AddKeys(signingKeys.ToArray()) .Send(destinationScript, amount) .SetChange(changeAddress.ScriptPubKey) .SendFees(calculationResult.fee) .BuildTransaction(true); if (!builder.Verify(tx)) { throw new Exception("Could not build transaction, please make sure you entered the correct data."); } return(tx.ToHex(), tx.GetHash(), calculationResult.fee); }
/// <inheritdoc /> public IEnumerable <HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType) { Wallet wallet = this.GetWalletByName(walletName); return(wallet.GetAccountsByCoinType(coinType)); }
/// <inheritdoc /> public Wallet GetWallet(string walletName) { Wallet wallet = this.GetWalletByName(walletName); return(wallet); }
/// <inheritdoc /> public IEnumerable <HdAddress> GetHistoryByCoinType(string walletName, CoinType coinType) { Wallet wallet = this.GetWalletByName(walletName); return(this.GetHistoryByCoinType(wallet, coinType)); }
/// <inheritdoc /> public HdAccount GetUnusedAccount(string walletName, CoinType coinType, string password) { Wallet wallet = this.GetWalletByName(walletName); return(this.GetUnusedAccount(wallet, coinType, password)); }