Trait bdk_wallet::keys::IntoDescriptorKey

source ·
pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    // Required method
    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
}
Expand description

Trait for objects that can be turned into a public or secret DescriptorKey

The generic type Ctx is used to define the context in which the key is valid: some key formats, like the mnemonics used by Electrum wallets, encode internally whether the wallet is legacy or segwit. Thus, trying to turn a valid legacy mnemonic into a DescriptorKey that would become part of a segwit descriptor should fail.

For key types that do care about this, the ExtScriptContext trait provides some useful methods that can be used to check at runtime which Ctx is being used.

For key types that can do this check statically (because they can only work within a single Ctx), the “specialized” trait can be implemented to make the compiler handle the type checking.

Keys also have control over the networks they support: constructing the return object with DescriptorKey::from_public or DescriptorKey::from_secret allows to specify a set of ValidNetworks.

§Examples

Key type valid in any context:

use bdk_wallet::bitcoin::PublicKey;

use bdk_wallet::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};

pub struct MyKeyType {
    pubkey: PublicKey,
}

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
        self.pubkey.into_descriptor_key()
    }
}

Key type that is only valid on mainnet:

use bdk_wallet::bitcoin::PublicKey;

use bdk_wallet::keys::{
    mainnet_network, DescriptorKey, DescriptorPublicKey, IntoDescriptorKey, KeyError,
    ScriptContext, SinglePub, SinglePubKey,
};

pub struct MyKeyType {
    pubkey: PublicKey,
}

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
        Ok(DescriptorKey::from_public(
            DescriptorPublicKey::Single(SinglePub {
                origin: None,
                key: SinglePubKey::FullKey(self.pubkey),
            }),
            mainnet_network(),
        ))
    }
}

Key type that internally encodes in which context it’s valid. The context is checked at runtime:

use bdk_wallet::bitcoin::PublicKey;

use bdk_wallet::keys::{
    DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext,
};

pub struct MyKeyType {
    is_legacy: bool,
    pubkey: PublicKey,
}

impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
        if Ctx::is_legacy() == self.is_legacy {
            self.pubkey.into_descriptor_key()
        } else {
            Err(KeyError::InvalidScriptContext)
        }
    }
}

Key type that can only work within miniscript::Segwitv0 context. Only the specialized version of the trait is implemented.

This example deliberately fails to compile, to demonstrate how the compiler can catch when keys are misused. In this case, the “segwit-only” key is used to build a pkh() descriptor, which makes the compiler (correctly) fail.

use bdk_wallet::bitcoin::PublicKey;
use core::str::FromStr;

use bdk_wallet::keys::{DescriptorKey, IntoDescriptorKey, KeyError};

pub struct MySegwitOnlyKeyType {
    pubkey: PublicKey,
}

impl IntoDescriptorKey<bdk_wallet::miniscript::Segwitv0> for MySegwitOnlyKeyType {
    fn into_descriptor_key(self) -> Result<DescriptorKey<bdk_wallet::miniscript::Segwitv0>, KeyError> {
        self.pubkey.into_descriptor_key()
    }
}

let key = MySegwitOnlyKeyType {
    pubkey: PublicKey::from_str("...")?,
};
let (descriptor, _, _) = bdk_wallet::descriptor!(pkh(key))?;
//                                               ^^^^^ changing this to `wpkh` would make it compile

Required Methods§

source

fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

Turn the key into a DescriptorKey within the requested ScriptContext

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &str

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey

source§

impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, DerivationPath)

source§

impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, KeySource, DerivationPath)

Implementors§

source§

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

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx>

The “identity” conversion is used internally by some bdk_wallet::fragments

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

source§

impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey