Example #1
0
        /// <summary>
        /// Create an account for a specific account index and account name pattern.
        /// </summary>
        /// <param name="password">The password used to decrypt the wallet's encrypted seed.</param>
        /// <param name="encryptedSeed">The encrypted private key for this wallet.</param>
        /// <param name="chainCode">The chain code for this wallet.</param>
        /// <param name="network">The network for which this account will be created.</param>
        /// <param name="accountCreationTime">Creation time of the account to be created.</param>
        /// <param name="newAccountIndex">The optional account index to use.</param>
        /// <param name="newAccountName">The optional account name to use.</param>
        /// <returns>A new HD account.</returns>
        public HdAccount CreateAccount(string password, string encryptedSeed, byte[] chainCode,
                                       Network network, DateTimeOffset accountCreationTime,
                                       int newAccountIndex, string newAccountName = null)
        {
            if (string.IsNullOrEmpty(newAccountName))
            {
                newAccountName = string.Format(Wallet.AccountNamePattern, newAccountIndex);
            }

            // Get the extended pub key used to generate addresses for this account.
            string    accountHdPath    = HdOperations.GetAccountHdPath((int)this.CoinType, newAccountIndex);
            Key       privateKey       = HdOperations.DecryptSeed(encryptedSeed, password, network);
            ExtPubKey accountExtPubKey = HdOperations.GetExtendedPublicKey(privateKey, chainCode, accountHdPath);

            return(new HdAccount
            {
                Index = newAccountIndex,
                ExtendedPubKey = accountExtPubKey.ToString(network),
                ExternalAddresses = new List <HdAddress>(),
                InternalAddresses = new List <HdAddress>(),
                Name = newAccountName,
                HdPath = accountHdPath,
                CreationTime = accountCreationTime
            });
        }
Example #2
0
        /// <inheritdoc cref="AddNewAccount(string, string, byte[], Network, DateTimeOffset)"/>
        /// <summary>
        /// Adds an account to the current account root using extended public key and account index.
        /// </summary>
        /// <param name="accountExtPubKey">The extended public key for the account.</param>
        /// <param name="accountIndex">The zero-based account index.</param>
        public HdAccount AddNewAccount(ExtPubKey accountExtPubKey, int accountIndex, Network network, DateTimeOffset accountCreationTime)
        {
            ICollection <HdAccount> hdAccounts = this.Accounts.ToList();

            if (hdAccounts.Any(a => a.Index == accountIndex))
            {
                throw new WalletException("There is already an account in this wallet with index: " + accountIndex);
            }

            if (hdAccounts.Any(x => x.ExtendedPubKey == accountExtPubKey.ToString(network)))
            {
                throw new WalletException("There is already an account in this wallet with this xpubkey: " +
                                          accountExtPubKey.ToString(network));
            }

            string accountHdPath = HdOperations.GetAccountHdPath((int)this.CoinType, accountIndex);

            var newAccount = new HdAccount
            {
                Index             = accountIndex,
                ExtendedPubKey    = accountExtPubKey.ToString(network),
                ExternalAddresses = new List <HdAddress>(),
                InternalAddresses = new List <HdAddress>(),
                Name         = $"account {accountIndex}",
                HdPath       = accountHdPath,
                CreationTime = accountCreationTime
            };

            hdAccounts.Add(newAccount);
            this.Accounts = hdAccounts;

            return(newAccount);
        }
Example #3
0
        public void pubKeysDerivedFromExtendedPrivateAndPublicKeysMatch()
        {
            string password   = "******";
            string passphrase = password;

            string mnemonic = "chalk call anger chase endless level slow sleep coast left sand enter save bind curious puzzle stadium volume mixture shuffle hurry gas borrow believe";

            ExtKey extendedKey = HdOperations.GetExtendedKey(mnemonic, passphrase);

            string encryptedSeed = extendedKey.PrivateKey.GetEncryptedBitcoinSecret(password, this.Network).ToWif();
            Key    privateKey    = HdOperations.DecryptSeed(encryptedSeed, password, this.Network);

            string accountHdPath = HdOperations.GetAccountHdPath(COINTYPE, 0);
            string path          = HdOperations.CreateHdPath(COINTYPE, 0, false, 0);

            ExtPubKey accountExtPubKey = HdOperations.GetExtendedPublicKey(privateKey, extendedKey.ChainCode, accountHdPath);
            var       subjectPubKey    = HdOperations.GeneratePublicKey(accountExtPubKey.ToString(this.Network), 0, false, this.Network);

            var subjectPrivKey = HdOperations.GetExtendedPrivateKey(privateKey, extendedKey.ChainCode, path, this.Network);

            Assert.Equal(subjectPubKey.ScriptPubKey, subjectPrivKey.PrivateKey.PubKey.ScriptPubKey);
        }