HD keys
HDPrivateKey and HDPublicKey implement BIP32 hierarchical deterministic keys. One seed yields an entire
tree of keys, each addressed by a path such as m/44'/236'/0'/0/5. The guide’s
HD keys page explains the scheme. The examples here use the BIP32 test
vectors, so that you can check the outputs against the specification.
A master key from a seed
Section titled “A master key from a seed”The seed is given as hex. In practice it will come from a mnemonic.
final master = HDPrivateKey.fromSeed('000102030405060708090a0b0c0d0e0f', NetworkType.MAIN);
master.xprivkey; // xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHimaster.xpubkey; // xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8Deriving along a path
Section titled “Deriving along a path”deriveChildKey takes a path, in which an apostrophe marks a hardened step. deriveChildNumber(i) derives a
single non-hardened step.
// An apostrophe marks a hardened step.final child = master.deriveChildKey("m/0'/1/2'/2/1000000000");Please note that
deriveChildNumberaccepts only non-hardened indexes. Passing0x80000000or above throws anIllegalArgumentException. Use a path ("m/0'") for hardened steps.
Restoring a key and signing with it
Section titled “Restoring a key and signing with it”HDPrivateKey.fromXpriv restores a key from its xprv string. It should be noted that HD keys only derive. To
sign a Transaction or a message, or to get an Address, we take the privateKey (an SVPrivateKey) of the
derived node.
final account = HDPrivateKey.fromXpriv( 'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7');
// HD keys only derive. Transactions, messages and Addresses take an SVPrivateKey.final SVPrivateKey signingKey = account.deriveChildKey('m/0/0').privateKey;final address = signingKey.toAddress(networkType: NetworkType.MAIN);Watch-only wallets with an xpub
Section titled “Watch-only wallets with an xpub”An extended Public Key derives the public half of the tree. A server that holds only the account xpub can
generate fresh receiving Addresses, but only the wallet holding the xprv can spend from them.
// We give a server the account xpub. It can derive receiving Addresses without any Private Key.final String accountXpub = account.xpubkey;
final watchOnly = HDPublicKey.fromXpub(accountXpub);final receiving = watchOnly.deriveChildKey('m/0/5').publicKey.toAddress(NetworkType.MAIN);
// The wallet holding the xprv derives the same Address, and can sign for it.final sameAddress = account.deriveChildKey('m/0/5').privateKey.toAddress(networkType: NetworkType.MAIN);Hardened children cannot be derived from an xpub:
try { xpub.deriveChildKey("m/0'");} on DerivationException { // an xpub can only follow non-hardened steps}Testnet extended keys
Section titled “Testnet extended keys”The network we pass to fromSeed selects the tprv/tpub prefixes, and the derived SVPrivateKey carries
that same network.
final master = HDPrivateKey.fromSeed('000102030405060708090a0b0c0d0e0f', NetworkType.TEST);master.xprivkey; // tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m
final key = master.deriveChildKey("m/0'").privateKey;key.toWIF(); // a testnet WIF (starts with c)
