bdk_wallet::keys

Trait DerivableKey

Source
pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
    // Required method
    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;

    // Provided method
    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_wallet::bitcoin;
use bdk_wallet::bitcoin::bip32;
use bdk_wallet::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.into(),
            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_wallet::bitcoin;
use bdk_wallet::bitcoin::bip32;
use bdk_wallet::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.into(), // 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§

Source

fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>

Consume self and turn it into an ExtendedKey

Provided Methods§

Source

fn into_descriptor_key( self, origin: Option<KeySource>, derivation_path: DerivationPath, ) -> Result<DescriptorKey<Ctx>, KeyError>

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

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpriv

Source§

impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpub

Implementors§

Source§

impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>
where Ctx: ScriptContext, K: DerivableKey<Ctx>,

Source§

impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx>

Identity conversion