Commit 135a3452 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Merge pull request #44 from bokobza/feature/build-transaction

Feature/build transaction
parents 823f271e d520c752
...@@ -295,4 +295,4 @@ Thumbs.db ...@@ -295,4 +295,4 @@ Thumbs.db
# DNX # DNX
project.lock.json project.lock.json
/Breeze/src/Breeze.Deamon/Wallets /Breeze/src/Breeze.Daemon/Wallets
...@@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Api.Tests", "src\Bre ...@@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Api.Tests", "src\Bre
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Wallet", "src\Breeze.Wallet\Breeze.Wallet.csproj", "{D16CD478-9D1E-4C69-91AD-43539E94A215}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Wallet", "src\Breeze.Wallet\Breeze.Wallet.csproj", "{D16CD478-9D1E-4C69-91AD-43539E94A215}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Deamon", "src\Breeze.Deamon\Breeze.Deamon.csproj", "{1B598E33-667F-496D-BC0D-88276E8E7632}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Breeze.Daemon", "src\Breeze.Daemon\Breeze.Daemon.csproj", "{1B598E33-667F-496D-BC0D-88276E8E7632}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>..\\Breeze.Deamon\\bin\\Debug\\netcoreapp1.0\\Breeze.Api.xml</DocumentationFile> <DocumentationFile>..\\Breeze.Daemon\\bin\\Debug\\netcoreapp1.0\\Breeze.Api.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework> <TargetFramework>netcoreapp1.0</TargetFramework>
<AssemblyName>Breeze.Deamon</AssemblyName> <AssemblyName>Breeze.Daemon</AssemblyName>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<PackageId>Breeze.Deamon</PackageId> <PackageId>Breeze.Daemon</PackageId>
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion> <RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback> <PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
......
...@@ -9,7 +9,7 @@ using Stratis.Bitcoin.Logging; ...@@ -9,7 +9,7 @@ using Stratis.Bitcoin.Logging;
using Breeze.Wallet; using Breeze.Wallet;
using Stratis.Bitcoin.Notifications; using Stratis.Bitcoin.Notifications;
namespace Breeze.Deamon namespace Breeze.Daemon
{ {
public class Program public class Program
{ {
......
...@@ -7,7 +7,7 @@ using System.Runtime.InteropServices; ...@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Breeze.Deamon")] [assembly: AssemblyProduct("Breeze.Daemon")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>..\\Breeze.Deamon\\bin\\Debug\\netcoreapp1.0\\Breeze.Wallet.xml</DocumentationFile> <DocumentationFile>..\\Breeze.Daemon\\bin\\Debug\\netcoreapp1.0\\Breeze.Wallet.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -198,8 +198,9 @@ namespace Breeze.Wallet.Controllers ...@@ -198,8 +198,9 @@ namespace Breeze.Wallet.Controllers
{ {
WalletHistoryModel model = new WalletHistoryModel { Transactions = new List<TransactionItem>() }; WalletHistoryModel model = new WalletHistoryModel { Transactions = new List<TransactionItem>() };
var accounts = this.walletManager.GetAccountsByCoinType(request.WalletName, request.CoinType).ToList(); // get transactions contained in the wallet
foreach (var address in accounts.SelectMany(a => a.ExternalAddresses).Concat(accounts.SelectMany(a => a.InternalAddresses))) var addresses = this.walletManager.GetHistoryByCoinType(request.WalletName, request.CoinType);
foreach (var address in addresses)
{ {
foreach (var transaction in address.Transactions) foreach (var transaction in address.Transactions)
{ {
...@@ -213,7 +214,7 @@ namespace Breeze.Wallet.Controllers ...@@ -213,7 +214,7 @@ namespace Breeze.Wallet.Controllers
}); });
} }
} }
model.Transactions = model.Transactions.OrderByDescending(t => t.Timestamp).ToList(); model.Transactions = model.Transactions.OrderByDescending(t => t.Timestamp).ToList();
return this.Json(model); return this.Json(model);
} }
......
...@@ -74,7 +74,7 @@ namespace Breeze.Wallet ...@@ -74,7 +74,7 @@ namespace Breeze.Wallet
/// </remarks> /// </remarks>
/// <returns>An unused account.</returns> /// <returns>An unused account.</returns>
HdAccount GetUnusedAccount(Wallet wallet, CoinType coinType, string password); HdAccount GetUnusedAccount(Wallet wallet, CoinType coinType, string password);
/// <summary> /// <summary>
/// Creates a new account. /// Creates a new account.
/// </summary> /// </summary>
...@@ -97,6 +97,22 @@ namespace Breeze.Wallet ...@@ -97,6 +97,22 @@ namespace Breeze.Wallet
/// <returns>An unused address or a newly created address, in Base58 format.</returns> /// <returns>An unused address or a newly created address, in Base58 format.</returns>
string GetUnusedAddress(string walletName, CoinType coinType, string accountName); string GetUnusedAddress(string walletName, CoinType coinType, string accountName);
/// <summary>
/// Gets a collection of addresses containing transactions for this coin.
/// </summary>
/// <param name="walletName">The name of the wallet to get history from.</param>
/// <param name="coinType">Type of the coin.</param>
/// <returns></returns>
IEnumerable<HdAddress> GetHistoryByCoinType(string walletName, CoinType coinType);
/// <summary>
/// Gets a collection of addresses containing transactions for this coin.
/// </summary>
/// <param name="wallet">The wallet to get history from.</param>
/// <param name="coinType">Type of the coin.</param>
/// <returns></returns>
IEnumerable<HdAddress> GetHistoryByCoinType(Wallet wallet, CoinType coinType);
WalletGeneralInfoModel GetGeneralInfo(string walletName); WalletGeneralInfoModel GetGeneralInfo(string walletName);
/// <summary> /// <summary>
...@@ -126,6 +142,6 @@ namespace Breeze.Wallet ...@@ -126,6 +142,6 @@ namespace Breeze.Wallet
/// <param name="transaction">The transaction.</param> /// <param name="transaction">The transaction.</param>
/// <param name="blockHeight">The height of the block this transaction came from. Null if it was not a transaction included in a block.</param> /// <param name="blockHeight">The height of the block this transaction came from. Null if it was not a transaction included in a block.</param>
/// <param name="blockTime">The block time.</param> /// <param name="blockTime">The block time.</param>
void ProcessTransaction(CoinType coinType, NBitcoin.Transaction transaction, int? blockHeight = null, uint? blockTime = null); void ProcessTransaction(CoinType coinType, NBitcoin.Transaction transaction, int? blockHeight = null, uint? blockTime = null);
} }
} }
...@@ -57,6 +57,33 @@ namespace Breeze.Wallet ...@@ -57,6 +57,33 @@ namespace Breeze.Wallet
/// </summary> /// </summary>
[JsonProperty(PropertyName = "accountsRoot")] [JsonProperty(PropertyName = "accountsRoot")]
public IEnumerable<AccountRoot> AccountsRoot { get; set; } public IEnumerable<AccountRoot> AccountsRoot { get; set; }
/// <summary>
/// Gets the type of the accounts by coin.
/// </summary>
/// <param name="coinType">Type of the coin.</param>
/// <returns></returns>
public IEnumerable<HdAccount> GetAccountsByCoinType(CoinType coinType)
{
return this.AccountsRoot.Where(a => a.CoinType == coinType).SelectMany(a => a.Accounts);
}
/// <summary>
/// Gets all the transactions by coin type.
/// </summary>
/// <param name="coinType">Type of the coin.</param>
/// <returns></returns>
public IEnumerable<TransactionData> GetAllTransactionsByCoinType(CoinType coinType)
{
List<TransactionData> result = new List<TransactionData>();
var accounts = this.GetAccountsByCoinType(coinType).ToList();
foreach (var address in accounts.SelectMany(a => a.ExternalAddresses).Concat(accounts.SelectMany(a => a.InternalAddresses)))
{
result.AddRange(address.Transactions);
}
return result;
}
} }
/// <summary> /// <summary>
...@@ -219,7 +246,18 @@ namespace Breeze.Wallet ...@@ -219,7 +246,18 @@ namespace Breeze.Wallet
// gets the used address with the highest index // gets the used address with the highest index
var index = usedAddresses.Max(a => a.Index); var index = usedAddresses.Max(a => a.Index);
return usedAddresses.Single(a => a.Index == index); return usedAddresses.Single(a => a.Index == index);
} }
/// <summary>
/// Gets a collection of transactions by id.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns></returns>
public IEnumerable<TransactionData> GetTransactionsById(uint256 id)
{
var addresses = this.ExternalAddresses.Concat(this.InternalAddresses);
return addresses.SelectMany(a => a.Transactions.Where(t => t.Id == id));
}
} }
/// <summary> /// <summary>
...@@ -232,14 +270,7 @@ namespace Breeze.Wallet ...@@ -232,14 +270,7 @@ namespace Breeze.Wallet
/// </summary> /// </summary>
[JsonProperty(PropertyName = "index")] [JsonProperty(PropertyName = "index")]
public int Index { get; set; } public int Index { get; set; }
/// <summary>
/// Gets or sets the creation time.
/// </summary>
[JsonProperty(PropertyName = "creationTime")]
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset CreationTime { get; set; }
/// <summary> /// <summary>
/// The script pub key for this address. /// The script pub key for this address.
/// </summary> /// </summary>
...@@ -284,6 +315,13 @@ namespace Breeze.Wallet ...@@ -284,6 +315,13 @@ namespace Breeze.Wallet
[JsonConverter(typeof(UInt256JsonConverter))] [JsonConverter(typeof(UInt256JsonConverter))]
public uint256 Id { get; set; } public uint256 Id { get; set; }
/// <summary>
/// The id of the transaction in which the output referenced in this transaction is spent.
/// </summary>
[JsonProperty(PropertyName = "spentIn", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(UInt256JsonConverter))]
public uint256 SpentInTransaction { get; set; }
/// <summary> /// <summary>
/// The transaction amount. /// The transaction amount.
/// </summary> /// </summary>
......
...@@ -40,14 +40,14 @@ namespace Breeze.Wallet ...@@ -40,14 +40,14 @@ namespace Breeze.Wallet
// find wallets and load them in memory // find wallets and load them in memory
foreach (var path in this.GetWalletFilesPaths()) foreach (var path in this.GetWalletFilesPaths())
{ {
this.Load(this.GetWallet(path)); this.Load(this.DeserializeWallet(path));
} }
// load data in memory for faster lookups // load data in memory for faster lookups
// TODO get the coin type from somewhere else // TODO get the coin type from somewhere else
this.PubKeys = this.LoadKeys(CoinType.Bitcoin); this.PubKeys = this.LoadKeys(CoinType.Bitcoin);
this.TrackedTransactions = this.LoadTransactions(CoinType.Bitcoin); this.TrackedTransactions = this.LoadTransactions(CoinType.Bitcoin);
this.TransactionFound += this.OnTransactionFound; this.TransactionFound += this.OnTransactionFound;
} }
/// <inheritdoc /> /// <inheritdoc />
...@@ -91,7 +91,7 @@ namespace Breeze.Wallet ...@@ -91,7 +91,7 @@ namespace Breeze.Wallet
string walletFilePath = Path.Combine(folderPath, $"{name}.json"); string walletFilePath = Path.Combine(folderPath, $"{name}.json");
// load the file from the local system // load the file from the local system
Wallet wallet = this.GetWallet(walletFilePath); Wallet wallet = this.DeserializeWallet(walletFilePath);
this.Load(wallet); this.Load(wallet);
return wallet; return wallet;
...@@ -133,11 +133,7 @@ namespace Breeze.Wallet ...@@ -133,11 +133,7 @@ namespace Breeze.Wallet
/// <inheritdoc /> /// <inheritdoc />
public HdAccount GetUnusedAccount(string walletName, CoinType coinType, string password) public HdAccount GetUnusedAccount(string walletName, CoinType coinType, string password)
{ {
Wallet wallet = this.Wallets.SingleOrDefault(w => w.Name == walletName); Wallet wallet = this.GetWalletByName(walletName);
if (wallet == null)
{
throw new Exception($"No wallet with name {walletName} could be found.");
}
return this.GetUnusedAccount(wallet, coinType, password); return this.GetUnusedAccount(wallet, coinType, password);
} }
...@@ -207,11 +203,7 @@ namespace Breeze.Wallet ...@@ -207,11 +203,7 @@ namespace Breeze.Wallet
/// <inheritdoc /> /// <inheritdoc />
public string GetUnusedAddress(string walletName, CoinType coinType, string accountName) public string GetUnusedAddress(string walletName, CoinType coinType, string accountName)
{ {
Wallet wallet = this.Wallets.SingleOrDefault(w => w.Name == walletName); Wallet wallet = this.GetWalletByName(walletName);
if (wallet == null)
{
throw new Exception($"No wallet with name {walletName} could be found.");
}
// get the account // get the account
HdAccount account = wallet.AccountsRoot.Single(a => a.CoinType == coinType).Accounts.SingleOrDefault(a => a.Name == accountName); HdAccount account = wallet.AccountsRoot.Single(a => a.CoinType == coinType).Accounts.SingleOrDefault(a => a.Name == accountName);
...@@ -242,6 +234,28 @@ namespace Breeze.Wallet ...@@ -242,6 +234,28 @@ namespace Breeze.Wallet
return account.GetFirstUnusedExternalAddress().Address; return account.GetFirstUnusedExternalAddress().Address;
} }
/// <inheritdoc />
public IEnumerable<HdAddress> GetHistoryByCoinType(string walletName, CoinType coinType)
{
Wallet wallet = this.GetWalletByName(walletName);
return this.GetHistoryByCoinType(wallet, coinType);
}
/// <inheritdoc />
public IEnumerable<HdAddress> GetHistoryByCoinType(Wallet wallet, CoinType coinType)
{
var accounts = wallet.GetAccountsByCoinType(coinType).ToList();
foreach (var address in accounts.SelectMany(a => a.ExternalAddresses).Concat(accounts.SelectMany(a => a.InternalAddresses)))
{
if (address.Transactions.Any())
{
yield return address;
}
}
}
/// <summary> /// <summary>
/// Creates a number of addresses in the provided account. /// Creates a number of addresses in the provided account.
/// </summary> /// </summary>
...@@ -275,8 +289,7 @@ namespace Breeze.Wallet ...@@ -275,8 +289,7 @@ namespace Breeze.Wallet
HdPath = CreateBip44Path(account.GetCoinType(), account.Index, i, isChange), HdPath = CreateBip44Path(account.GetCoinType(), account.Index, i, isChange),
ScriptPubKey = address.ScriptPubKey, ScriptPubKey = address.ScriptPubKey,
Address = address.ToString(), Address = address.ToString(),
Transactions = new List<TransactionData>(), Transactions = new List<TransactionData>()
CreationTime = DateTimeOffset.Now
}}); }});
addressesCreated.Add(address.ToString()); addressesCreated.Add(address.ToString());
...@@ -302,9 +315,9 @@ namespace Breeze.Wallet ...@@ -302,9 +315,9 @@ namespace Breeze.Wallet
/// <inheritdoc /> /// <inheritdoc />
public IEnumerable<HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType) public IEnumerable<HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType)
{ {
return this.Wallets. Wallet wallet = this.GetWalletByName(walletName);
SelectMany(w => w.AccountsRoot.Where(a => a.CoinType == coinType)).
SelectMany(a => a.Accounts); return wallet.GetAccountsByCoinType(coinType);
} }
public WalletBuildTransactionModel BuildTransaction(string password, string address, Money amount, string feeType, bool allowUnconfirmed) public WalletBuildTransactionModel BuildTransaction(string password, string address, Money amount, string feeType, bool allowUnconfirmed)
...@@ -342,13 +355,13 @@ namespace Breeze.Wallet ...@@ -342,13 +355,13 @@ namespace Breeze.Wallet
{ {
Console.WriteLine($"transaction notification: tx hash {transaction.GetHash()}, coin type: {coinType}"); Console.WriteLine($"transaction notification: tx hash {transaction.GetHash()}, coin type: {coinType}");
foreach (var k in this.PubKeys) foreach (var pubKey in this.PubKeys)
{ {
// check if the outputs contain one of our addresses // check if the outputs contain one of our addresses
var utxo = transaction.Outputs.SingleOrDefault(o => k == o.ScriptPubKey); var utxo = transaction.Outputs.SingleOrDefault(o => pubKey == o.ScriptPubKey);
if (utxo != null) if (utxo != null)
{ {
AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, k, blockHeight, blockTime); AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, pubKey, blockHeight, blockTime);
} }
// if the inputs have a reference to a transaction containing one of our scripts // if the inputs have a reference to a transaction containing one of our scripts
...@@ -359,7 +372,7 @@ namespace Breeze.Wallet ...@@ -359,7 +372,7 @@ namespace Breeze.Wallet
// compare the index of the output in its original transaction and the index references in the input // compare the index of the output in its original transaction and the index references in the input
if (input.PrevOut.N == tTx.Index) if (input.PrevOut.N == tTx.Index)
{ {
AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, null, -tTx.Amount, k, blockHeight, blockTime); AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, null, -tTx.Amount, pubKey, blockHeight, blockTime, tTx.Hash, tTx.Index);
} }
} }
} }
...@@ -376,7 +389,9 @@ namespace Breeze.Wallet ...@@ -376,7 +389,9 @@ namespace Breeze.Wallet
/// <param name="script">The script.</param> /// <param name="script">The script.</param>
/// <param name="blockHeight">Height of the block.</param> /// <param name="blockHeight">Height of the block.</param>
/// <param name="blockTime">The block time.</param> /// <param name="blockTime">The block time.</param>
private void AddTransactionToWallet(CoinType coinType, uint256 transactionHash, uint time, int? index, Money amount, Script script, int? blockHeight = null, uint? blockTime = null) /// <param name="spendingTransactionId">The id of the transaction containing the output being spent, if this is a spending transaction.</param>
/// <param name="spendingTransactionIndex">The index of the output in the transaction being referenced, if this is a spending transaction.</param>
private void AddTransactionToWallet(CoinType coinType, uint256 transactionHash, uint time, int? index, Money amount, Script script, int? blockHeight = null, uint? blockTime = null, uint256 spendingTransactionId = null, int? spendingTransactionIndex = null)
{ {
// selects all the transactions we already have in the wallet // selects all the transactions we already have in the wallet
var txs = this.Wallets. var txs = this.Wallets.
...@@ -403,7 +418,7 @@ namespace Breeze.Wallet ...@@ -403,7 +418,7 @@ namespace Breeze.Wallet
Amount = amount, Amount = amount,
BlockHeight = blockHeight, BlockHeight = blockHeight,
Confirmed = blockHeight.HasValue, Confirmed = blockHeight.HasValue,
Id = transactionHash, Id = transactionHash,
CreationTime = DateTimeOffset.FromUnixTimeMilliseconds(blockTime ?? time), CreationTime = DateTimeOffset.FromUnixTimeMilliseconds(blockTime ?? time),
Index = index Index = index
} }
...@@ -412,6 +427,16 @@ namespace Breeze.Wallet ...@@ -412,6 +427,16 @@ namespace Breeze.Wallet
// notify a transaction has been found // notify a transaction has been found
this.TransactionFound?.Invoke(this, new TransactionFoundEventArgs(wallet, accountRoot.CoinType, account, address, false)); this.TransactionFound?.Invoke(this, new TransactionFoundEventArgs(wallet, accountRoot.CoinType, account, address, false));
} }
// if this is a spending transaction, mark the spent transaction as such
if (spendingTransactionId != null)
{
var transactions = account.GetTransactionsById(spendingTransactionId);
if (transactions.Any())
{
transactions.Single(t => t.Index == spendingTransactionIndex).SpentInTransaction = transactionHash;
}
}
} }
} }
} }
...@@ -518,7 +543,7 @@ namespace Breeze.Wallet ...@@ -518,7 +543,7 @@ namespace Breeze.Wallet
/// <param name="walletFilePath">The wallet file path.</param> /// <param name="walletFilePath">The wallet file path.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="System.IO.FileNotFoundException"></exception> /// <exception cref="System.IO.FileNotFoundException"></exception>
private Wallet GetWallet(string walletFilePath) private Wallet DeserializeWallet(string walletFilePath)
{ {
if (!File.Exists(walletFilePath)) if (!File.Exists(walletFilePath))
throw new FileNotFoundException($"No wallet file found at {walletFilePath}"); throw new FileNotFoundException($"No wallet file found at {walletFilePath}");
...@@ -600,8 +625,8 @@ namespace Breeze.Wallet ...@@ -600,8 +625,8 @@ namespace Breeze.Wallet
SelectMany(a => a.Accounts). SelectMany(a => a.Accounts).
SelectMany(a => a.ExternalAddresses). SelectMany(a => a.ExternalAddresses).
Select(s => s.ScriptPubKey)); Select(s => s.ScriptPubKey));
// uncomment the following for testing on a random address // uncomment the following for testing on a random address
//Select(t => (new BitcoinPubKeyAddress(t.Address, Network.Main)).ScriptPubKey)); //Select(t => (new BitcoinPubKeyAddress(t.Address, Network.Main)).ScriptPubKey));
} }
/// <summary> /// <summary>
...@@ -623,6 +648,22 @@ namespace Breeze.Wallet ...@@ -623,6 +648,22 @@ namespace Breeze.Wallet
Amount = t.Amount Amount = t.Amount
})); }));
} }
/// <summary>
/// Gets a wallet given its name.
/// </summary>
/// <param name="walletName">The name of the wallet to get.</param>
/// <returns>A wallet or null if it doesn't exist</returns>
private Wallet GetWalletByName(string walletName)
{
Wallet wallet = this.Wallets.SingleOrDefault(w => w.Name == walletName);
if (wallet == null)
{
throw new Exception($"No wallet with name {walletName} could be found.");
}
return wallet;
}
} }
public class TransactionDetails public class TransactionDetails
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment