Commit e6f7cf8f authored by Jeremy Bokobza's avatar Jeremy Bokobza

Merged the Wallet and WalletFIle objects, no need to have both.

Added a WalletHierarchy class to contain accounts, addresses and transactions.
parent 73763b96
using System;
using Breeze.Wallet.JsonConverters;
using NBitcoin;
using Newtonsoft.Json;
namespace Breeze.Wallet
{
......@@ -8,29 +10,44 @@ namespace Breeze.Wallet
/// </summary>
public class Wallet
{
/// <summary>
/// The seed for this wallet, password encrypted.
/// </summary>
[JsonProperty(PropertyName = "encryptedSeed")]
public string EncryptedSeed { get; set; }
/// <summary>
/// The chain code.
/// </summary>
[JsonProperty(PropertyName = "chainCode")]
[JsonConverter(typeof(ByteArrayConverter))]
public byte[] ChainCode { get; set; }
/// <summary>
/// The network this wallet is for.
/// </summary>
[JsonProperty(PropertyName = "network")]
[JsonConverter(typeof(NetworkConverter))]
public Network Network { get; set; }
/// <summary>
/// The time this wallet was created.
/// </summary>
[JsonProperty(PropertyName = "creationTime")]
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset CreationTime { get; set; }
/// <summary>
/// The location of the wallet file on the local system.
/// </summary>
[JsonIgnore]
public string WalletFilePath { get; set; }
/// <summary>
/// The key used to generate keys.
/// The hierarchy of the wallet's accounts and addresses.
/// </summary>
public ExtKey ExtendedKey { get; set; }
[JsonProperty(PropertyName = "hierarchy")]
public WalletHierarchy Hierarchy { get; set; }
}
}
\ No newline at end of file
......@@ -42,7 +42,7 @@ namespace Breeze.Wallet
.FeatureServices(services =>
{
services.AddTransient<IWalletWrapper, WalletWrapper>();
services.AddTransient<ITrackerWrapper, TrackerWrapper>();
services.AddSingleton<ITrackerWrapper, TrackerWrapper>();
services.AddSingleton<IWalletManager, WalletManager>();
services.AddSingleton<WalletController>();
});
......
using System;
using NBitcoin;
using Newtonsoft.Json;
using Breeze.Wallet.JsonConverters;
namespace Breeze.Wallet
{
/// <summary>
/// An object representing a wallet on a local file system.
/// </summary>
public class WalletFile
{
/// <summary>
/// The seed for this wallet, password encrypted.
/// </summary>
[JsonProperty(PropertyName = "encryptedSeed")]
public string EncryptedSeed { get; set; }
/// <summary>
/// The chain code.
/// </summary>
[JsonProperty(PropertyName = "chainCode")]
[JsonConverter(typeof(ByteArrayConverter))]
public byte[] ChainCode { get; set; }
/// <summary>
/// The network this wallet is for.
/// </summary>
[JsonProperty(PropertyName = "network")]
[JsonConverter(typeof(NetworkConverter))]
public Network Network { get; set; }
/// <summary>
/// The time this wallet was created.
/// </summary>
[JsonProperty(PropertyName = "creationTime")]
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset CreationTime { get; set; }
}
}
using System;
using System.Collections.Generic;
using Breeze.Wallet.JsonConverters;
using NBitcoin;
using Newtonsoft.Json;
namespace Breeze.Wallet
{
/// <summary>
/// Represents the root of the user's wallet's addresses and transactions.
/// </summary>
public class WalletHierarchy
{
/// <summary>
/// The type of coin, Bitcoin or Stratis.
/// </summary>
[JsonProperty(PropertyName = "coinType")]
public CoinType CoinType { get; set; }
/// <summary>
/// The accounts used in the wallet.
/// </summary>
[JsonProperty(PropertyName = "accounts")]
public IEnumerable<HdAccount> Accounts { get; set; }
}
/// <summary>
/// The type of coin, as specified in BIP44.
/// </summary>
public enum CoinType
{
Bitcoin = 0,
Stratis = 105
}
/// <summary>
/// An Hd account's details.
/// </summary>
public class HdAccount
{
/// <summary>
/// The index of the account.
/// </summary>
/// <remarks>
/// According to BIP44, an account at index (i) can only be created when the account
/// at index (i - 1) contains transactions.
/// </remarks>
[JsonProperty(PropertyName = "index")]
public int Index { get; set; }
/// <summary>
/// The list of external addresses, typically used for receiving money.
/// </summary>
[JsonProperty(PropertyName = "externalAddresses")]
public IEnumerable<HdAddress> ExternalAddresses { get; set; }
/// <summary>
/// The list of internal addresses, typically used to receive change.
/// </summary>
[JsonProperty(PropertyName = "internalAddresses")]
public IEnumerable<HdAddress> InternalAddresses { get; set; }
}
/// <summary>
/// An Hd address.
/// </summary>
public class HdAddress
{
/// <summary>
/// Gets or sets the creation time.
/// </summary>
[JsonProperty(PropertyName = "creationTime")]
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset CreationTime { get; set; }
/// <summary>
/// The script pub key for this address.
/// </summary>
[JsonProperty(PropertyName = "scriptPubKey")]
public Script ScriptPubKey { get; set; }
/// <summary>
/// The Base58 representation of this address.
/// </summary>
[JsonProperty(PropertyName = "address")]
public BitcoinAddress Address { get; set; }
/// <summary>
/// A path to the address as defined in BIP44.
/// </summary>
[JsonProperty(PropertyName = "hdPath")]
public string HdPath { get; set; }
/// <summary>
/// A list detailing which blocks have been scanned for this address.
/// </summary>
[JsonIgnore]
public SortedList<int, int> BlocksScanned { get; set; }
/// <summary>
/// A list of transactions involving this address.
/// </summary>
[JsonProperty(PropertyName = "transactions")]
public IEnumerable<TransactionData> Transactions { get; set; }
}
/// <summary>
/// An object containing transaction data.
/// </summary>
public class TransactionData
{
/// <summary>
/// Transaction id.
/// </summary>
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
/// <summary>
/// The transaction amount.
/// </summary>
[JsonProperty(PropertyName = "amount")]
public Money Amount { get; set; }
/// <summary>
/// The height of the block including this transaction.
/// </summary>
[JsonProperty(PropertyName = "blockHeight")]
public int BlockHeight { get; set; }
/// <summary>
/// Whether this transaction has been confirmed or not.
/// </summary>
[JsonProperty(PropertyName = "confirmed")]
public bool Confirmed { get; set; }
/// <summary>
/// Gets or sets the creation time.
/// </summary>
[JsonProperty(PropertyName = "creationTime")]
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset CreationTime { get; set; }
}
}
......@@ -19,8 +19,7 @@ namespace Breeze.Wallet
ExtKey extendedKey = mnemonic.DeriveExtKey(passphrase);
// create a wallet file
this.GenerateWalletFile(password, walletFilePath, network, extendedKey);
Wallet wallet = this.GenerateWalletFile(password, walletFilePath, network, extendedKey);
return mnemonic;
}
......@@ -31,21 +30,7 @@ namespace Breeze.Wallet
throw new FileNotFoundException($"No wallet file found at {walletFilePath}");
// load the file from the local system
WalletFile walletFile = JsonConvert.DeserializeObject<WalletFile>(File.ReadAllText(walletFilePath));
// decrypt the private key and use it to regenerate the seed
var privateKey = Key.Parse(walletFile.EncryptedSeed, password, walletFile.Network);
var seedExtKey = new ExtKey(privateKey, walletFile.ChainCode);
Wallet wallet = new Wallet
{
ChainCode = walletFile.ChainCode,
CreationTime = walletFile.CreationTime,
Network = walletFile.Network,
WalletFilePath = walletFilePath,
ExtendedKey = seedExtKey
};
Wallet wallet = JsonConvert.DeserializeObject<Wallet>(File.ReadAllText(walletFilePath));
return wallet;
}
......@@ -56,17 +41,7 @@ namespace Breeze.Wallet
ExtKey extendedKey = mnemonic.DeriveExtKey(passphrase);
// create a wallet file
WalletFile walletFile = this.GenerateWalletFile(password, walletFilePath, network, extendedKey, creationTime);
Wallet wallet = new Wallet
{
ChainCode = walletFile.ChainCode,
CreationTime = walletFile.CreationTime,
Network = walletFile.Network,
WalletFilePath = walletFilePath,
ExtendedKey = extendedKey
};
Wallet wallet = this.GenerateWalletFile(password, walletFilePath, network, extendedKey, creationTime);
return wallet;
}
......@@ -92,12 +67,12 @@ namespace Breeze.Wallet
/// <param name="creationTime">The time this wallet was created.</param>
/// <returns></returns>
/// <exception cref="System.NotSupportedException"></exception>
private WalletFile GenerateWalletFile(string password, string walletFilePath, Network network, ExtKey extendedKey, DateTimeOffset? creationTime = null)
private Wallet GenerateWalletFile(string password, string walletFilePath, Network network, ExtKey extendedKey, DateTimeOffset? creationTime = null)
{
if (File.Exists(walletFilePath))
throw new InvalidOperationException($"Wallet already exists at {walletFilePath}");
WalletFile walletFile = new WalletFile
Wallet walletFile = new Wallet
{
EncryptedSeed = extendedKey.PrivateKey.GetEncryptedBitcoinSecret(password, network).ToWif(),
ChainCode = extendedKey.ChainCode,
......
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