Trait bdk::keys::DerivableKey

source ·
pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;

    fn into_descriptor_key(
        self,
        origin: Option<KeySource>,
        derivation_path: DerivationPath
    ) -> Result<DescriptorKey<Ctx>, KeyError> { ... } }
Expand description

Trait for keys that can be derived.

When extra metadata are provided, a DerivableKey can be transformed into a DescriptorKey: the trait IntoDescriptorKey is automatically implemented for (DerivableKey, DerivationPath) and (DerivableKey, KeySource, DerivationPath) tuples.

For key types that don’t encode any indication about the path to use (like bip39), it’s generally recommended to implement this trait instead of IntoDescriptorKey. The same rules regarding script context and valid networks apply.

Examples

Key types that can be directly converted into an Xpriv or an Xpub can implement only the required into_extended_key() method.

use bdk::bitcoin;
use bdk::bitcoin::bip32;
use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};

struct MyCustomKeyType {
    key_data: bitcoin::PrivateKey,
    chain_code: [u8; 32],
    network: bitcoin::Network,
}

impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
        let xprv = bip32::Xpriv {
            network: self.network,
            depth: 0,
            parent_fingerprint: bip32::Fingerprint::default(),
            private_key: self.key_data.inner,
            chain_code: bip32::ChainCode::from(&self.chain_code),
            child_number: bip32::ChildNumber::Normal { index: 0 },
        };

        xprv.into_extended_key()
    }
}

Types that don’t internally encode the [Network] in which they are valid need some extra steps to override the set of valid networks, otherwise only the network specified in the Xpriv or Xpub will be considered valid.

use bdk::bitcoin;
use bdk::bitcoin::bip32;
use bdk::keys::{
    any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
};

struct MyCustomKeyType {
    key_data: bitcoin::PrivateKey,
    chain_code: [u8; 32],
}

impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
        let xprv = bip32::Xpriv {
            network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
            depth: 0,
            parent_fingerprint: bip32::Fingerprint::default(),
            private_key: self.key_data.inner,
            chain_code: bip32::ChainCode::from(&self.chain_code),
            child_number: bip32::ChildNumber::Normal { index: 0 },
        };

        xprv.into_extended_key()
    }

    fn into_descriptor_key(
        self,
        source: Option<bip32::KeySource>,
        derivation_path: bip32::DerivationPath,
    ) -> Result<DescriptorKey<Ctx>, KeyError> {
        let descriptor_key = self
            .into_extended_key()?
            .into_descriptor_key(source, derivation_path)?;

        // Override the set of valid networks here
        Ok(descriptor_key.override_valid_networks(any_network()))
    }
}

Required Methods§

Consume self and turn it into an ExtendedKey

Provided Methods§

Consume self and turn it into a DescriptorKey by adding the extra metadata, such as key origin and derivation path

Implementations on Foreign Types§

Implementors§

Identity conversion