From e4eb95fb9cfbae3596deb310984fa18462d1b30c Mon Sep 17 00:00:00 2001 From: Alekos Filini Date: Wed, 13 Apr 2022 12:37:27 +0200 Subject: [PATCH] [keys] Implement `DerivableKey` for `(GeneratedKey, Option)` This lets us use a tuple of (generated mnemonic, optional passphrase) as a `DerivableKey` directly, without extracting the inner mnemonic from the `GeneratedKey` wrapper. For BIP39 keys specifically it doesn't make much difference because the mnemonic format doesn't encode the network, but in general this is not the case and having a consistent API will make it harder for people to make mistakes. To explain why we should not extract the key: some key formats (like BIP32 extended keys) are network-specific, meaning that if somebody tries to use a Testnet key on a Mainnet BDK wallet, it won't work. However, when we generate a new key we would like to be able to use that key on any network, but we need to set some kind of placeholder for the `network` field in the structure. This is why (or at least one of the reasons why) we wrap the key in the `GeneratedKey` struct: we keep track of the "valid_networks" separately, which means that even if we set our BIP32 xprv to be a "Mainnet" key, once we go try creating a wallet with that key BDK is smart enough to understand that `GeneratedKey`s have their own separate set of valid networks and it will use that set to validate whether the key can be used in the wallet or not. --- src/keys/bip39.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/keys/bip39.rs b/src/keys/bip39.rs index c6cf24fd..a8902a9f 100644 --- a/src/keys/bip39.rs +++ b/src/keys/bip39.rs @@ -94,6 +94,23 @@ impl DerivableKey for MnemonicWithPassphrase { } } +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))] +impl DerivableKey for (GeneratedKey, Option) { + fn into_extended_key(self) -> Result, KeyError> { + let (mnemonic, passphrase) = self; + (mnemonic.into_key(), passphrase).into_extended_key() + } + + fn into_descriptor_key( + self, + source: Option, + derivation_path: bip32::DerivationPath, + ) -> Result, KeyError> { + let (mnemonic, passphrase) = self; + (mnemonic.into_key(), passphrase).into_descriptor_key(source, derivation_path) + } +} + #[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))] impl DerivableKey for Mnemonic { fn into_extended_key(self) -> Result, KeyError> {