public static IEnumerable <ExtendedKeyDerivation> Derive(ExtendedKey masterKey, IEnumerable <ExtendedKeyPath> pathItems) { Guard.Require(masterKey.Depth == 0); // calculate the child keys based on the path items return(from keyPath in pathItems let iterator = masterKey let keyIetrator = keyPath.Items.Aggregate(iterator, (current, item) => current.GetChild(item)) select new ExtendedKeyDerivation { ExtendedKey = keyIetrator, PathItem = keyPath }); }
public static ExtendedKeyPathBip44 CreateBip44(uint coinIndex, uint accountIndex = 0) { var keyPath = new ExtendedKeyPathBip44 { Items = new List <uint>() }; //// populate the items according to the BIP44 path //// [m/purpose'/coin_type'/account'/change/address_index] keyPath.Items.Add(ExtendedKey.ToHadrendIndex(44)); keyPath.Items.Add(ExtendedKey.ToHadrendIndex(coinIndex)); keyPath.Items.Add(ExtendedKey.ToHadrendIndex(accountIndex)); return(keyPath); }
public override string ToString() { var builder = new StringBuilder(); builder.Append("m/"); this.Items.Aggregate( builder, (current, item) => current.Append("{0}{1}/".StringFormat( ExtendedKey.IsHardendIndex(item) ? ExtendedKey.FromHadrendIndex(item) : item, ExtendedKey.IsHardendIndex(item) ? "'" : string.Empty))); return(builder.ToString().TrimEnd("/".ToCharArray())); }
public static ExtendedKeyPathBip44 ParseBip44(string path) { Guard.Require(path.StartsWith("m/")); var keyPath = new ExtendedKeyPathBip44 { Path = path, Items = path.Substring(2).Split('/').Select(ConvertPathItem).ToList() }; Guard.Require(keyPath.Index(0) == ExtendedKey.ToHadrendIndex(44)); Guard.Require(keyPath.IsHardendIndex(1)); Guard.Require(keyPath.IsHardendIndex(2)); return(keyPath); }
public static IEnumerable <BitcoinPublicKey> DeriveBip44Account(ExtendedKey extKey, IEnumerable <ExtendedKeyPathBip44> pathItems) { Guard.Require(extKey.Depth == 3); Guard.Require(extKey.IsHardened); //// the pub key we received should be [m/44'/coin-index'/account'] //// to support multi account wallets we store the account level pub key foreach (var pathItem in pathItems) { Guard.Require(extKey.Index == ExtendedKey.ToHadrendIndex(pathItem.AccountIndex)); //// use the chain index and address index to generate the key //// this will yield a public key [m/44'/coin-index'/account'/chain/index] var derrivedKey = extKey.GetChild(pathItem.ChangeIndex).GetKey(pathItem.AddressIndex).PublicKey; yield return(derrivedKey); } }
protected static uint ConvertPathItem(string item) { return(item.Contains("'") ? ExtendedKey.ToHadrendIndex(uint.Parse(item.TrimEnd("'".ToCharArray()))) : uint.Parse(item)); }
public bool IsHardendIndex(int index) { return(ExtendedKey.IsHardendIndex(this.Items.ElementAt(index))); }