Commit 1dc3c9a7 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Merge pull request #38 from bokobza/feature/history

Added getting the balance for the user's accounts
parents e4036778 bae6052a
This diff is collapsed.
......@@ -110,7 +110,7 @@
{
"name": "Get Wallet History",
"request": {
"url": "http://localhost:5000/api/v1/wallet/history?name=mywallet",
"url": "http://localhost:5000/api/v1/wallet/history?walletname=wallet1&cointype=0",
"method": "GET",
"header": [
{
......@@ -130,7 +130,7 @@
{
"name": "Get wallet balance",
"request": {
"url": "http://localhost:5000/api/v1/wallet/balance?name=mywallet",
"url": "http://localhost:5000/api/v1/wallet/balance?walletname=wallet1&cointype=0",
"method": "GET",
"header": [
{
......
......@@ -121,7 +121,7 @@ namespace Breeze.Wallet.Controllers
DirectoryInfo walletFolder = GetWalletFolder(request.FolderPath);
Wallet wallet = this.walletManager.RecoverWallet(request.Password, walletFolder.FullName, request.Name, request.Network, request.Mnemonic);
// TODO give the tracker the date at which this wallet was originally created so that it can start syncing blocks for it
return this.Json(new WalletModel
......@@ -192,7 +192,7 @@ namespace Breeze.Wallet.Controllers
try
{
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();
foreach (var address in accounts.SelectMany(a => a.ExternalAddresses).Concat(accounts.SelectMany(a => a.InternalAddresses)))
......@@ -209,8 +209,9 @@ namespace Breeze.Wallet.Controllers
});
}
}
return this.Json(model.Transactions.OrderByDescending(t => t.Timestamp));
model.Transactions = model.Transactions.OrderByDescending(t => t.Timestamp).ToList();
return this.Json(model);
}
catch (Exception e)
{
......@@ -221,11 +222,11 @@ namespace Breeze.Wallet.Controllers
/// <summary>
/// Gets the balance of a wallet.
/// </summary>
/// <param name="model">The name of the wallet.</param>
/// <param name="request">The request parameters.</param>
/// <returns></returns>
[Route("balance")]
[Route("balance")]
[HttpGet]
public IActionResult GetBalance([FromQuery] WalletName model)
public IActionResult GetBalance([FromQuery] WalletBalanceRequest request)
{
// checks the request is valid
if (!this.ModelState.IsValid)
......@@ -236,8 +237,26 @@ namespace Breeze.Wallet.Controllers
try
{
return this.Json(this.walletManager.GetBalance(model.Name));
WalletBalanceModel model = new WalletBalanceModel { AccountsBalances = new List<AccountBalance>() };
var accounts = this.walletManager.GetAccountsByCoinType(request.WalletName, request.CoinType).ToList();
foreach (var account in accounts)
{
var allTransactions = account.ExternalAddresses.SelectMany(a => a.Transactions)
.Concat(account.InternalAddresses.SelectMany(i => i.Transactions)).ToList();
AccountBalance balance = new AccountBalance
{
CoinType = request.CoinType,
Name = account.Name,
HdPath = account.HdPath,
AmountConfirmed = allTransactions.Where(t => t.Confirmed).Sum(t => t.Amount),
AmountUnconfirmed = allTransactions.Where(t => !t.Confirmed).Sum(t => t.Amount)
};
model.AccountsBalances.Add(balance);
}
return this.Json(model);
}
catch (Exception e)
{
......
......@@ -71,10 +71,8 @@ namespace Breeze.Wallet
/// <param name="accountName">The name of the account in which this address will be created.</param>
/// <returns>The new address, in Base58 format.</returns>
string CreateNewAddress(string walletName, CoinType coinType, string accountName);
WalletGeneralInfoModel GetGeneralInfo(string walletName);
WalletBalanceModel GetBalance(string walletName);
WalletGeneralInfoModel GetGeneralInfo(string walletName);
/// <summary>
/// Gets a list of accounts filtered by coin type.
......
......@@ -56,6 +56,15 @@ namespace Breeze.Wallet.Models
public CoinType CoinType { get; set; }
}
public class WalletBalanceRequest
{
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string WalletName { get; set; }
[Required(ErrorMessage = "The type of coin for which history is requested is missing.")]
public CoinType CoinType { get; set; }
}
public class WalletName
{
[Required(ErrorMessage = "The name of the wallet is missing.")]
......
......@@ -9,13 +9,25 @@ namespace Breeze.Wallet.Models
{
public class WalletBalanceModel
{
[JsonProperty(PropertyName = "isSynced")]
public bool IsSynced { get; set; }
[JsonProperty(PropertyName = "balances")]
public List<AccountBalance> AccountsBalances { get; set; }
}
[JsonProperty(PropertyName = "confirmed")]
public Money Confirmed { get; set; }
public class AccountBalance
{
[JsonProperty(PropertyName = "accountName")]
public string Name { get; set; }
[JsonProperty(PropertyName = "accountHdPath")]
public string HdPath { get; set; }
[JsonProperty(PropertyName = "coinType")]
public CoinType CoinType { get; set; }
[JsonProperty(PropertyName = "amountConfirmed")]
public Money AmountConfirmed { get; set; }
[JsonProperty(PropertyName = "unconfirmed")]
public Money Unconfirmed { get; set; }
}
[JsonProperty(PropertyName = "amountUnconfirmed")]
public Money AmountUnconfirmed { get; set; }
}
}
......@@ -125,6 +125,13 @@ namespace Breeze.Wallet
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
/// <summary>
/// A path to the account as defined in BIP44.
/// </summary>
[JsonProperty(PropertyName = "hdPath")]
public string HdPath { get; set; }
/// <summary>
/// An extended pub key used to generate addresses.
/// </summary>
......
......@@ -127,7 +127,8 @@ namespace Breeze.Wallet
// get the extended pub key used to generate addresses for this account
var privateKey = Key.Parse(wallet.EncryptedSeed, password, wallet.Network);
var seedExtKey = new ExtKey(privateKey, wallet.ChainCode);
KeyPath keyPath = new KeyPath($"m/44'/{(int)coinType}'/{newAccountIndex}'");
var accountHdPath = $"m/44'/{(int) coinType}'/{newAccountIndex}'";
KeyPath keyPath = new KeyPath(accountHdPath);
ExtKey accountExtKey = seedExtKey.Derive(keyPath);
ExtPubKey accountExtPubKey = accountExtKey.Neuter();
......@@ -138,6 +139,7 @@ namespace Breeze.Wallet
ExternalAddresses = new List<HdAddress>(),
InternalAddresses = new List<HdAddress>(),
Name = accountName,
HdPath = accountHdPath,
CreationTime = DateTimeOffset.Now
});
......@@ -206,17 +208,12 @@ namespace Breeze.Wallet
throw new System.NotImplementedException();
}
public WalletBalanceModel GetBalance(string walletName)
{
throw new System.NotImplementedException();
}
/// <inheritdoc />
public IEnumerable<HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType)
{
return this.Wallets.
SelectMany(w => w.AccountsRoot.Where(a => a.CoinType == coinType)).
SelectMany(a => a.Accounts);
SelectMany(a => a.Accounts);
}
public WalletBuildTransactionModel BuildTransaction(string password, string address, Money amount, string feeType, bool allowUnconfirmed)
......@@ -253,7 +250,7 @@ namespace Breeze.Wallet
public void ProcessTransaction(CoinType coinType, Transaction transaction, int? blockHeight = null, uint? blockTime = null)
{
Console.WriteLine($"transaction notification: tx hash {transaction.GetHash()}, coin type: {coinType}");
foreach (var k in this.PubKeys)
{
// check if the outputs contain one of our addresses
......@@ -270,7 +267,7 @@ namespace Breeze.Wallet
// compare the index of the output in its original transaction and the index references in the input
if (input.PrevOut.N == tTx.Index)
{
{
AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, null, -tTx.Amount, k, blockHeight, blockTime);
}
}
......@@ -488,7 +485,7 @@ namespace Breeze.Wallet
SelectMany(a => a.ExternalAddresses).
Select(s => s.ScriptPubKey));
// 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>
......
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