Commit e4036778 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Merge pull request #37 from bokobza/feature/history

Added get transactions history
parents 0a7b7a87 d8bcbeb8
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
...@@ -176,11 +177,11 @@ namespace Breeze.Wallet.Controllers ...@@ -176,11 +177,11 @@ namespace Breeze.Wallet.Controllers
/// <summary> /// <summary>
/// Retrieves the history of a wallet. /// Retrieves the history of a wallet.
/// </summary> /// </summary>
/// <param name="model">The name of the wallet.</param> /// <param name="request">The request parameters.</param>
/// <returns></returns> /// <returns></returns>
[Route("history")] [Route("history")]
[HttpGet] [HttpGet]
public IActionResult GetHistory([FromQuery] WalletName model) public IActionResult GetHistory([FromQuery] WalletHistoryRequest request)
{ {
// checks the request is valid // checks the request is valid
if (!this.ModelState.IsValid) if (!this.ModelState.IsValid)
...@@ -191,8 +192,25 @@ namespace Breeze.Wallet.Controllers ...@@ -191,8 +192,25 @@ namespace Breeze.Wallet.Controllers
try try
{ {
return this.Json(this.walletManager.GetHistory(model.Name)); 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)))
{
foreach (var transaction in address.Transactions)
{
model.Transactions.Add(new TransactionItem
{
Amount = transaction.Amount,
Confirmed = transaction.Confirmed,
Timestamp = transaction.CreationTime,
TransactionId = transaction.Id,
Address = address.Address
});
}
}
return this.Json(model.Transactions.OrderByDescending(t => t.Timestamp));
} }
catch (Exception e) catch (Exception e)
{ {
......
using System; using System;
using System.Collections.Generic;
using Breeze.Wallet.Models; using Breeze.Wallet.Models;
using NBitcoin; using NBitcoin;
...@@ -75,7 +76,13 @@ namespace Breeze.Wallet ...@@ -75,7 +76,13 @@ namespace Breeze.Wallet
WalletBalanceModel GetBalance(string walletName); WalletBalanceModel GetBalance(string walletName);
WalletHistoryModel GetHistory(string walletName); /// <summary>
/// Gets a list of accounts filtered by coin type.
/// </summary>
/// <param name="walletName">The name of the wallet to look into.</param>
/// <param name="coinType">The type of coin to filter by.</param>
/// <returns></returns>
IEnumerable<HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType);
WalletBuildTransactionModel BuildTransaction(string password, string address, Money amount, string feeType, bool allowUnconfirmed); WalletBuildTransactionModel BuildTransaction(string password, string address, Money amount, string feeType, bool allowUnconfirmed);
......
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Breeze.Wallet.Models
{
/// <summary>
/// Object used to create a new wallet
/// </summary>
public class WalletCreationRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string Network { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet to create is missing.")]
public string Name { get; set; }
}
public class WalletLoadRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string Name { get; set; }
}
public class WalletRecoveryRequest
{
[Required(ErrorMessage = "A mnemonic is required.")]
public string Mnemonic { get; set; }
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string Name { get; set; }
public string Network { get; set; }
}
public class WalletHistoryRequest
{
[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.")]
public string Name { get; set; }
}
public class BuildTransactionRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
[Required(ErrorMessage = "A destination address is required.")]
public string Address { get; set; }
[Required(ErrorMessage = "An amount is required.")]
public string Amount { get; set; }
[Required(ErrorMessage = "A fee type is required. It can be 'low', 'medium' or 'high'.")]
public string FeeType { get; set; }
public bool AllowUnconfirmed { get; set; }
}
public class SendTransactionRequest
{
[Required(ErrorMessage = "A transaction in hexadecimal format is required.")]
public string Hex { get; set; }
}
}
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Breeze.Wallet.Models
{
/// <summary>
/// Object used to create a new wallet
/// </summary>
public class WalletCreationRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string Network { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet to create is missing.")]
public string Name { get; set; }
}
public class WalletLoadRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string Name { get; set; }
}
public class WalletRecoveryRequest
{
[Required(ErrorMessage = "A mnemonic is required.")]
public string Mnemonic { get; set; }
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
public string FolderPath { get; set; }
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string Name { get; set; }
public string Network { get; set; }
}
public class WalletName
{
[Required(ErrorMessage = "The name of the wallet is missing.")]
public string Name { get; set; }
}
public class BuildTransactionRequest
{
[Required(ErrorMessage = "A password is required.")]
public string Password { get; set; }
[Required(ErrorMessage = "A destination address is required.")]
public string Address { get; set; }
[Required(ErrorMessage = "An amount is required.")]
public string Amount { get; set; }
[Required(ErrorMessage = "A fee type is required. It can be 'low', 'medium' or 'high'.")]
public string FeeType { get; set; }
public bool AllowUnconfirmed { get; set; }
}
public class SendTransactionRequest
{
[Required(ErrorMessage = "A transaction in hexadecimal format is required.")]
public string Hex { get; set; }
}
}
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Breeze.Wallet.JsonConverters;
using NBitcoin; using NBitcoin;
using NBitcoin.JsonConverters;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Breeze.Wallet.Models namespace Breeze.Wallet.Models
{ {
public class WalletHistoryModel public class WalletHistoryModel
{ {
[JsonProperty(PropertyName = "transactions")] [JsonProperty(PropertyName = "transactions")]
public List<TransactionItem> Transactions { get; set; } public List<TransactionItem> Transactions { get; set; }
} }
public class TransactionItem public class TransactionItem
{ {
[JsonProperty(PropertyName = "txId")] /// <summary>
public string TransactionId { get; set; } /// The Base58 representation of this address.
/// </summary>
[JsonProperty(PropertyName = "address")]
public string Address { get; set; }
[JsonProperty(PropertyName = "txId")]
[JsonConverter(typeof(UInt256JsonConverter))]
public uint256 TransactionId { get; set; }
[JsonProperty(PropertyName = "amount")] [JsonProperty(PropertyName = "amount")]
public Money Amount { get; set; } public Money Amount { get; set; }
[JsonProperty(PropertyName = "confirmed")] [JsonProperty(PropertyName = "confirmed")]
public bool Confirmed { get; set; } public bool Confirmed { get; set; }
[JsonProperty(PropertyName = "timestamp")] [JsonProperty(PropertyName = "timestamp")]
public string Timestamp { get; set; } [JsonConverter(typeof(DateTimeOffsetConverter))]
} public DateTimeOffset Timestamp { get; set; }
}
} }
...@@ -223,7 +223,7 @@ namespace Breeze.Wallet ...@@ -223,7 +223,7 @@ namespace Breeze.Wallet
/// <summary> /// <summary>
/// The index of this scriptPubKey in the transaction it is contained. /// The index of this scriptPubKey in the transaction it is contained.
/// </summary> /// </summary>
[JsonProperty(PropertyName = "index")] [JsonProperty(PropertyName = "index", NullValueHandling = NullValueHandling.Ignore)]
public int? Index { get; set; } public int? Index { get; set; }
/// <summary> /// <summary>
......
...@@ -211,9 +211,12 @@ namespace Breeze.Wallet ...@@ -211,9 +211,12 @@ namespace Breeze.Wallet
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public WalletHistoryModel GetHistory(string walletName) /// <inheritdoc />
public IEnumerable<HdAccount> GetAccountsByCoinType(string walletName, CoinType coinType)
{ {
throw new System.NotImplementedException(); return this.Wallets.
SelectMany(w => w.AccountsRoot.Where(a => a.CoinType == coinType)).
SelectMany(a => a.Accounts);
} }
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)
...@@ -250,7 +253,7 @@ namespace Breeze.Wallet ...@@ -250,7 +253,7 @@ namespace Breeze.Wallet
public void ProcessTransaction(CoinType coinType, Transaction transaction, int? blockHeight = null, uint? blockTime = null) public void ProcessTransaction(CoinType coinType, Transaction transaction, int? blockHeight = null, uint? blockTime = null)
{ {
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 k in this.PubKeys)
{ {
// check if the outputs contain one of our addresses // check if the outputs contain one of our addresses
...@@ -267,7 +270,7 @@ namespace Breeze.Wallet ...@@ -267,7 +270,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, k, blockHeight, blockTime);
} }
} }
......
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