diff --git a/examples/xpub_descriptors.rs b/examples/xpub_descriptors.rs index 54f68ba29..64f7d718b 100644 --- a/examples/xpub_descriptors.rs +++ b/examples/xpub_descriptors.rs @@ -18,7 +18,7 @@ use std::str::FromStr; use miniscript::bitcoin::secp256k1::{Secp256k1, Verification}; use miniscript::bitcoin::{Address, Network}; -use miniscript::{Descriptor, DescriptorPublicKey}; +use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; const XPUB_1: &str = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"; const XPUB_2: &str = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"; @@ -40,9 +40,9 @@ fn p2wsh(secp: &Secp256k1) -> Address { let s = format!("wsh(sortedmulti(1,{},{}))", XPUB_1, XPUB_2); // let s = format!("wsh(sortedmulti(1,{},{}))", XPUB_2, XPUB_1); - let address = Descriptor::::from_str(&s) + let address = Descriptor::::from_str(&s) .unwrap() - .derived_descriptor(&secp, 0) // dummy index value if it not a wildcard + .derived_descriptor(&secp) .unwrap() .address(Network::Bitcoin) .unwrap(); diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index c00114321..b12873e81 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -70,14 +70,9 @@ pub enum SinglePubKey { XOnly(XOnlyPublicKey), } -/// A derived [`DescriptorPublicKey`] -/// -/// Derived keys are guaranteed to never contain wildcards +/// A [`DescriptorPublicKey`] without any wildcards. #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)] -pub struct DerivedDescriptorKey { - key: DescriptorPublicKey, - index: u32, -} +pub struct DefiniteDescriptorKey(DescriptorPublicKey); impl fmt::Display for DescriptorSecretKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -357,22 +352,14 @@ impl FromStr for DescriptorPublicKey { /// Descriptor key conversion error #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] pub enum ConversionError { - /// Attempted to convert a key with a wildcard to a bitcoin public key - Wildcard, /// Attempted to convert a key with hardened derivations to a bitcoin public key HardenedChild, - /// Attempted to convert a key with a hardened wildcard to a bitcoin public key - HardenedWildcard, } impl fmt::Display for ConversionError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { - ConversionError::Wildcard => "uninstantiated wildcard in bip32 path", ConversionError::HardenedChild => "hardened child step in bip32 path", - ConversionError::HardenedWildcard => { - "hardened and uninstantiated wildcard in bip32 path" - } }) } } @@ -383,7 +370,7 @@ impl error::Error for ConversionError { use self::ConversionError::*; match self { - Wildcard | HardenedChild | HardenedWildcard => None, + HardenedChild => None, } } } @@ -441,40 +428,50 @@ impl DescriptorPublicKey { } } - /// Whether or not the key has a wildcards + /// Whether or not the key has a wildcard + #[deprecated(note = "use has_wildcard instead")] pub fn is_deriveable(&self) -> bool { + self.has_wildcard() + } + + /// Whether or not the key has a wildcard + pub fn has_wildcard(&self) -> bool { match *self { DescriptorPublicKey::Single(..) => false, DescriptorPublicKey::XPub(ref xpub) => xpub.wildcard != Wildcard::None, } } - /// Derives the [`DescriptorPublicKey`] at `index` if this key is an xpub and has a wildcard. + #[deprecated(note = "use at_derivation_index instead")] + /// Deprecated name of [`at_derivation_index`]. + pub fn derive(self, index: u32) -> DefiniteDescriptorKey { + self.at_derivation_index(index) + } + + /// Replaces any wildcard (i.e. `/*`) in the key with a particular derivation index, turning it into a + /// *definite* key (i.e. one where all the derivation paths are set). /// /// # Returns /// /// - If this key is not an xpub, returns `self`. /// - If this key is an xpub but does not have a wildcard, returns `self`. - /// - Otherwise, returns the derived xpub at `index` (removing the wildcard). - /// - /// Since it's guaranteed that extended keys won't have wildcards, the key is returned as - /// [`DerivedDescriptorKey`]. + /// - Otherwise, returns the xpub at derivation `index` (removing the wildcard). /// /// # Panics /// /// If `index` ≥ 2^31 - pub fn derive(self, index: u32) -> DerivedDescriptorKey { - let derived = match self { + pub fn at_derivation_index(self, index: u32) -> DefiniteDescriptorKey { + let definite = match self { DescriptorPublicKey::Single(_) => self, DescriptorPublicKey::XPub(xpub) => { let derivation_path = match xpub.wildcard { Wildcard::None => xpub.derivation_path, - Wildcard::Unhardened => xpub - .derivation_path - .into_child(bip32::ChildNumber::from_normal_idx(index).unwrap()), - Wildcard::Hardened => xpub - .derivation_path - .into_child(bip32::ChildNumber::from_hardened_idx(index).unwrap()), + Wildcard::Unhardened => xpub.derivation_path.into_child( + bip32::ChildNumber::from_normal_idx(index).expect("index must < 2^31"), + ), + Wildcard::Hardened => xpub.derivation_path.into_child( + bip32::ChildNumber::from_hardened_idx(index).expect("index must < 2^31"), + ), }; DescriptorPublicKey::XPub(DescriptorXKey { origin: xpub.origin, @@ -485,7 +482,7 @@ impl DescriptorPublicKey { } }; - DerivedDescriptorKey::new(derived, index) + DefiniteDescriptorKey::new(definite) .expect("The key should not contain any wildcards at this point") } @@ -494,13 +491,10 @@ impl DescriptorPublicKey { /// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations /// always return a compressed key /// - /// Will return an error if the descriptor key has any hardened - /// derivation steps in its path, or if the key has any wildcards. + /// Will return an error if the descriptor key has any hardened derivation steps in its path. To + /// avoid this error you should replace any such public keys first with [`translate_pk`]. /// - /// To ensure there are no wildcards, call `.derive(0)` or similar; - /// to avoid hardened derivation steps, start from a `DescriptorSecretKey` - /// and call `to_public`, or call `TranslatePk2::translate_pk2` with - /// some function which has access to secret key data. + /// [`translate_pk`]: crate::TranslatePk::translate_pk pub fn derive_public_key( &self, secp: &Secp256k1, @@ -511,8 +505,9 @@ impl DescriptorPublicKey { SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()), }, DescriptorPublicKey::XPub(ref xpk) => match xpk.wildcard { - Wildcard::Unhardened => Err(ConversionError::Wildcard), - Wildcard::Hardened => Err(ConversionError::HardenedWildcard), + Wildcard::Unhardened | Wildcard::Hardened => { + unreachable!("we've excluded this error case") + } Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) { Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)), Err(bip32::Error::CannotDeriveFromHardenedKey) => { @@ -767,7 +762,7 @@ impl MiniscriptKey for DescriptorPublicKey { } } -impl DerivedDescriptorKey { +impl DefiniteDescriptorKey { /// Computes the raw [`bitcoin::PublicKey`] for this descriptor key. /// /// Will return an error if the key has any hardened derivation steps @@ -778,32 +773,51 @@ impl DerivedDescriptorKey { &self, secp: &Secp256k1, ) -> Result { - self.key.derive_public_key(secp) - } - - /// Return the derivation index of this key - pub fn index(&self) -> u32 { - self.index + self.0.derive_public_key(secp) } /// Construct an instance from a descriptor key and a derivation index /// /// Returns `None` if the key contains a wildcard - fn new(key: DescriptorPublicKey, index: u32) -> Option { - match key { - DescriptorPublicKey::XPub(ref xpk) if xpk.wildcard != Wildcard::None => None, - k => Some(DerivedDescriptorKey { key: k, index }), + fn new(key: DescriptorPublicKey) -> Option { + if key.has_wildcard() { + None + } else { + Some(Self(key)) } } + + /// The fingerprint of the master key associated with this key, `0x00000000` if none. + pub fn master_fingerprint(&self) -> bip32::Fingerprint { + self.0.master_fingerprint() + } + + /// Full path, from the master key + pub fn full_derivation_path(&self) -> bip32::DerivationPath { + self.0.full_derivation_path() + } +} + +impl FromStr for DefiniteDescriptorKey { + type Err = DescriptorKeyParseError; + + fn from_str(s: &str) -> Result { + let inner = DescriptorPublicKey::from_str(s)?; + Ok( + DefiniteDescriptorKey::new(inner).ok_or(DescriptorKeyParseError( + "cannot parse key with a wilcard as a DerivedDescriptorKey", + ))?, + ) + } } -impl fmt::Display for DerivedDescriptorKey { +impl fmt::Display for DefiniteDescriptorKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.key.fmt(f) + self.0.fmt(f) } } -impl MiniscriptKey for DerivedDescriptorKey { +impl MiniscriptKey for DefiniteDescriptorKey { // This allows us to be able to derive public keys even for PkH s type RawPkHash = Self; type Sha256 = sha256::Hash; @@ -812,11 +826,11 @@ impl MiniscriptKey for DerivedDescriptorKey { type Hash160 = hash160::Hash; fn is_uncompressed(&self) -> bool { - self.key.is_uncompressed() + self.0.is_uncompressed() } fn is_x_only_key(&self) -> bool { - self.key.is_x_only_key() + self.0.is_x_only_key() } fn to_pubkeyhash(&self) -> Self { @@ -824,10 +838,10 @@ impl MiniscriptKey for DerivedDescriptorKey { } } -impl ToPublicKey for DerivedDescriptorKey { +impl ToPublicKey for DefiniteDescriptorKey { fn to_public_key(&self) -> bitcoin::PublicKey { let secp = Secp256k1::verification_only(); - self.key.derive_public_key(&secp).unwrap() + self.0.derive_public_key(&secp).unwrap() } fn hash_to_hash160(hash: &Self) -> hash160::Hash { @@ -851,6 +865,12 @@ impl ToPublicKey for DerivedDescriptorKey { } } +impl From for DescriptorPublicKey { + fn from(d: DefiniteDescriptorKey) -> Self { + d.0 + } +} + #[cfg(test)] mod test { use core::str::FromStr; @@ -957,17 +977,17 @@ mod test { let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/2").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'/2"); - assert_eq!(public_key.is_deriveable(), false); + assert_eq!(public_key.has_wildcard(), false); let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/*").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'"); - assert_eq!(public_key.is_deriveable(), true); + assert_eq!(public_key.has_wildcard(), true); let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/*h").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'"); - assert_eq!(public_key.is_deriveable(), true); + assert_eq!(public_key.has_wildcard(), true); } #[test] @@ -979,7 +999,7 @@ mod test { assert_eq!(public_key.to_string(), "[2cbe2a6d/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/2"); assert_eq!(public_key.master_fingerprint().to_string(), "2cbe2a6d"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'/2"); - assert_eq!(public_key.is_deriveable(), false); + assert_eq!(public_key.has_wildcard(), false); let secret_key = DescriptorSecretKey::from_str("tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/0'/1'/2'").unwrap(); let public_key = secret_key.to_public(&secp).unwrap(); diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 2b02dc165..1c8083d22 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -58,7 +58,7 @@ mod checksum; mod key; pub use self::key::{ - ConversionError, DerivedDescriptorKey, DescriptorKeyParseError, DescriptorPublicKey, + ConversionError, DefiniteDescriptorKey, DescriptorKeyParseError, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, InnerXKey, SinglePriv, SinglePub, SinglePubKey, Wildcard, }; @@ -513,53 +513,67 @@ impl ForEachKey for Descriptor { impl Descriptor { /// Whether or not the descriptor has any wildcards + #[deprecated(note = "use has_wildcards instead")] pub fn is_deriveable(&self) -> bool { - self.for_any_key(|key| key.is_deriveable()) + self.has_wildcard() } - /// Derives all wildcard keys in the descriptor using the supplied index + /// Whether or not the descriptor has any wildcards i.e. `/*`. + pub fn has_wildcard(&self) -> bool { + self.for_any_key(|key| key.has_wildcard()) + } + + /// Replaces all wildcards (i.e. `/*`) in the descriptor with a particular derivation index, + /// turning it into a *definite* descriptor. /// - /// Panics if given an index ≥ 2^31 + /// # Panics /// - /// In most cases, you would want to use [`Self::derived_descriptor`] directly to obtain - /// a [`Descriptor`] - pub fn derive(&self, index: u32) -> Descriptor { + /// If index ≥ 2^31 + pub fn at_derivation_index(&self, index: u32) -> Descriptor { struct Derivator(u32); - impl PkTranslator for Derivator { - fn pk(&mut self, pk: &DescriptorPublicKey) -> Result { - Ok(pk.clone().derive(self.0)) + impl PkTranslator for Derivator { + fn pk(&mut self, pk: &DescriptorPublicKey) -> Result { + Ok(pk.clone().at_derivation_index(self.0)) } - fn pkh(&mut self, pkh: &DescriptorPublicKey) -> Result { - Ok(pkh.clone().derive(self.0)) + fn pkh(&mut self, pkh: &DescriptorPublicKey) -> Result { + Ok(pkh.clone().at_derivation_index(self.0)) } } self.translate_pk(&mut Derivator(index)) .expect("BIP 32 key index substitution cannot fail") } - /// Derive a [`Descriptor`] with a concrete [`bitcoin::PublicKey`] at a given index - /// Removes all extended pubkeys and wildcards from the descriptor and only leaves - /// concrete [`bitcoin::PublicKey`]. All [`bitcoin::XOnlyPublicKey`]s are converted - /// to [`bitcoin::PublicKey`]s by adding a default(0x02) y-coordinate. For [`Tr`] - /// descriptor, spend info is also cached. + #[deprecated(note = "use at_derivation_index instead")] + /// Deprecated name for [`at_derivation_index`]. + pub fn derive(&self, index: u32) -> Descriptor { + self.at_derivation_index(index) + } + + /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or + /// otherwise converting them. All [`bitcoin::XOnlyPublicKey`]s are converted to by adding a + /// default(0x02) y-coordinate. /// - /// # Examples + /// This is a shorthand for: /// /// ``` - /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey}; - /// use miniscript::bitcoin::secp256k1; - /// use std::str::FromStr; - /// - /// // test from bip 86 - /// let secp = secp256k1::Secp256k1::verification_only(); - /// let descriptor = Descriptor::::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)") + /// # use miniscript::{Descriptor, DescriptorPublicKey, bitcoin::secp256k1::Secp256k1}; + /// # use core::str::FromStr; + /// # let descriptor = Descriptor::::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)") /// .expect("Valid ranged descriptor"); - /// let result = descriptor.derived_descriptor(&secp, 0).expect("Non-hardened derivation"); - /// assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym"); + /// # let index = 42; + /// # let secp = Secp256k1::verification_only(); + /// let derived_descriptor = descriptor.at_derivation_index(index).derived_descriptor(&secp); + /// # assert_eq!(descriptor.derived_descriptor(&secp, index), derived_descriptor); /// ``` /// + /// and is only here really here for backwards compatbility. + /// See [`at_derivation_index`] and `[derived_descriptor`] for more documentation. + /// + /// [`at_derivation_index`]: Self::at_derivation_index + /// [`derived_descriptor`]: crate::DerivedDescriptor::derived_descriptor + /// /// # Errors /// /// This function will return an error if hardened derivation is attempted. @@ -568,29 +582,7 @@ impl Descriptor { secp: &secp256k1::Secp256k1, index: u32, ) -> Result, ConversionError> { - struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1); - - impl<'a, C: secp256k1::Verification> - PkTranslator - for Derivator<'a, C> - { - fn pk( - &mut self, - pk: &DerivedDescriptorKey, - ) -> Result { - pk.derive_public_key(&self.0) - } - - fn pkh( - &mut self, - pkh: &DerivedDescriptorKey, - ) -> Result { - Ok(pkh.derive_public_key(&self.0)?.to_pubkeyhash()) - } - } - - let derived = self.derive(index).translate_pk(&mut Derivator(secp))?; - Ok(derived) + self.at_derivation_index(index).derived_descriptor(&secp) } /// Parse a descriptor that may contain secret keys @@ -731,7 +723,7 @@ impl Descriptor { script_pubkey: &Script, range: Range, ) -> Result)>, ConversionError> { - let range = if self.is_deriveable() { range } else { 0..1 }; + let range = if self.has_wildcard() { range } else { 0..1 }; for i in range { let concrete = self.derived_descriptor(secp, i)?; @@ -744,6 +736,59 @@ impl Descriptor { } } +impl Descriptor { + /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or + /// otherwise converting them. All [`bitcoin::XOnlyPublicKey`]s are converted to by adding a + /// default(0x02) y-coordinate. + /// + /// # Examples + /// + /// ``` + /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey}; + /// use miniscript::bitcoin::secp256k1; + /// use std::str::FromStr; + /// + /// // test from bip 86 + /// let secp = secp256k1::Secp256k1::verification_only(); + /// let descriptor = Descriptor::::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)") + /// .expect("Valid ranged descriptor"); + /// let result = descriptor.at_derivation_index(0).derived_descriptor(&secp).expect("Non-hardened derivation"); + /// assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym"); + /// ``` + /// + /// # Errors + /// + /// This function will return an error if hardened derivation is attempted. + pub fn derived_descriptor( + &self, + secp: &secp256k1::Secp256k1, + ) -> Result, ConversionError> { + struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1); + + impl<'a, C: secp256k1::Verification> + PkTranslator + for Derivator<'a, C> + { + fn pk( + &mut self, + pk: &DefiniteDescriptorKey, + ) -> Result { + pk.derive_public_key(&self.0) + } + + fn pkh( + &mut self, + pkh: &DefiniteDescriptorKey, + ) -> Result { + Ok(pkh.derive_public_key(&self.0)?.to_pubkeyhash()) + } + } + + let derived = self.translate_pk(&mut Derivator(secp))?; + Ok(derived) + } +} + impl_from_tree!( Descriptor, /// Parse an expression tree into a descriptor. @@ -1564,12 +1609,14 @@ mod tests { // Same address let addr_one = desc_one - .derived_descriptor(&secp_ctx, index) + .at_derivation_index(index) + .derived_descriptor(&secp_ctx) .unwrap() .address(bitcoin::Network::Bitcoin) .unwrap(); let addr_two = desc_two - .derived_descriptor(&secp_ctx, index) + .at_derivation_index(index) + .derived_descriptor(&secp_ctx) .unwrap() .address(bitcoin::Network::Bitcoin) .unwrap(); @@ -1646,7 +1693,7 @@ pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHW pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))"; let policy: policy::concrete::Policy = descriptor_str.parse().unwrap(); let descriptor = Descriptor::new_sh(policy.compile().unwrap()).unwrap(); - let derived_descriptor = descriptor.derive(42); + let definite_descriptor = descriptor.at_derivation_index(42); let res_descriptor_str = "thresh(2,\ pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\ @@ -1656,7 +1703,7 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))"; res_descriptor_str.parse().unwrap(); let res_descriptor = Descriptor::new_sh(res_policy.compile().unwrap()).unwrap(); - assert_eq!(res_descriptor.to_string(), derived_descriptor.to_string()); + assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string()); } #[test] diff --git a/src/lib.rs b/src/lib.rs index 69713728e..3deae23aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,7 +135,7 @@ use std::error; use bitcoin::blockdata::{opcodes, script}; use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -pub use crate::descriptor::{Descriptor, DescriptorPublicKey}; +pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; pub use crate::interpreter::Interpreter; pub use crate::miniscript::context::{BareCtx, Legacy, ScriptContext, Segwitv0, Tap}; pub use crate::miniscript::decode::Terminal; diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index 50a7144f7..b0047bd78 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -36,7 +36,7 @@ use crate::miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG; use crate::miniscript::satisfy::{After, Older}; use crate::prelude::*; use crate::{ - descriptor, interpreter, Descriptor, DescriptorPublicKey, MiniscriptKey, PkTranslator, + descriptor, interpreter, DefiniteDescriptorKey, Descriptor, MiniscriptKey, PkTranslator, Preimage32, Satisfier, ToPublicKey, TranslatePk, }; @@ -568,7 +568,7 @@ pub trait PsbtExt { fn update_input_with_descriptor( &mut self, input_index: usize, - descriptor: &Descriptor, + descriptor: &Descriptor, ) -> Result<(), UtxoUpdateError>; /// Get the sighash message(data to sign) at input index `idx` based on the sighash @@ -735,7 +735,7 @@ impl PsbtExt for Psbt { fn update_input_with_descriptor( &mut self, input_index: usize, - desc: &Descriptor, + desc: &Descriptor, ) -> Result<(), UtxoUpdateError> { let n_inputs = self.inputs.len(); let input = self @@ -916,14 +916,14 @@ pub trait PsbtInputExt { /// [`update_input_with_descriptor`]: PsbtExt::update_input_with_descriptor fn update_with_descriptor_unchecked( &mut self, - descriptor: &Descriptor, + descriptor: &Descriptor, ) -> Result, descriptor::ConversionError>; } impl PsbtInputExt for psbt::Input { fn update_with_descriptor_unchecked( &mut self, - descriptor: &Descriptor, + descriptor: &Descriptor, ) -> Result, descriptor::ConversionError> { let (derived, _) = update_input_with_descriptor_helper(self, descriptor, None)?; Ok(derived) @@ -937,19 +937,19 @@ struct XOnlyHashLookUp( pub secp256k1::Secp256k1, ); -impl PkTranslator +impl PkTranslator for XOnlyHashLookUp { fn pk( &mut self, - xpk: &DescriptorPublicKey, + xpk: &DefiniteDescriptorKey, ) -> Result { xpk.derive_public_key(&self.1) } fn pkh( &mut self, - xpk: &DescriptorPublicKey, + xpk: &DefiniteDescriptorKey, ) -> Result { let pk = xpk.derive_public_key(&self.1)?; let xonly = pk.to_x_only_pubkey(); @@ -966,12 +966,12 @@ struct KeySourceLookUp( pub secp256k1::Secp256k1, ); -impl PkTranslator +impl PkTranslator for KeySourceLookUp { fn pk( &mut self, - xpk: &DescriptorPublicKey, + xpk: &DefiniteDescriptorKey, ) -> Result { let derived = xpk.derive_public_key(&self.1)?; self.0.insert( @@ -983,7 +983,7 @@ impl PkTranslator Result { Ok(self.pk(xpk)?.to_pubkeyhash()) } @@ -991,7 +991,7 @@ impl PkTranslator, + descriptor: &Descriptor, check_script: Option