Skip to content

Commit b170a01

Browse files
committed
[descriptor] Expose utilities to deal with derived descriptors
1 parent c84790f commit b170a01

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

src/descriptor/derived.rs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,41 @@
1010
// licenses.
1111

1212
//! Derived descriptor keys
13+
//!
14+
//! The [`DerivedDescriptorKey`] type is a wrapper over the standard [`DescriptorPublicKey`] which
15+
//! guarantees that all the extended keys have a fixed derivation path, i.e. all the wildcards have
16+
//! been replaced by actual derivation indexes.
17+
//!
18+
//! The [`AsDerived`] trait provides a quick way to derive descriptors to obtain a
19+
//! `Descriptor<DerivedDescriptorKey>` type. This, in turn, can be used to derive public
20+
//! keys for arbitrary derivation indexes.
21+
//!
22+
//! Combining this with [`Wallet::get_signers`], secret keys can also be derived.
23+
//!
24+
//! # Example
25+
//!
26+
//! ```
27+
//! # use std::str::FromStr;
28+
//! # use bitcoin::secp256k1::Secp256k1;
29+
//! use bdk::descriptor::{AsDerived, DescriptorPublicKey};
30+
//! use bdk::miniscript::{ToPublicKey, TranslatePk, MiniscriptKey};
31+
//!
32+
//! let secp = Secp256k1::gen_new();
33+
//!
34+
//! let key = DescriptorPublicKey::from_str("[aa600a45/84'/0'/0']tpubDCbDXFKoLTQp44wQuC12JgSn5g9CWGjZdpBHeTqyypZ4VvgYjTJmK9CkyR5bFvG9f4PutvwmvpYCLkFx2rpx25hiMs4sUgxJveW8ZzSAVAc/0/*")?;
35+
//! let (descriptor, _, _) = bdk::descriptor!(wpkh(key))?;
36+
//!
37+
//! // derived: wpkh([aa600a45/84'/0'/0']tpubDCbDXFKoLTQp44wQuC12JgSn5g9CWGjZdpBHeTqyypZ4VvgYjTJmK9CkyR5bFvG9f4PutvwmvpYCLkFx2rpx25hiMs4sUgxJveW8ZzSAVAc/0/42)#3ladd0t2
38+
//! let derived = descriptor.as_derived(42, &secp);
39+
//! println!("derived: {}", derived);
40+
//!
41+
//! // with_pks: wpkh(02373ecb54c5e83bd7e0d40adf78b65efaf12fafb13571f0261fc90364eee22e1e)#p4jjgvll
42+
//! let with_pks = derived.translate_pk_infallible(|pk| pk.to_public_key(), |pkh| pkh.to_public_key().to_pubkeyhash());
43+
//! println!("with_pks: {}", with_pks);
44+
//! # Ok::<(), Box<dyn std::error::Error>>(())
45+
//! ```
46+
//!
47+
//! [`Wallet::get_signers`]: crate::wallet::Wallet::get_signers
1348
1449
use std::cmp::Ordering;
1550
use std::fmt;
@@ -19,10 +54,7 @@ use std::ops::Deref;
1954
use bitcoin::hashes::hash160;
2055
use bitcoin::PublicKey;
2156

22-
pub use miniscript::{
23-
descriptor::KeyMap, descriptor::Wildcard, Descriptor, DescriptorPublicKey, Legacy, Miniscript,
24-
ScriptContext, Segwitv0,
25-
};
57+
use miniscript::{descriptor::Wildcard, Descriptor, DescriptorPublicKey};
2658
use miniscript::{MiniscriptKey, ToPublicKey, TranslatePk};
2759

2860
use crate::wallet::utils::SecpCtx;
@@ -119,14 +151,19 @@ impl<'s> ToPublicKey for DerivedDescriptorKey<'s> {
119151
}
120152
}
121153

122-
pub(crate) trait AsDerived {
123-
// Derive a descriptor and transform all of its keys to `DerivedDescriptorKey`
154+
/// Utilities to derive descriptors
155+
///
156+
/// Check out the [module level] documentation for more.
157+
///
158+
/// [module level]: crate::descriptor::derived
159+
pub trait AsDerived {
160+
/// Derive a descriptor and transform all of its keys to `DerivedDescriptorKey`
124161
fn as_derived<'s>(&self, index: u32, secp: &'s SecpCtx)
125162
-> Descriptor<DerivedDescriptorKey<'s>>;
126163

127-
// Transform the keys into `DerivedDescriptorKey`.
128-
//
129-
// Panics if the descriptor is not "fixed", i.e. if it's derivable
164+
/// Transform the keys into `DerivedDescriptorKey`.
165+
///
166+
/// Panics if the descriptor is not "fixed", i.e. if it's derivable
130167
fn as_derived_fixed<'s>(&self, secp: &'s SecpCtx) -> Descriptor<DerivedDescriptorKey<'s>>;
131168
}
132169

src/descriptor/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,25 @@ use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerpr
2121
use bitcoin::util::psbt;
2222
use bitcoin::{Network, PublicKey, Script, TxOut};
2323

24-
use miniscript::descriptor::{
25-
DescriptorPublicKey, DescriptorType, DescriptorXKey, InnerXKey, Wildcard,
24+
use miniscript::descriptor::{DescriptorType, InnerXKey};
25+
pub use miniscript::{
26+
descriptor::DescriptorXKey, descriptor::KeyMap, descriptor::Wildcard, Descriptor,
27+
DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
2628
};
27-
pub use miniscript::{descriptor::KeyMap, Descriptor, Legacy, Miniscript, ScriptContext, Segwitv0};
2829
use miniscript::{DescriptorTrait, ForEachKey, TranslatePk};
2930

3031
use crate::descriptor::policy::BuildSatisfaction;
3132

3233
pub mod checksum;
33-
pub(crate) mod derived;
34+
pub mod derived;
3435
#[doc(hidden)]
3536
pub mod dsl;
3637
pub mod error;
3738
pub mod policy;
3839
pub mod template;
3940

4041
pub use self::checksum::get_checksum;
41-
use self::derived::AsDerived;
42-
pub use self::derived::DerivedDescriptorKey;
42+
pub use self::derived::{AsDerived, DerivedDescriptorKey};
4343
pub use self::error::Error as DescriptorError;
4444
pub use self::policy::Policy;
4545
use self::template::DescriptorTemplateOut;

0 commit comments

Comments
 (0)