Skip to content

Commit 5ad23ae

Browse files
sanket1729SarcasticNastik
authored andcommitted
Add simple API for derivation
1 parent da34f9e commit 5ad23ae

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/descriptor/mod.rs

+38
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,48 @@ impl Descriptor<DescriptorPublicKey> {
557557
/// Derives all wildcard keys in the descriptor using the supplied index
558558
///
559559
/// Panics if given an index ≥ 2^31
560+
///
561+
/// In most cases, you would want to use [`Self::derived_descriptor`] directly to obtain
562+
/// a [`Descriptor<bitcoin::PublicKey>`]
560563
pub fn derive(&self, index: u32) -> Descriptor<DescriptorPublicKey> {
561564
self.translate_pk2_infallible(|pk| pk.clone().derive(index))
562565
}
563566

567+
/// Derive a [`Descriptor`] with a concrete [`bitcoin::PublicKey`] at a given index
568+
/// Removes all extended pubkeys and wildcards from the descriptor and only leaves
569+
/// concrete [`bitcoin::PublicKey`]. All [`crate::XOnlyKey`]s are converted to [`bitcoin::PublicKey`]
570+
/// by adding a default(0x02) y-coordinate. For [`crate::descriptor::Tr`] descriptor,
571+
/// spend info is also cached.
572+
///
573+
/// # Examples
574+
///
575+
/// ```
576+
/// use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
577+
/// use miniscript::bitcoin::secp256k1;
578+
/// use std::str::FromStr;
579+
///
580+
/// // test from bip 86
581+
/// let secp = secp256k1::Secp256k1::verification_only();
582+
/// let descriptor = Descriptor::<DescriptorPublicKey>::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
583+
/// .expect("Valid ranged descriptor");
584+
/// let result = descriptor.derived_descriptor(0, &secp).expect("Non-hardened derivation");
585+
/// assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym");
586+
/// ```
587+
///
588+
/// # Errors
589+
///
590+
/// This function will return an error if hardened derivation is attempted.
591+
pub fn derived_descriptor<C: secp256k1::Verification>(
592+
&self,
593+
index: u32,
594+
secp: &secp256k1::Secp256k1<C>,
595+
) -> Result<Descriptor<bitcoin::PublicKey>, ConversionError> {
596+
let derived = self
597+
.derive(index)
598+
.translate_pk2(|xpk| xpk.derive_public_key(secp))?;
599+
Ok(derived)
600+
}
601+
564602
/// Parse a descriptor that may contain secret keys
565603
///
566604
/// Internally turns every secret key found into the corresponding public key and then returns a

0 commit comments

Comments
 (0)