Exemple #1
0
        public void TrySign(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath, SigHash sigHash = SigHash.All)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (accountHDScriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(accountHDScriptPubKey));
            }
            var cache = accountKey.AsHDKeyCache();

            accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
            foreach (var hdk in this.HDKeysFor(accountHDScriptPubKey, cache, accountKeyPath))
            {
                if (((HDKeyCache)cache.Derive(hdk.AddressKeyPath)).Inner is ISecret k)
                {
                    Sign(k.PrivateKey, sigHash);
                }
                else
                {
                    throw new ArgumentException(paramName: nameof(accountKey), message: "This should be a private key");
                }
            }
        }
Exemple #2
0
 /// <summary>
 /// Deriving an IHDScriptPubKey is normally time consuming, this wrap the IHDScriptPubKey in a new IHDScriptPubKey object which can cache derivations
 /// </summary>
 /// <param name="hdScriptPubKey">The hdScriptPubKey to wrap</param>
 /// <returns>An hdkey which cache derivations, of the parameter if it is already itself a cache</returns>
 public static IHDScriptPubKey AsHDKeyCache(this IHDScriptPubKey hdScriptPubKey)
 {
     if (hdScriptPubKey == null)
     {
         throw new ArgumentNullException(nameof(hdScriptPubKey));
     }
     if (hdScriptPubKey is HDScriptPubKeyCache c)
     {
         return(c);
     }
     return(new HDScriptPubKeyCache(hdScriptPubKey));
 }
 /// <summary>
 /// Filter the keys which contains the <paramref name="accountKey"/> and <paramref name="accountKeyPath"/> in the HDKeys and whose input/output
 /// the same scriptPubKeys as <paramref name="accountHDScriptPubKey"/>.
 /// </summary>
 /// <param name="accountHDScriptPubKey">The hdScriptPubKey used to generate addresses</param>
 /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
 /// <param name="accountKeyPath">The account key path</param>
 /// <returns>HD Keys matching master root key</returns>
 public IEnumerable <PSBTHDKeyMatch> HDKeysFor(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     if (accountKey == null)
     {
         throw new ArgumentNullException(nameof(accountKey));
     }
     if (accountHDScriptPubKey == null)
     {
         throw new ArgumentNullException(nameof(accountHDScriptPubKey));
     }
     accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
     accountKey            = accountKey.AsHDKeyCache();
     return(Inputs.HDKeysFor(accountHDScriptPubKey, accountKey, accountKeyPath).OfType <PSBTHDKeyMatch>().Concat(Outputs.HDKeysFor(accountHDScriptPubKey, accountKey, accountKeyPath)));
 }
Exemple #4
0
        internal IEnumerable <PSBTHDKeyMatch <T> > GetHDKeys(IHDScriptPubKey hdScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            accountKey     = accountKey.AsHDKeyCache();
            hdScriptPubKey = hdScriptPubKey?.AsHDKeyCache();
            var accountFingerprint = accountKey.GetPublicKey().GetHDFingerPrint();

            foreach (var c in this)
            {
                foreach (var match in c.HDKeysFor(hdScriptPubKey, accountKey, accountKeyPath, accountFingerprint))
                {
                    yield return((PSBTHDKeyMatch <T>)match);
                }
            }
        }
        /// <summary>
        /// Get the balance change if you were signing this transaction.
        /// </summary>
        /// <param name="accountHDScriptPubKey">The hdScriptPubKey used to generate addresses</param>
        /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
        /// <param name="accountKeyPath">The account key path</param>
        /// <returns>The balance change</returns>
        public Money GetBalance(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
        {
            if (accountHDScriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(accountHDScriptPubKey));
            }
            Money total = Money.Zero;

            foreach (var o in CoinsFor(accountHDScriptPubKey, accountKey, accountKeyPath))
            {
                var amount = o.GetCoin()?.Amount;
                if (amount == null)
                {
                    continue;
                }
                total += o is PSBTInput ? -amount : amount;
            }
            return(total);
        }
        /// <summary>
        /// Sign all inputs which derive addresses from <paramref name="accountHDScriptPubKey"/> and that need to be signed by <paramref name="accountKey"/>.
        /// </summary>
        /// <param name="accountHDScriptPubKey">The address generator</param>
        /// <param name="accountKey">The account key with which to sign</param>
        /// <param name="accountKeyPath">The account key path (eg. [masterFP]/49'/0'/0')</param>
        /// <param name="sigHash">The SigHash</param>
        /// <returns>This PSBT</returns>
        public PSBT SignAll(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath, SigHash sigHash = SigHash.All)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (accountHDScriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(accountHDScriptPubKey));
            }
            accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
            accountKey            = accountKey.AsHDKeyCache();
            Money total = Money.Zero;

            foreach (var o in Inputs.CoinsFor(accountHDScriptPubKey, accountKey, accountKeyPath))
            {
                o.TrySign(accountHDScriptPubKey, accountKey, accountKeyPath, sigHash);
            }
            return(this);
        }
Exemple #7
0
 public void TrySign(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, SigHash sigHash = SigHash.All)
 {
     TrySign(accountHDScriptPubKey, accountKey, null, sigHash);
 }
Exemple #8
0
 internal IEnumerable <T> GetPSBTCoins(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     return(GetHDKeys(accountHDScriptPubKey, accountKey, accountKeyPath)
            .Select(c => c.Coin)
            .Distinct());
 }
Exemple #9
0
 /// <summary>
 /// Filter the keys which contains the <paramref name="accountKey"/> and <paramref name="accountKeyPath"/> in the HDKeys and whose input/output
 /// the same scriptPubKeys as <paramref name="accountHDScriptPubKey"/>.
 /// </summary>
 /// <param name="accountHDScriptPubKey">The hdScriptPubKey used to generate addresses</param>
 /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
 /// <param name="accountKeyPath">The account key path</param>
 /// <returns>HD Keys matching master root key</returns>
 public IEnumerable <PSBTHDKeyMatch <T> > HDKeysFor(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     return(GetHDKeys(accountHDScriptPubKey, accountKey, accountKeyPath));
 }
Exemple #10
0
 /// <summary>
 /// Filter the coins which contains the <paramref name="accountKey"/> and <paramref name="accountKeyPath"/> in the HDKeys and derive
 /// the same scriptPubKeys as <paramref name="accountHDScriptPubKey"/>.
 /// </summary>
 /// <param name="accountHDScriptPubKey">The hdScriptPubKey used to generate addresses</param>
 /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
 /// <param name="accountKeyPath">The account key path</param>
 /// <returns>Inputs with HD keys matching masterFingerprint and account key</returns>
 public IEnumerable <T> CoinsFor(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     return(GetPSBTCoins(accountHDScriptPubKey, accountKey, accountKeyPath));
 }
Exemple #11
0
 public void TrySign(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath, SigHash sigHash = SigHash.All)
 {
     TrySign(accountHDScriptPubKey, accountKey, accountKeyPath, Parent.Normalize(new SigningOptions(sigHash)));
 }
 /// <summary>
 /// Sign all inputs which derive addresses from <paramref name="accountHDScriptPubKey"/> and that need to be signed by <paramref name="accountKey"/>.
 /// </summary>
 /// <param name="accountHDScriptPubKey">The address generator</param>
 /// <param name="accountKey">The account key with which to sign</param>
 /// <param name="sigHash">The SigHash</param>
 /// <returns>This PSBT</returns>
 public PSBT SignAll(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, SigHash sigHash = SigHash.All)
 {
     return(SignAll(accountHDScriptPubKey, accountKey, null, sigHash));
 }
Exemple #13
0
 HDScriptPubKeyCache(IHDScriptPubKey hdKey, KeyPath childPath, ConcurrentDictionary <KeyPath, IHDScriptPubKey> cache)
 {
     this.derivationCache = cache;
     _PathFromRoot        = childPath;
     this.hdKey           = hdKey;
 }
Exemple #14
0
 internal HDScriptPubKeyCache(IHDScriptPubKey masterKey)
 {
     this.hdKey      = masterKey;
     _PathFromRoot   = new KeyPath();
     derivationCache = new ConcurrentDictionary <KeyPath, IHDScriptPubKey>();
 }