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
......@@ -196,8 +196,6 @@ Works as expected.
"1HDypWxXWZC5KXK259EHMnrWaa2youy7Mj"
```
## GET /wallet/mempool/?allow=[true/false] - Allows or disallows mempool syncing
Works as expected.
## GET /wallet/receive/[account1/account2] - Displays unused receive addresses of the specified wallet account
### Responses
......@@ -216,38 +214,54 @@ Works as expected.
}
```
## GET /wallet/history/[account1/account2] - Displays the history of the specified wallet account
## GET /wallet/history - Displays the history of the specified wallet account
### Query parameters
`walletName` (required) - the name of the wallet.
`coinType` (required) - the type of coin, e.g 0 for bitcoin, 105 for stratis.
### Responses
```
{
"history":
[
"transactions": [
{
"txid": "9a9949476b629b4075b31d8faad64dad352586a18df8f2810c5a7bb900478c60",
"amount": "0.1",
"address": "1H2jbtknP6jRYx2riaXJf3H9Mb1JC6kcL2",
"txId": "b800f9b24a9c49a375cddf4fc8c484722af0bec7d23ac65b782daf1b0089bb29",
"amount": -50360386,
"confirmed": true,
"timestamp": "2016.12.19. 23:15:05" // if confirmed it's the blocktime, utc
"timestamp": "1337803568"
},
{
"txid": "9a9949476b629b4075b31d8faad64dad352586a18df8f2810c5a7bb900478c60",
"amount": "-0.1",
"confirmed": false,
"timestamp": "2016.12.20. 1:15:36" // if unconfirmed it's the time our node first seen this transaction, utc
"address": "1H2jbtknP6jRYx2riaXJf3H9Mb1JC6kcL2",
"txId": "9c0560a34f88573a71ebf68a2540cb7215b55bc2ddee0af3cb1dc343f2f3e0da",
"amount": 53845026,
"confirmed": true,
"timestamp": "1337605326"
}
]
}
```
## GET /wallet/balance/[account1/account2] - Displays the balances of the specified wallet account
## GET /wallet/balance - Displays the balances of the specified wallet account
### Query parameters
`walletName` (required) - the name of the wallet.
`coinType` (required) - the type of coin, e.g 0 for bitcoin, 105 for stratis.
### Responses
```
{
"isSynced": true,
"confirmed": "0.144",
"unconfirmed": "-6.23"
"balances": [
{
"accountName": "account one",
"accountHdPath": "m/44'/0'/0'",
"coinType": 0,
"amountConfirmed": 209268016,
"amountUnconfirmed": 0
}
]
}
```
If the synced is false, then the balances might not be accurate.
Confirmed balance is the (amount of unspent confirmed outputs - unconfirmed outgoing transactions). It cannot be negative.
Unconfirmed balance is the difference of unconfirmed incoming and outgoing transactions. It can be negative.
......
......@@ -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": [
{
......
......@@ -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)))
......@@ -210,7 +210,8 @@ 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")]
[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)
{
......
......@@ -74,8 +74,6 @@ namespace Breeze.Wallet
WalletGeneralInfoModel GetGeneralInfo(string walletName);
WalletBalanceModel GetBalance(string walletName);
/// <summary>
/// Gets a list of accounts filtered by coin type.
/// </summary>
......
......@@ -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; }
}
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 = "confirmed")]
public Money Confirmed { 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,11 +208,6 @@ 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)
{
......
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