miniscript/descriptor/
mod.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Output Descriptors
4//!
5//! Tools for representing Bitcoin output's scriptPubKeys as abstract spending
6//! policies known as "output descriptors". These include a Miniscript which
7//! describes the actual signing policy, as well as the blockchain format (P2SH,
8//! Segwit v0, etc.)
9//!
10//! The format represents EC public keys abstractly to allow wallets to replace
11//! these with BIP32 paths, pay-to-contract instructions, etc.
12//!
13
14use core::fmt;
15use core::ops::Range;
16use core::str::{self, FromStr};
17
18use bitcoin::hashes::{hash160, ripemd160, sha256};
19use bitcoin::{
20    secp256k1, Address, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion,
21};
22use sync::Arc;
23
24use crate::expression::FromTree as _;
25use crate::miniscript::decode::Terminal;
26use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
27use crate::miniscript::{satisfy, Legacy, Miniscript, Segwitv0};
28use crate::plan::{AssetProvider, Plan};
29use crate::prelude::*;
30use crate::{
31    expression, hash256, BareCtx, Error, ForEachKey, FromStrKey, MiniscriptKey, ParseError,
32    Satisfier, Threshold, ToPublicKey, TranslateErr, Translator,
33};
34
35mod bare;
36mod iter;
37mod segwitv0;
38mod sh;
39mod sortedmulti;
40mod tr;
41
42// Descriptor Exports
43pub use self::bare::{Bare, Pkh};
44pub use self::iter::PkIter;
45pub use self::segwitv0::{Wpkh, Wsh, WshInner};
46pub use self::sh::{Sh, ShInner};
47pub use self::sortedmulti::SortedMultiVec;
48pub use self::tr::{
49    TapTree, TapTreeDepthError, TapTreeIter, TapTreeIterItem, Tr, TrSpendInfo, TrSpendInfoIter,
50    TrSpendInfoIterItem,
51};
52
53pub mod checksum;
54mod key;
55mod key_map;
56
57pub use self::key::{
58    DefiniteDescriptorKey, DerivPaths, DescriptorKeyParseError, DescriptorMultiXKey,
59    DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, InnerXKey, MalformedKeyDataKind,
60    NonDefiniteKeyError, SinglePriv, SinglePub, SinglePubKey, Wildcard, XKeyNetwork,
61};
62pub use self::key_map::KeyMap;
63
64/// Script descriptor
65#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub enum Descriptor<Pk: MiniscriptKey> {
67    /// A raw scriptpubkey (including pay-to-pubkey) under Legacy context
68    Bare(Bare<Pk>),
69    /// Pay-to-PubKey-Hash
70    Pkh(Pkh<Pk>),
71    /// Pay-to-Witness-PubKey-Hash
72    Wpkh(Wpkh<Pk>),
73    /// Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)
74    Sh(Sh<Pk>),
75    /// Pay-to-Witness-ScriptHash with Segwitv0 context
76    Wsh(Wsh<Pk>),
77    /// Pay-to-Taproot
78    Tr(Tr<Pk>),
79}
80
81impl<Pk: MiniscriptKey> From<Bare<Pk>> for Descriptor<Pk> {
82    #[inline]
83    fn from(inner: Bare<Pk>) -> Self { Descriptor::Bare(inner) }
84}
85
86impl<Pk: MiniscriptKey> From<Pkh<Pk>> for Descriptor<Pk> {
87    #[inline]
88    fn from(inner: Pkh<Pk>) -> Self { Descriptor::Pkh(inner) }
89}
90
91impl<Pk: MiniscriptKey> From<Wpkh<Pk>> for Descriptor<Pk> {
92    #[inline]
93    fn from(inner: Wpkh<Pk>) -> Self { Descriptor::Wpkh(inner) }
94}
95
96impl<Pk: MiniscriptKey> From<Sh<Pk>> for Descriptor<Pk> {
97    #[inline]
98    fn from(inner: Sh<Pk>) -> Self { Descriptor::Sh(inner) }
99}
100
101impl<Pk: MiniscriptKey> From<Wsh<Pk>> for Descriptor<Pk> {
102    #[inline]
103    fn from(inner: Wsh<Pk>) -> Self { Descriptor::Wsh(inner) }
104}
105
106impl<Pk: MiniscriptKey> From<Tr<Pk>> for Descriptor<Pk> {
107    #[inline]
108    fn from(inner: Tr<Pk>) -> Self { Descriptor::Tr(inner) }
109}
110
111/// Descriptor Type of the descriptor
112#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
113pub enum DescriptorType {
114    /// Bare descriptor(Contains the native P2pk)
115    Bare,
116    /// Pure Sh Descriptor. Does not contain nested Wsh/Wpkh
117    Sh,
118    /// Pkh Descriptor
119    Pkh,
120    /// Wpkh Descriptor
121    Wpkh,
122    /// Wsh
123    Wsh,
124    /// Sh Wrapped Wsh
125    ShWsh,
126    /// Sh wrapped Wpkh
127    ShWpkh,
128    /// Sh Sorted Multi
129    ShSortedMulti,
130    /// Wsh Sorted Multi
131    WshSortedMulti,
132    /// Sh Wsh Sorted Multi
133    ShWshSortedMulti,
134    /// Tr Descriptor
135    Tr,
136}
137
138impl DescriptorType {
139    /// Returns the segwit version implied by the descriptor type.
140    ///
141    /// This will return `Some(WitnessVersion::V0)` whether it is "native" segwitv0 or "wrapped" p2sh segwit.
142    pub fn segwit_version(&self) -> Option<WitnessVersion> {
143        use self::DescriptorType::*;
144        match self {
145            Tr => Some(WitnessVersion::V1),
146            Wpkh | ShWpkh | Wsh | ShWsh | ShWshSortedMulti | WshSortedMulti => {
147                Some(WitnessVersion::V0)
148            }
149            Bare | Sh | Pkh | ShSortedMulti => None,
150        }
151    }
152}
153
154impl<Pk: MiniscriptKey> Descriptor<Pk> {
155    // Keys
156
157    /// Create a new pk descriptor
158    pub fn new_pk(pk: Pk) -> Self {
159        // roundabout way to constuct `c:pk_k(pk)`
160        let ms: Miniscript<Pk, BareCtx> = Miniscript::from_ast(Terminal::Check(Arc::new(
161            Miniscript::from_ast(Terminal::PkK(pk)).expect("Type check cannot fail"),
162        )))
163        .expect("Type check cannot fail");
164        Descriptor::Bare(Bare::new(ms).expect("Context checks cannot fail for p2pk"))
165    }
166
167    /// Create a new PkH descriptor
168    pub fn new_pkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Pkh(Pkh::new(pk)?)) }
169
170    /// Create a new Wpkh descriptor
171    /// Will return Err if uncompressed key is used
172    pub fn new_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Wpkh(Wpkh::new(pk)?)) }
173
174    /// Create a new sh wrapped wpkh from `Pk`.
175    /// Errors when uncompressed keys are supplied
176    pub fn new_sh_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Sh(Sh::new_wpkh(pk)?)) }
177
178    // Miniscripts
179
180    /// Create a new sh for a given redeem script
181    /// Errors when miniscript exceeds resource limits under p2sh context
182    /// or does not type check at the top level
183    pub fn new_sh(ms: Miniscript<Pk, Legacy>) -> Result<Self, Error> {
184        Ok(Descriptor::Sh(Sh::new(ms)?))
185    }
186
187    /// Create a new wsh descriptor from witness script
188    /// Errors when miniscript exceeds resource limits under p2sh context
189    /// or does not type check at the top level
190    pub fn new_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
191        Ok(Descriptor::Wsh(Wsh::new(ms)?))
192    }
193
194    /// Create a new sh wrapped wsh descriptor with witness script
195    /// Errors when miniscript exceeds resource limits under wsh context
196    /// or does not type check at the top level
197    pub fn new_sh_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
198        Ok(Descriptor::Sh(Sh::new_wsh(ms)?))
199    }
200
201    /// Create a new bare descriptor from witness script
202    /// Errors when miniscript exceeds resource limits under bare context
203    /// or does not type check at the top level
204    pub fn new_bare(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
205        Ok(Descriptor::Bare(Bare::new(ms)?))
206    }
207
208    // Wrap with sh
209
210    /// Create a new sh wrapper for the given wpkh descriptor
211    pub fn new_sh_with_wpkh(wpkh: Wpkh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wpkh(wpkh)) }
212
213    /// Create a new sh wrapper for the given wsh descriptor
214    pub fn new_sh_with_wsh(wsh: Wsh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wsh(wsh)) }
215
216    // sorted multi
217
218    /// Create a new sh sortedmulti descriptor with threshold `k`
219    /// and Vec of `pks`.
220    /// Errors when miniscript exceeds resource limits under p2sh context
221    pub fn new_sh_sortedmulti(
222        thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
223    ) -> Result<Self, Error> {
224        Ok(Descriptor::Sh(Sh::new_sortedmulti(thresh)?))
225    }
226
227    /// Create a new sh wrapped wsh sortedmulti descriptor from threshold
228    /// `k` and Vec of `pks`
229    /// Errors when miniscript exceeds resource limits under segwit context
230    pub fn new_sh_wsh_sortedmulti(
231        thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
232    ) -> Result<Self, Error> {
233        Ok(Descriptor::Sh(Sh::new_wsh_sortedmulti(thresh)?))
234    }
235
236    /// Create a new wsh sorted multi descriptor
237    /// Errors when miniscript exceeds resource limits under p2sh context
238    pub fn new_wsh_sortedmulti(
239        thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
240    ) -> Result<Self, Error> {
241        Ok(Descriptor::Wsh(Wsh::new_sortedmulti(thresh)?))
242    }
243
244    /// Create new tr descriptor
245    /// Errors when miniscript exceeds resource limits under Tap context
246    pub fn new_tr(key: Pk, script: Option<tr::TapTree<Pk>>) -> Result<Self, Error> {
247        Ok(Descriptor::Tr(Tr::new(key, script)?))
248    }
249
250    /// An iterator over all the keys referenced in the descriptor.
251    pub fn iter_pk(&self) -> PkIter<'_, Pk> {
252        match *self {
253            Descriptor::Bare(ref bare) => PkIter::from_miniscript_bare(bare.as_inner()),
254            Descriptor::Pkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
255            Descriptor::Wpkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
256            Descriptor::Sh(ref sh) => match *sh.as_inner() {
257                ShInner::Wsh(ref wsh) => match wsh.as_inner() {
258                    WshInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
259                    WshInner::Ms(ref ms) => PkIter::from_miniscript_segwit(ms),
260                },
261                ShInner::Wpkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
262                ShInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
263                ShInner::Ms(ref ms) => PkIter::from_miniscript_legacy(ms),
264            },
265            Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
266                WshInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
267                WshInner::Ms(ref ms) => PkIter::from_miniscript_segwit(ms),
268            },
269            Descriptor::Tr(ref tr) => PkIter::from_tr(tr),
270        }
271    }
272
273    /// For a Taproot descriptor, returns the internal key.
274    pub fn internal_key(&self) -> Option<&Pk> {
275        if let Descriptor::Tr(ref tr) = self {
276            Some(tr.internal_key())
277        } else {
278            None
279        }
280    }
281
282    /// For a Taproot descriptor, returns the [`TapTree`] describing the Taproot tree.
283    ///
284    /// To obtain the individual leaves of the tree, call [`TapTree::leaves`] on the
285    /// returned value.
286    pub fn tap_tree(&self) -> Option<&TapTree<Pk>> {
287        if let Descriptor::Tr(ref tr) = self {
288            tr.tap_tree()
289        } else {
290            None
291        }
292    }
293
294    /// For a Taproot descriptor, returns an iterator over the scripts in the Taptree.
295    ///
296    /// If the descriptor is not a Taproot descriptor, **or** if the descriptor is a
297    /// Taproot descriptor containing only a keyspend, returns an empty iterator.
298    pub fn tap_tree_iter(&self) -> tr::TapTreeIter<'_, Pk> {
299        if let Descriptor::Tr(ref tr) = self {
300            if let Some(tree) = tr.tap_tree() {
301                return tree.leaves();
302            }
303        }
304        tr::TapTreeIter::empty()
305    }
306
307    /// Get the [DescriptorType] of [Descriptor]
308    pub fn desc_type(&self) -> DescriptorType {
309        match *self {
310            Descriptor::Bare(ref _bare) => DescriptorType::Bare,
311            Descriptor::Pkh(ref _pkh) => DescriptorType::Pkh,
312            Descriptor::Wpkh(ref _wpkh) => DescriptorType::Wpkh,
313            Descriptor::Sh(ref sh) => match sh.as_inner() {
314                ShInner::Wsh(ref wsh) => match wsh.as_inner() {
315                    WshInner::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
316                    WshInner::Ms(ref _ms) => DescriptorType::ShWsh,
317                },
318                ShInner::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
319                ShInner::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
320                ShInner::Ms(ref _ms) => DescriptorType::Sh,
321            },
322            Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
323                WshInner::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
324                WshInner::Ms(ref _ms) => DescriptorType::Wsh,
325            },
326            Descriptor::Tr(ref _tr) => DescriptorType::Tr,
327        }
328    }
329
330    /// Checks whether the descriptor is safe.
331    ///
332    /// Checks whether all the spend paths in the descriptor are possible on the
333    /// bitcoin network under the current standardness and consensus rules. Also
334    /// checks whether the descriptor requires signatures on all spend paths and
335    /// whether the script is malleable.
336    ///
337    /// In general, all the guarantees of miniscript hold only for safe scripts.
338    /// The signer may not be able to find satisfactions even if one exists.
339    pub fn sanity_check(&self) -> Result<(), Error> {
340        match *self {
341            Descriptor::Bare(ref bare) => bare.sanity_check(),
342            Descriptor::Pkh(_) => Ok(()),
343            Descriptor::Wpkh(ref wpkh) => wpkh.sanity_check(),
344            Descriptor::Wsh(ref wsh) => wsh.sanity_check(),
345            Descriptor::Sh(ref sh) => sh.sanity_check(),
346            Descriptor::Tr(ref tr) => tr.sanity_check(),
347        }
348    }
349
350    /// Computes an upper bound on the difference between a non-satisfied
351    /// `TxIn`'s `segwit_weight` and a satisfied `TxIn`'s `segwit_weight`
352    ///
353    /// Since this method uses `segwit_weight` instead of `legacy_weight`,
354    /// if you want to include only legacy inputs in your transaction,
355    /// you should remove 1WU from each input's `max_weight_to_satisfy`
356    /// for a more accurate estimate.
357    ///
358    /// In other words, for segwit inputs or legacy inputs included in
359    /// segwit transactions, the following will hold for each input if
360    /// that input was satisfied with the largest possible witness:
361    /// ```ignore
362    /// for i in 0..transaction.input.len() {
363    ///     assert_eq!(
364    ///         descriptor_for_input[i].max_weight_to_satisfy(),
365    ///         transaction.input[i].segwit_weight() - TxIn::default().segwit_weight()
366    ///     );
367    /// }
368    /// ```
369    ///
370    /// Instead, for legacy transactions, the following will hold for each input
371    /// if that input was satisfied with the largest possible witness:
372    /// ```ignore
373    /// for i in 0..transaction.input.len() {
374    ///     assert_eq!(
375    ///         descriptor_for_input[i].max_weight_to_satisfy(),
376    ///         transaction.input[i].legacy_weight() - TxIn::default().legacy_weight()
377    ///     );
378    /// }
379    /// ```
380    ///
381    /// Assumes all ECDSA signatures are 73 bytes, including push opcode and
382    /// sighash suffix.
383    /// Assumes all Schnorr signatures are 66 bytes, including push opcode and
384    /// sighash suffix.
385    ///
386    /// # Errors
387    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
388    pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
389        let weight = match *self {
390            Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
391            Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),
392            Descriptor::Wpkh(ref wpkh) => wpkh.max_weight_to_satisfy(),
393            Descriptor::Wsh(ref wsh) => wsh.max_weight_to_satisfy()?,
394            Descriptor::Sh(ref sh) => sh.max_weight_to_satisfy()?,
395            Descriptor::Tr(ref tr) => tr.max_weight_to_satisfy()?,
396        };
397        Ok(weight)
398    }
399
400    /// Computes an upper bound on the weight of a satisfying witness to the
401    /// transaction.
402    ///
403    /// Assumes all ec-signatures are 73 bytes, including push opcode and
404    /// sighash suffix. Includes the weight of the VarInts encoding the
405    /// scriptSig and witness stack length.
406    ///
407    /// # Errors
408    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
409    #[deprecated(
410        since = "10.0.0",
411        note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
412    )]
413    #[allow(deprecated)]
414    pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
415        let weight = match *self {
416            Descriptor::Bare(ref bare) => bare.max_satisfaction_weight()?,
417            Descriptor::Pkh(ref pkh) => pkh.max_satisfaction_weight(),
418            Descriptor::Wpkh(ref wpkh) => wpkh.max_satisfaction_weight(),
419            Descriptor::Wsh(ref wsh) => wsh.max_satisfaction_weight()?,
420            Descriptor::Sh(ref sh) => sh.max_satisfaction_weight()?,
421            Descriptor::Tr(ref tr) => tr.max_satisfaction_weight()?,
422        };
423        Ok(weight)
424    }
425
426    /// Converts a descriptor using one kind of keys to another kind of key.
427    pub fn translate_pk<T>(
428        &self,
429        t: &mut T,
430    ) -> Result<Descriptor<T::TargetPk>, TranslateErr<T::Error>>
431    where
432        T: Translator<Pk>,
433    {
434        let desc = match *self {
435            Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?),
436            Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?),
437            Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?),
438            Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?),
439            Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?),
440            Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?),
441        };
442        Ok(desc)
443    }
444}
445
446impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
447    /// Computes the Bitcoin address of the descriptor, if one exists
448    ///
449    /// Some descriptors like pk() don't have an address.
450    ///
451    /// # Errors
452    /// For raw/bare descriptors that don't have an address.
453    pub fn address(&self, network: Network) -> Result<Address, Error> {
454        match *self {
455            Descriptor::Bare(_) => Err(Error::BareDescriptorAddr),
456            Descriptor::Pkh(ref pkh) => Ok(pkh.address(network)),
457            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.address(network)),
458            Descriptor::Wsh(ref wsh) => Ok(wsh.address(network)),
459            Descriptor::Sh(ref sh) => Ok(sh.address(network)),
460            Descriptor::Tr(ref tr) => Ok(tr.address(network)),
461        }
462    }
463
464    /// Computes the scriptpubkey of the descriptor.
465    pub fn script_pubkey(&self) -> ScriptBuf {
466        match *self {
467            Descriptor::Bare(ref bare) => bare.script_pubkey(),
468            Descriptor::Pkh(ref pkh) => pkh.script_pubkey(),
469            Descriptor::Wpkh(ref wpkh) => wpkh.script_pubkey(),
470            Descriptor::Wsh(ref wsh) => wsh.script_pubkey(),
471            Descriptor::Sh(ref sh) => sh.script_pubkey(),
472            Descriptor::Tr(ref tr) => tr.script_pubkey(),
473        }
474    }
475
476    /// Computes the scriptSig that will be in place for an unsigned input
477    /// spending an output with this descriptor. For pre-segwit descriptors,
478    /// which use the scriptSig for signatures, this returns the empty script.
479    ///
480    /// This is used in Segwit transactions to produce an unsigned transaction
481    /// whose txid will not change during signing (since only the witness data
482    /// will change).
483    pub fn unsigned_script_sig(&self) -> ScriptBuf {
484        match *self {
485            Descriptor::Bare(_) => ScriptBuf::new(),
486            Descriptor::Pkh(_) => ScriptBuf::new(),
487            Descriptor::Wpkh(_) => ScriptBuf::new(),
488            Descriptor::Wsh(_) => ScriptBuf::new(),
489            Descriptor::Sh(ref sh) => sh.unsigned_script_sig(),
490            Descriptor::Tr(_) => ScriptBuf::new(),
491        }
492    }
493
494    /// Computes the the underlying script before any hashing is done. For
495    /// `Bare`, `Pkh` and `Wpkh` this is the scriptPubkey; for `ShWpkh` and `Sh`
496    /// this is the redeemScript; for the others it is the witness script.
497    ///
498    /// # Errors
499    /// If the descriptor is a taproot descriptor.
500    pub fn explicit_script(&self) -> Result<ScriptBuf, Error> {
501        match *self {
502            Descriptor::Bare(ref bare) => Ok(bare.script_pubkey()),
503            Descriptor::Pkh(ref pkh) => Ok(pkh.script_pubkey()),
504            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.script_pubkey()),
505            Descriptor::Wsh(ref wsh) => Ok(wsh.inner_script()),
506            Descriptor::Sh(ref sh) => Ok(sh.inner_script()),
507            Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
508        }
509    }
510
511    /// Computes the `scriptCode` of a transaction output.
512    ///
513    /// The `scriptCode` is the Script of the previous transaction output being
514    /// serialized in the sighash when evaluating a `CHECKSIG` & co. OP code.
515    ///
516    /// # Errors
517    /// If the descriptor is a taproot descriptor.
518    pub fn script_code(&self) -> Result<ScriptBuf, Error> {
519        match *self {
520            Descriptor::Bare(ref bare) => Ok(bare.ecdsa_sighash_script_code()),
521            Descriptor::Pkh(ref pkh) => Ok(pkh.ecdsa_sighash_script_code()),
522            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.ecdsa_sighash_script_code()),
523            Descriptor::Wsh(ref wsh) => Ok(wsh.ecdsa_sighash_script_code()),
524            Descriptor::Sh(ref sh) => Ok(sh.ecdsa_sighash_script_code()),
525            Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
526        }
527    }
528
529    /// Returns satisfying non-malleable witness and scriptSig to spend an
530    /// output controlled by the given descriptor if it possible to
531    /// construct one using the satisfier S.
532    pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
533    where
534        S: Satisfier<Pk>,
535    {
536        match *self {
537            Descriptor::Bare(ref bare) => bare.get_satisfaction(satisfier),
538            Descriptor::Pkh(ref pkh) => pkh.get_satisfaction(satisfier),
539            Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction(satisfier),
540            Descriptor::Wsh(ref wsh) => wsh.get_satisfaction(satisfier),
541            Descriptor::Sh(ref sh) => sh.get_satisfaction(satisfier),
542            Descriptor::Tr(ref tr) => tr.get_satisfaction(&satisfier),
543        }
544    }
545
546    /// Returns a possilbly mallable satisfying non-malleable witness and scriptSig to spend an
547    /// output controlled by the given descriptor if it possible to
548    /// construct one using the satisfier S.
549    pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
550    where
551        S: Satisfier<Pk>,
552    {
553        match *self {
554            Descriptor::Bare(ref bare) => bare.get_satisfaction_mall(satisfier),
555            Descriptor::Pkh(ref pkh) => pkh.get_satisfaction_mall(satisfier),
556            Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction_mall(satisfier),
557            Descriptor::Wsh(ref wsh) => wsh.get_satisfaction_mall(satisfier),
558            Descriptor::Sh(ref sh) => sh.get_satisfaction_mall(satisfier),
559            Descriptor::Tr(ref tr) => tr.get_satisfaction_mall(&satisfier),
560        }
561    }
562
563    /// Attempts to produce a non-malleable satisfying witness and scriptSig to spend an
564    /// output controlled by the given descriptor; add the data to a given
565    /// `TxIn` output.
566    pub fn satisfy<S>(&self, txin: &mut TxIn, satisfier: S) -> Result<(), Error>
567    where
568        S: Satisfier<Pk>,
569    {
570        let (witness, script_sig) = self.get_satisfaction(satisfier)?;
571        txin.witness = Witness::from_slice(&witness);
572        txin.script_sig = script_sig;
573        Ok(())
574    }
575}
576
577impl Descriptor<DefiniteDescriptorKey> {
578    /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
579    ///
580    /// If the assets aren't sufficient for generating a Plan, the descriptor is returned
581    #[allow(clippy::result_large_err)] // our "error type" is the original descriptor
582    pub fn plan<P>(self, provider: &P) -> Result<Plan, Self>
583    where
584        P: AssetProvider<DefiniteDescriptorKey>,
585    {
586        let satisfaction = match self {
587            Descriptor::Bare(ref bare) => bare.plan_satisfaction(provider),
588            Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction(provider),
589            Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction(provider),
590            Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction(provider),
591            Descriptor::Sh(ref sh) => sh.plan_satisfaction(provider),
592            Descriptor::Tr(ref tr) => tr.plan_satisfaction(provider),
593        };
594
595        if let satisfy::Witness::Stack(stack) = satisfaction.stack {
596            Ok(Plan {
597                descriptor: self,
598                template: stack,
599                absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
600                relative_timelock: satisfaction.relative_timelock.map(Into::into),
601            })
602        } else {
603            Err(self)
604        }
605    }
606
607    /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
608    ///
609    /// If the assets aren't sufficient for generating a Plan, the descriptor is returned
610    #[allow(clippy::result_large_err)] // our "error type" is the original descriptor
611    pub fn plan_mall<P>(self, provider: &P) -> Result<Plan, Self>
612    where
613        P: AssetProvider<DefiniteDescriptorKey>,
614    {
615        let satisfaction = match self {
616            Descriptor::Bare(ref bare) => bare.plan_satisfaction_mall(provider),
617            Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction_mall(provider),
618            Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction_mall(provider),
619            Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider),
620            Descriptor::Sh(ref sh) => sh.plan_satisfaction_mall(provider),
621            Descriptor::Tr(ref tr) => tr.plan_satisfaction_mall(provider),
622        };
623
624        if let satisfy::Witness::Stack(stack) = satisfaction.stack {
625            Ok(Plan {
626                descriptor: self,
627                template: stack,
628                absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
629                // unwrap to be removed in a later commit
630                relative_timelock: satisfaction.relative_timelock.map(Into::into),
631            })
632        } else {
633            Err(self)
634        }
635    }
636}
637
638impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
639    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
640        match *self {
641            Descriptor::Bare(ref bare) => bare.for_each_key(pred),
642            Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),
643            Descriptor::Wpkh(ref wpkh) => wpkh.for_each_key(pred),
644            Descriptor::Wsh(ref wsh) => wsh.for_each_key(pred),
645            Descriptor::Sh(ref sh) => sh.for_each_key(pred),
646            Descriptor::Tr(ref tr) => tr.for_each_key(pred),
647        }
648    }
649}
650
651impl Descriptor<DescriptorPublicKey> {
652    /// Whether or not the descriptor has any wildcards i.e. `/*`.
653    pub fn has_wildcard(&self) -> bool { self.for_any_key(|key| key.has_wildcard()) }
654
655    /// Replaces all wildcards (i.e. `/*`) in the descriptor with a particular derivation index,
656    /// turning it into a *definite* descriptor.
657    ///
658    /// # Errors
659    /// - If index ≥ 2^31
660    /// - If the descriptor contains multi-path derivations
661    pub fn at_derivation_index(
662        &self,
663        index: u32,
664    ) -> Result<Descriptor<DefiniteDescriptorKey>, NonDefiniteKeyError> {
665        struct Derivator(u32);
666
667        impl Translator<DescriptorPublicKey> for Derivator {
668            type TargetPk = DefiniteDescriptorKey;
669            type Error = NonDefiniteKeyError;
670
671            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<Self::TargetPk, Self::Error> {
672                pk.clone().at_derivation_index(self.0)
673            }
674
675            translate_hash_clone!(DescriptorPublicKey);
676        }
677        self.translate_pk(&mut Derivator(index))
678            .map_err(|e| e.expect_translator_err("No Context errors while translating"))
679    }
680
681    /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
682    /// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a
683    /// default(0x02) y-coordinate.
684    ///
685    /// This is a shorthand for:
686    ///
687    /// ```
688    /// # use miniscript::{Descriptor, DescriptorPublicKey, bitcoin::secp256k1::Secp256k1};
689    /// # use core::str::FromStr;
690    /// # let descriptor = Descriptor::<DescriptorPublicKey>::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
691    ///     .expect("Valid ranged descriptor");
692    /// # let index = 42;
693    /// # let secp = Secp256k1::verification_only();
694    /// let derived_descriptor = descriptor.at_derivation_index(index).unwrap().derived_descriptor(&secp);
695    /// # assert_eq!(descriptor.derived_descriptor(&secp, index).unwrap(), derived_descriptor);
696    /// ```
697    ///
698    /// and is only here really here for backwards compatibility.
699    /// See [`at_derivation_index`] and `[derived_descriptor`] for more documentation.
700    ///
701    /// [`at_derivation_index`]: Self::at_derivation_index
702    /// [`derived_descriptor`]: Self::derived_descriptor
703    ///
704    /// # Errors
705    ///
706    /// This function will return an error for multi-path descriptors
707    /// or if hardened derivation is attempted,
708    pub fn derived_descriptor<C: secp256k1::Verification>(
709        &self,
710        secp: &secp256k1::Secp256k1<C>,
711        index: u32,
712    ) -> Result<Descriptor<bitcoin::PublicKey>, NonDefiniteKeyError> {
713        Ok(self.at_derivation_index(index)?.derived_descriptor(secp))
714    }
715
716    /// Parse a descriptor that may contain secret keys
717    ///
718    /// Internally turns every secret key found into the corresponding public key and then returns a
719    /// a descriptor that only contains public keys and a map to lookup the secret key given a public key.
720    pub fn parse_descriptor<C: secp256k1::Signing>(
721        secp: &secp256k1::Secp256k1<C>,
722        s: &str,
723    ) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap), Error> {
724        fn parse_key<C: secp256k1::Signing>(
725            s: &str,
726            key_map: &mut KeyMap,
727            secp: &secp256k1::Secp256k1<C>,
728        ) -> Result<DescriptorPublicKey, Error> {
729            match DescriptorSecretKey::from_str(s) {
730                Ok(sk) => {
731                    let pk = key_map
732                        .insert(secp, sk)
733                        .map_err(|e| Error::Unexpected(e.to_string()))?;
734                    Ok(pk)
735                }
736                Err(_) => {
737                    // try to parse as a public key if parsing as a secret key failed
738                    let pk = s
739                        .parse()
740                        .map_err(|e| Error::Parse(ParseError::box_from_str(e)))?;
741                    Ok(pk)
742                }
743            }
744        }
745
746        let mut keymap_pk = KeyMapWrapper(KeyMap::new(), secp);
747
748        struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>);
749
750        impl<C: secp256k1::Signing> Translator<String> for KeyMapWrapper<'_, C> {
751            type TargetPk = DescriptorPublicKey;
752            type Error = Error;
753
754            fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> {
755                parse_key(pk, &mut self.0, self.1)
756            }
757
758            fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Error> {
759                sha256
760                    .parse()
761                    .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
762            }
763
764            fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
765                hash256
766                    .parse()
767                    .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
768            }
769
770            fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Error> {
771                ripemd160
772                    .parse()
773                    .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
774            }
775
776            fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Error> {
777                hash160
778                    .parse()
779                    .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
780            }
781        }
782
783        let descriptor = Descriptor::<String>::from_str(s)?;
784        let descriptor = descriptor
785            .translate_pk(&mut keymap_pk)
786            .map_err(TranslateErr::flatten)?;
787
788        Ok((descriptor, keymap_pk.0))
789    }
790
791    /// Serialize a descriptor to string with its secret keys
792    pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String {
793        struct KeyMapLookUp<'a>(&'a KeyMap);
794
795        impl Translator<DescriptorPublicKey> for KeyMapLookUp<'_> {
796            type TargetPk = String;
797            type Error = core::convert::Infallible;
798
799            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, Self::Error> {
800                key_to_string(pk, self.0)
801            }
802
803            fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, Self::Error> {
804                Ok(sha256.to_string())
805            }
806
807            fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, Self::Error> {
808                Ok(hash256.to_string())
809            }
810
811            fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, Self::Error> {
812                Ok(ripemd160.to_string())
813            }
814
815            fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, Self::Error> {
816                Ok(hash160.to_string())
817            }
818        }
819
820        fn key_to_string(
821            pk: &DescriptorPublicKey,
822            key_map: &KeyMap,
823        ) -> Result<String, core::convert::Infallible> {
824            Ok(match key_map.get(pk) {
825                Some(secret) => secret.to_string(),
826                None => pk.to_string(),
827            })
828        }
829
830        let descriptor = self
831            .translate_pk(&mut KeyMapLookUp(key_map))
832            .expect("Translation to string cannot fail");
833
834        descriptor.to_string()
835    }
836
837    /// Utility method for deriving the descriptor at each index in a range to find one matching
838    /// `script_pubkey`.
839    ///
840    /// If it finds a match then it returns the index it was derived at and the concrete
841    /// descriptor at that index. If the descriptor is non-derivable then it will simply check the
842    /// script pubkey against the descriptor and return it if it matches (in this case the index
843    /// returned will be meaningless).
844    pub fn find_derivation_index_for_spk<C: secp256k1::Verification>(
845        &self,
846        secp: &secp256k1::Secp256k1<C>,
847        script_pubkey: &Script,
848        range: Range<u32>,
849    ) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey>)>, NonDefiniteKeyError> {
850        let range = if self.has_wildcard() { range } else { 0..1 };
851
852        for i in range {
853            let concrete = self.derived_descriptor(secp, i)?;
854            if &concrete.script_pubkey() == script_pubkey {
855                return Ok(Some((i, concrete)));
856            }
857        }
858
859        Ok(None)
860    }
861
862    /// Whether this descriptor contains a key that has multiple derivation paths.
863    pub fn is_multipath(&self) -> bool { self.for_any_key(DescriptorPublicKey::is_multipath) }
864
865    /// Get as many descriptors as different paths in this descriptor.
866    ///
867    /// For multipath descriptors it will return as many descriptors as there is
868    /// "parallel" paths. For regular descriptors it will just return itself.
869    #[allow(clippy::blocks_in_conditions)]
870    pub fn into_single_descriptors(self) -> Result<Vec<Descriptor<DescriptorPublicKey>>, Error> {
871        // All single-path descriptors contained in this descriptor.
872        let mut descriptors = Vec::new();
873        // We (ab)use `for_any_key` to gather the number of separate descriptors.
874        if !self.for_any_key(|key| {
875            // All multipath keys must have the same number of indexes at the "multi-index"
876            // step. So we can return early if we already populated the vector.
877            if !descriptors.is_empty() {
878                return true;
879            }
880
881            match key {
882                DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => false,
883                DescriptorPublicKey::MultiXPub(xpub) => {
884                    for _ in 0..xpub.derivation_paths.paths().len() {
885                        descriptors.push(self.clone());
886                    }
887                    true
888                }
889            }
890        }) {
891            // If there is no multipath key, return early.
892            return Ok(vec![self]);
893        }
894        assert!(!descriptors.is_empty());
895
896        // Now, transform the multipath key of each descriptor into a single-key using each index.
897        struct IndexChoser(usize);
898        impl Translator<DescriptorPublicKey> for IndexChoser {
899            type TargetPk = DescriptorPublicKey;
900            type Error = Error;
901
902            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> {
903                match pk {
904                    DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => {
905                        Ok(pk.clone())
906                    }
907                    DescriptorPublicKey::MultiXPub(_) => pk
908                        .clone()
909                        .into_single_keys()
910                        .get(self.0)
911                        .cloned()
912                        .ok_or(Error::MultipathDescLenMismatch),
913                }
914            }
915            translate_hash_clone!(DescriptorPublicKey);
916        }
917
918        for (i, desc) in descriptors.iter_mut().enumerate() {
919            let mut index_choser = IndexChoser(i);
920            *desc = desc
921                .translate_pk(&mut index_choser)
922                .map_err(|e| e.expect_translator_err("No Context errors possible"))?;
923        }
924
925        Ok(descriptors)
926    }
927
928    /// Check the network consistency of all extended keys in this descriptor.
929    ///
930    /// Returns `XKeyNetwork::NoXKeys` if no extended keys are present,
931    /// `XKeyNetwork::Mixed` if extended keys have conflicting network prefixes,
932    /// or `XKeyNetwork::Single(network)` if all extended keys have the same network.
933    ///
934    /// This can be used to prevent accidentally using testnet keys on mainnet
935    /// and vice versa, which could lead to funds being sent to unspendable addresses.
936    pub fn xkey_network(&self) -> XKeyNetwork {
937        let mut first_network = None;
938
939        for key in self.iter_pk() {
940            if let Some(network) = key.xkey_network() {
941                match first_network {
942                    None => first_network = Some(network),
943                    Some(ref n) if *n != network => return XKeyNetwork::Mixed,
944                    _ => continue,
945                }
946            }
947        }
948
949        match first_network {
950            Some(network) => XKeyNetwork::Single(network),
951            None => XKeyNetwork::NoXKeys,
952        }
953    }
954}
955
956impl Descriptor<DefiniteDescriptorKey> {
957    /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
958    /// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a
959    /// default(0x02) y-coordinate.
960    ///
961    /// # Examples
962    ///
963    /// ```
964    /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
965    /// use miniscript::bitcoin::secp256k1;
966    /// use std::str::FromStr;
967    ///
968    /// // test from bip 86
969    /// let secp = secp256k1::Secp256k1::verification_only();
970    /// let descriptor = Descriptor::<DescriptorPublicKey>::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
971    ///     .expect("Valid ranged descriptor");
972    /// let result = descriptor.at_derivation_index(0).unwrap().derived_descriptor(&secp);
973    /// assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym");
974    /// ```
975    ///
976    /// # Errors
977    ///
978    /// This function will return an error if hardened derivation is attempted.
979    pub fn derived_descriptor<C: secp256k1::Verification>(
980        &self,
981        secp: &secp256k1::Secp256k1<C>,
982    ) -> Descriptor<bitcoin::PublicKey> {
983        struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
984
985        impl<C: secp256k1::Verification> Translator<DefiniteDescriptorKey> for Derivator<'_, C> {
986            type TargetPk = bitcoin::PublicKey;
987            type Error = core::convert::Infallible;
988
989            fn pk(&mut self, pk: &DefiniteDescriptorKey) -> Result<Self::TargetPk, Self::Error> {
990                Ok(pk.derive_public_key(self.0))
991            }
992
993            translate_hash_clone!(DefiniteDescriptorKey);
994        }
995
996        let derived = self.translate_pk(&mut Derivator(secp));
997        match derived {
998            Ok(derived) => derived,
999            // Impossible to hit, since deriving keys does not change any Miniscript-relevant
1000            // properties of the key.
1001            Err(e) => panic!("Context errors when deriving keys: {}", e.into_outer_err()),
1002        }
1003    }
1004
1005    /// Check the network consistency of all extended keys in this descriptor.
1006    ///
1007    /// Returns `XKeyNetwork::NoXKeys` if no extended keys are present,
1008    /// `XKeyNetwork::Mixed` if extended keys have conflicting network prefixes,
1009    /// or `XKeyNetwork::Single(network)` if all extended keys have the same network.
1010    ///
1011    /// This can be used to prevent accidentally using testnet keys on mainnet
1012    /// and vice versa, which could lead to funds being sent to unspendable addresses.
1013    pub fn xkey_network(&self) -> XKeyNetwork {
1014        let mut first_network = None;
1015
1016        for key in self.iter_pk() {
1017            if let Some(network) = key.as_descriptor_public_key().xkey_network() {
1018                match first_network {
1019                    None => first_network = Some(network),
1020                    Some(ref n) if *n != network => return XKeyNetwork::Mixed,
1021                    _ => continue,
1022                }
1023            }
1024        }
1025
1026        match first_network {
1027            Some(network) => XKeyNetwork::Single(network),
1028            None => XKeyNetwork::NoXKeys,
1029        }
1030    }
1031}
1032
1033impl<Pk: FromStrKey> crate::expression::FromTree for Descriptor<Pk> {
1034    /// Parse an expression tree into a descriptor.
1035    fn from_tree(top: expression::TreeIterItem) -> Result<Descriptor<Pk>, Error> {
1036        Ok(match (top.name(), top.n_children()) {
1037            ("pkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
1038            ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),
1039            ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?),
1040            ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),
1041            ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?),
1042            _ => Descriptor::Bare(Bare::from_tree(top)?),
1043        })
1044    }
1045}
1046
1047impl<Pk: FromStrKey> FromStr for Descriptor<Pk> {
1048    type Err = Error;
1049    fn from_str(s: &str) -> Result<Descriptor<Pk>, Error> {
1050        let top = expression::Tree::from_str(s)?;
1051        let ret = Self::from_tree(top.root())?;
1052        if let Descriptor::Tr(ref inner) = ret {
1053            // FIXME preserve weird/broken behavior from 12.x.
1054            // See https://github.com/rust-bitcoin/rust-miniscript/issues/734
1055            ret.sanity_check()?;
1056            for item in inner.leaves() {
1057                item.miniscript()
1058                    .ext_check(&crate::miniscript::analyzable::ExtParams::sane())?;
1059            }
1060        }
1061        Ok(ret)
1062    }
1063}
1064
1065impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
1066    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1067        match *self {
1068            Descriptor::Bare(ref sub) => fmt::Debug::fmt(sub, f),
1069            Descriptor::Pkh(ref pkh) => fmt::Debug::fmt(pkh, f),
1070            Descriptor::Wpkh(ref wpkh) => fmt::Debug::fmt(wpkh, f),
1071            Descriptor::Sh(ref sub) => fmt::Debug::fmt(sub, f),
1072            Descriptor::Wsh(ref sub) => fmt::Debug::fmt(sub, f),
1073            Descriptor::Tr(ref tr) => fmt::Debug::fmt(tr, f),
1074        }
1075    }
1076}
1077
1078impl<Pk: MiniscriptKey> fmt::Display for Descriptor<Pk> {
1079    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1080        match *self {
1081            Descriptor::Bare(ref sub) => fmt::Display::fmt(sub, f),
1082            Descriptor::Pkh(ref pkh) => fmt::Display::fmt(pkh, f),
1083            Descriptor::Wpkh(ref wpkh) => fmt::Display::fmt(wpkh, f),
1084            Descriptor::Sh(ref sub) => fmt::Display::fmt(sub, f),
1085            Descriptor::Wsh(ref sub) => fmt::Display::fmt(sub, f),
1086            Descriptor::Tr(ref tr) => fmt::Display::fmt(tr, f),
1087        }
1088    }
1089}
1090
1091serde_string_impl_pk!(Descriptor, "a script descriptor");
1092
1093macro_rules! write_descriptor {
1094    ($fmt:expr, $s:literal $(, $args:expr)*) => {
1095        {
1096            use fmt::Write as _;
1097
1098            let mut wrapped_f = $crate::descriptor::checksum::Formatter::new($fmt);
1099            write!(wrapped_f, $s $(, $args)*)?;
1100            wrapped_f.write_checksum_if_not_alt()?;
1101
1102            fmt::Result::Ok(())
1103        }
1104    }
1105}
1106pub(crate) use write_descriptor;
1107
1108#[cfg(test)]
1109mod tests {
1110    use core::convert::TryFrom;
1111
1112    use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV};
1113    use bitcoin::blockdata::script::Instruction;
1114    use bitcoin::blockdata::{opcodes, script};
1115    use bitcoin::hashes::Hash;
1116    use bitcoin::script::PushBytes;
1117    use bitcoin::sighash::EcdsaSighashType;
1118    use bitcoin::{bip32, PublicKey, Sequence, XOnlyPublicKey};
1119
1120    use super::{checksum, *};
1121    use crate::hex_script;
1122    #[cfg(feature = "compiler")]
1123    use crate::policy;
1124
1125    type StdDescriptor = Descriptor<PublicKey>;
1126    const TEST_PK: &str = "pk(020000000000000000000000000000000000000000000000000000000000000002)";
1127
1128    fn roundtrip_descriptor(s: &str) {
1129        let desc = Descriptor::<String>::from_str(s).unwrap();
1130        let output = desc.to_string();
1131        let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1132
1133        let mut checksum_eng = checksum::Engine::new();
1134        checksum_eng.input(&normalize_aliases).unwrap();
1135        assert_eq!(format!("{}#{}", &normalize_aliases, checksum_eng.checksum()), output);
1136    }
1137
1138    #[test]
1139    fn display_prefers_u() {
1140        // The fragments u:0 and l:0 are identical in terms of Script and
1141        // in terms of the in-memory representation -- OrI(False, False).
1142        // Test that the way we display the ambiguous fragment doesn't
1143        // change, in case somebody somehow is depending on it.
1144        let desc = StdDescriptor::from_str("sh(u:0)").unwrap();
1145        assert_eq!("sh(u:0)#ncq3yf9h", desc.to_string());
1146
1147        // This is a regression test for https://github.com/rust-bitcoin/rust-miniscript/pull/735
1148        // which was found at the same time. It's just a bug plain and simple.
1149        let desc = StdDescriptor::from_str("sh(and_n(u:0,1))").unwrap();
1150        assert_eq!("sh(and_n(u:0,1))#5j5tw8nm", desc.to_string());
1151    }
1152
1153    #[test]
1154    fn desc_rtt_tests() {
1155        roundtrip_descriptor("c:pk_k()");
1156        roundtrip_descriptor("wsh(pk())");
1157        roundtrip_descriptor("wsh(c:pk_k())");
1158        roundtrip_descriptor("c:pk_h()");
1159    }
1160    #[test]
1161    fn parse_descriptor() {
1162        StdDescriptor::from_str("(").unwrap_err();
1163        StdDescriptor::from_str("(x()").unwrap_err();
1164        StdDescriptor::from_str("(\u{7f}()3").unwrap_err();
1165        StdDescriptor::from_str("pk()").unwrap_err();
1166        StdDescriptor::from_str("nl:0").unwrap_err(); //issue 63
1167        assert_eq!(
1168            StdDescriptor::from_str("sh(sortedmulti)")
1169                .unwrap_err()
1170                .to_string(),
1171            "sortedmulti must have at least 1 children, but found 0"
1172        ); //issue 202
1173        assert_eq!(
1174            StdDescriptor::from_str(&format!("sh(sortedmulti(2,{}))", &TEST_PK[3..69]))
1175                .unwrap_err()
1176                .to_string(),
1177            "invalid threshold 2-of-1; cannot have k > n",
1178        ); //issue 202
1179
1180        StdDescriptor::from_str(TEST_PK).unwrap();
1181
1182        let uncompressed_pk =
1183        "0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1184
1185        // Context tests
1186        StdDescriptor::from_str(&format!("pk({})", uncompressed_pk)).unwrap();
1187        StdDescriptor::from_str(&format!("pkh({})", uncompressed_pk)).unwrap();
1188        StdDescriptor::from_str(&format!("sh(pk({}))", uncompressed_pk)).unwrap();
1189        StdDescriptor::from_str(&format!("wpkh({})", uncompressed_pk)).unwrap_err();
1190        StdDescriptor::from_str(&format!("sh(wpkh({}))", uncompressed_pk)).unwrap_err();
1191        StdDescriptor::from_str(&format!("wsh(pk{})", uncompressed_pk)).unwrap_err();
1192        StdDescriptor::from_str(&format!("sh(wsh(pk{}))", uncompressed_pk)).unwrap_err();
1193        StdDescriptor::from_str(&format!("or_i(pk({}),pk({}))", uncompressed_pk, uncompressed_pk))
1194            .unwrap_err();
1195    }
1196
1197    #[test]
1198    pub fn script_pubkey() {
1199        let bare = StdDescriptor::from_str(
1200            "multi(1,020000000000000000000000000000000000000000000000000000000000000002)",
1201        )
1202        .unwrap();
1203        assert_eq!(
1204            bare.script_pubkey(),
1205            hex_script(
1206                "512102000000000000000000000000000000000000000000000000000000000000000251ae"
1207            )
1208        );
1209        assert_eq!(
1210            bare.address(Network::Bitcoin).unwrap_err().to_string(),
1211            "Bare descriptors don't have address"
1212        );
1213
1214        let pk = StdDescriptor::from_str(TEST_PK).unwrap();
1215        assert_eq!(
1216            pk.script_pubkey(),
1217            ScriptBuf::from(vec![
1218                0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220                0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xac,
1221            ])
1222        );
1223
1224        let pkh = StdDescriptor::from_str(
1225            "pkh(\
1226             020000000000000000000000000000000000000000000000000000000000000002\
1227             )",
1228        )
1229        .unwrap();
1230        assert_eq!(
1231            pkh.script_pubkey(),
1232            script::Builder::new()
1233                .push_opcode(opcodes::all::OP_DUP)
1234                .push_opcode(opcodes::all::OP_HASH160)
1235                .push_slice(
1236                    hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1237                        .unwrap()
1238                        .to_byte_array()
1239                )
1240                .push_opcode(opcodes::all::OP_EQUALVERIFY)
1241                .push_opcode(opcodes::all::OP_CHECKSIG)
1242                .into_script()
1243        );
1244        assert_eq!(
1245            pkh.address(Network::Bitcoin,).unwrap().to_string(),
1246            "1D7nRvrRgzCg9kYBwhPH3j3Gs6SmsRg3Wq"
1247        );
1248
1249        let wpkh = StdDescriptor::from_str(
1250            "wpkh(\
1251             020000000000000000000000000000000000000000000000000000000000000002\
1252             )",
1253        )
1254        .unwrap();
1255        assert_eq!(
1256            wpkh.script_pubkey(),
1257            script::Builder::new()
1258                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1259                .push_slice(
1260                    hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1261                        .unwrap()
1262                        .to_byte_array()
1263                )
1264                .into_script()
1265        );
1266        assert_eq!(
1267            wpkh.address(Network::Bitcoin,).unwrap().to_string(),
1268            "bc1qsn57m9drscflq5nl76z6ny52hck5w4x5wqd9yt"
1269        );
1270
1271        let shwpkh = StdDescriptor::from_str(
1272            "sh(wpkh(\
1273             020000000000000000000000000000000000000000000000000000000000000002\
1274             ))",
1275        )
1276        .unwrap();
1277        assert_eq!(
1278            shwpkh.script_pubkey(),
1279            script::Builder::new()
1280                .push_opcode(opcodes::all::OP_HASH160)
1281                .push_slice(
1282                    hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",)
1283                        .unwrap()
1284                        .to_byte_array()
1285                )
1286                .push_opcode(opcodes::all::OP_EQUAL)
1287                .into_script()
1288        );
1289        assert_eq!(
1290            shwpkh.address(Network::Bitcoin,).unwrap().to_string(),
1291            "3PjMEzoveVbvajcnDDuxcJhsuqPHgydQXq"
1292        );
1293
1294        let sh = StdDescriptor::from_str(
1295            "sh(c:pk_k(\
1296             020000000000000000000000000000000000000000000000000000000000000002\
1297             ))",
1298        )
1299        .unwrap();
1300        assert_eq!(
1301            sh.script_pubkey(),
1302            script::Builder::new()
1303                .push_opcode(opcodes::all::OP_HASH160)
1304                .push_slice(
1305                    hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",)
1306                        .unwrap()
1307                        .to_byte_array()
1308                )
1309                .push_opcode(opcodes::all::OP_EQUAL)
1310                .into_script()
1311        );
1312        assert_eq!(
1313            sh.address(Network::Bitcoin,).unwrap().to_string(),
1314            "3HDbdvM9CQ6ASnQFUkWw6Z4t3qNwMesJE9"
1315        );
1316
1317        let wsh = StdDescriptor::from_str(
1318            "wsh(c:pk_k(\
1319             020000000000000000000000000000000000000000000000000000000000000002\
1320             ))",
1321        )
1322        .unwrap();
1323        assert_eq!(
1324            wsh.script_pubkey(),
1325            script::Builder::new()
1326                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1327                .push_slice(
1328                    sha256::Hash::from_str(
1329                        "\
1330                         f9379edc8983152dc781747830075bd5\
1331                         3896e4b0ce5bff73777fd77d124ba085\
1332                         "
1333                    )
1334                    .unwrap()
1335                    .to_byte_array()
1336                )
1337                .into_script()
1338        );
1339        assert_eq!(
1340            wsh.address(Network::Bitcoin,).unwrap().to_string(),
1341            "bc1qlymeahyfsv2jm3upw3urqp6m65ufde9seedl7umh0lth6yjt5zzsk33tv6"
1342        );
1343
1344        let shwsh = StdDescriptor::from_str(
1345            "sh(wsh(c:pk_k(\
1346             020000000000000000000000000000000000000000000000000000000000000002\
1347             )))",
1348        )
1349        .unwrap();
1350        assert_eq!(
1351            shwsh.script_pubkey(),
1352            script::Builder::new()
1353                .push_opcode(opcodes::all::OP_HASH160)
1354                .push_slice(
1355                    hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",)
1356                        .unwrap()
1357                        .to_byte_array()
1358                )
1359                .push_opcode(opcodes::all::OP_EQUAL)
1360                .into_script()
1361        );
1362        assert_eq!(
1363            shwsh.address(Network::Bitcoin,).unwrap().to_string(),
1364            "38cTksiyPT2b1uGRVbVqHdDhW9vKs84N6Z"
1365        );
1366    }
1367
1368    #[test]
1369    fn satisfy() {
1370        let secp = secp256k1::Secp256k1::new();
1371        let sk =
1372            secp256k1::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap();
1373        let pk = bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, &sk));
1374        let msg = secp256k1::Message::from_digest_slice(&b"michael was a message, amusingly"[..])
1375            .expect("32 bytes");
1376        let sig = secp.sign_ecdsa(&msg, &sk);
1377        let mut sigser = sig.serialize_der().to_vec();
1378        sigser.push(0x01); // sighash_all
1379
1380        struct SimpleSat {
1381            sig: secp256k1::ecdsa::Signature,
1382            pk: bitcoin::PublicKey,
1383        }
1384
1385        impl Satisfier<bitcoin::PublicKey> for SimpleSat {
1386            fn lookup_ecdsa_sig(
1387                &self,
1388                pk: &bitcoin::PublicKey,
1389            ) -> Option<bitcoin::ecdsa::Signature> {
1390                if *pk == self.pk {
1391                    Some(bitcoin::ecdsa::Signature {
1392                        signature: self.sig,
1393                        sighash_type: bitcoin::sighash::EcdsaSighashType::All,
1394                    })
1395                } else {
1396                    None
1397                }
1398            }
1399        }
1400
1401        let satisfier = SimpleSat { sig, pk };
1402        let ms = ms_str!("c:pk_k({})", pk);
1403
1404        let mut txin = bitcoin::TxIn {
1405            previous_output: bitcoin::OutPoint::default(),
1406            script_sig: bitcoin::ScriptBuf::new(),
1407            sequence: Sequence::from_height(100),
1408            witness: Witness::default(),
1409        };
1410        let bare = Descriptor::new_bare(ms).unwrap();
1411
1412        bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
1413        assert_eq!(
1414            txin,
1415            bitcoin::TxIn {
1416                previous_output: bitcoin::OutPoint::default(),
1417                script_sig: script::Builder::new()
1418                    .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1419                    .into_script(),
1420                sequence: Sequence::from_height(100),
1421                witness: Witness::default(),
1422            }
1423        );
1424        assert_eq!(bare.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1425
1426        let pkh = Descriptor::new_pkh(pk).unwrap();
1427        pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1428        assert_eq!(
1429            txin,
1430            bitcoin::TxIn {
1431                previous_output: bitcoin::OutPoint::default(),
1432                script_sig: script::Builder::new()
1433                    .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1434                    .push_key(&pk)
1435                    .into_script(),
1436                sequence: Sequence::from_height(100),
1437                witness: Witness::default(),
1438            }
1439        );
1440        assert_eq!(pkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1441
1442        let wpkh = Descriptor::new_wpkh(pk).unwrap();
1443        wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1444        assert_eq!(
1445            txin,
1446            bitcoin::TxIn {
1447                previous_output: bitcoin::OutPoint::default(),
1448                script_sig: bitcoin::ScriptBuf::new(),
1449                sequence: Sequence::from_height(100),
1450                witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1451            }
1452        );
1453        assert_eq!(wpkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1454
1455        let shwpkh = Descriptor::new_sh_wpkh(pk).unwrap();
1456        shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1457        let redeem_script = script::Builder::new()
1458            .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1459            .push_slice(
1460                hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab")
1461                    .unwrap()
1462                    .to_byte_array(),
1463            )
1464            .into_script();
1465        assert_eq!(
1466            txin,
1467            bitcoin::TxIn {
1468                previous_output: bitcoin::OutPoint::default(),
1469                script_sig: script::Builder::new()
1470                    .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1471                    .into_script(),
1472                sequence: Sequence::from_height(100),
1473                witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1474            }
1475        );
1476        assert_eq!(
1477            shwpkh.unsigned_script_sig(),
1478            script::Builder::new()
1479                .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1480                .into_script()
1481        );
1482
1483        let ms = ms_str!("c:pk_k({})", pk);
1484        let sh = Descriptor::new_sh(ms.clone()).unwrap();
1485        sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1486        assert_eq!(
1487            txin,
1488            bitcoin::TxIn {
1489                previous_output: bitcoin::OutPoint::default(),
1490                script_sig: script::Builder::new()
1491                    .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1492                    .push_slice(<&PushBytes>::try_from(ms.encode().as_bytes()).unwrap())
1493                    .into_script(),
1494                sequence: Sequence::from_height(100),
1495                witness: Witness::default(),
1496            }
1497        );
1498        assert_eq!(sh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1499
1500        let ms = ms_str!("c:pk_k({})", pk);
1501
1502        let wsh = Descriptor::new_wsh(ms.clone()).unwrap();
1503        wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1504        assert_eq!(
1505            txin,
1506            bitcoin::TxIn {
1507                previous_output: bitcoin::OutPoint::default(),
1508                script_sig: bitcoin::ScriptBuf::new(),
1509                sequence: Sequence::from_height(100),
1510                witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1511            }
1512        );
1513        assert_eq!(wsh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1514
1515        let shwsh = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1516        shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1517        assert_eq!(
1518            txin,
1519            bitcoin::TxIn {
1520                previous_output: bitcoin::OutPoint::default(),
1521                script_sig: script::Builder::new()
1522                    .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1523                    .into_script(),
1524                sequence: Sequence::from_height(100),
1525                witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1526            }
1527        );
1528        assert_eq!(
1529            shwsh.unsigned_script_sig(),
1530            script::Builder::new()
1531                .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1532                .into_script()
1533        );
1534    }
1535
1536    #[test]
1537    fn after_is_cltv() {
1538        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(after(1000))").unwrap();
1539        let script = descriptor.explicit_script().unwrap();
1540
1541        let actual_instructions: Vec<_> = script.instructions().collect();
1542        let check = actual_instructions.last().unwrap();
1543
1544        assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
1545    }
1546
1547    #[test]
1548    fn older_is_csv() {
1549        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(older(1000))").unwrap();
1550        let script = descriptor.explicit_script().unwrap();
1551
1552        let actual_instructions: Vec<_> = script.instructions().collect();
1553        let check = actual_instructions.last().unwrap();
1554
1555        assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
1556    }
1557
1558    #[test]
1559    fn tr_roundtrip_key() {
1560        let script = Tr::<String>::from_str("tr()").unwrap().to_string();
1561        assert_eq!(script, format!("tr()#x4ml3kxd"))
1562    }
1563
1564    #[test]
1565    fn tr_roundtrip_script() {
1566        let descriptor = Tr::<String>::from_str("tr(,{pk(),pk()})")
1567            .unwrap()
1568            .to_string();
1569
1570        assert_eq!(descriptor, "tr(,{pk(),pk()})#7dqr6v8r");
1571
1572        let descriptor = Descriptor::<String>::from_str("tr(A,{pk(B),pk(C)})")
1573            .unwrap()
1574            .to_string();
1575        assert_eq!(descriptor, "tr(A,{pk(B),pk(C)})#y0uc9t6x");
1576    }
1577
1578    #[test]
1579    fn tr_roundtrip_tree() {
1580        let p1 = "020000000000000000000000000000000000000000000000000000000000000001";
1581        let p2 = "020000000000000000000000000000000000000000000000000000000000000002";
1582        let p3 = "020000000000000000000000000000000000000000000000000000000000000003";
1583        let p4 = "020000000000000000000000000000000000000000000000000000000000000004";
1584        let p5 = "03f8551772d66557da28c1de858124f365a8eb30ce6ad79c10e0f4c546d0ab0f82";
1585        let descriptor = Tr::<PublicKey>::from_str(&format!(
1586            "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})",
1587            p1, p2, p3, p4, p5
1588        ))
1589        .unwrap();
1590
1591        // p5.to_pubkeyhash() = 516ca378e588a7ed71336147e2a72848b20aca1a
1592        assert_eq!(
1593            descriptor.to_string(),
1594            format!(
1595                "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})#tvu28c0s",
1596                p1, p2, p3, p4, p5
1597            )
1598        );
1599        assert_eq!(
1600            descriptor.spend_info().merkle_root().unwrap().to_string(),
1601            "e1597abcb76f7cbc0792cf04a9c2d4f39caed1ede0afef772064126f28c69b09"
1602        );
1603    }
1604
1605    #[test]
1606    fn tr_script_pubkey() {
1607        let key = Descriptor::<bitcoin::PublicKey>::from_str(
1608            "tr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)",
1609        )
1610        .unwrap();
1611        assert_eq!(
1612            key.script_pubkey().to_hex_string(),
1613            "51209c19294f03757da3dc235a5960631e3c55751632f5889b06b7a053bdc0bcfbcb"
1614        )
1615    }
1616
1617    #[test]
1618    fn tr_named_branch() {
1619        use crate::{ParseError, ParseTreeError};
1620
1621        assert!(matches!(
1622            StdDescriptor::from_str(
1623                "tr(0202d44008000010100000000084F0000000dd0dd00000000000201dceddd00d00,abc{0,0})"
1624            ),
1625            Err(Error::Parse(ParseError::Tree(ParseTreeError::IncorrectName {
1626                expected: "",
1627                ..
1628            }))),
1629        ));
1630    }
1631
1632    #[test]
1633    fn roundtrip_tests() {
1634        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("multi");
1635        assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal",);
1636    }
1637
1638    #[test]
1639    fn empty_thresh() {
1640        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("thresh");
1641        assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal");
1642    }
1643
1644    #[test]
1645    fn witness_stack_for_andv_is_arranged_in_correct_order() {
1646        // arrange
1647        let a = bitcoin::PublicKey::from_str(
1648            "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e",
1649        )
1650        .unwrap();
1651        let sig_a = secp256k1::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap();
1652
1653        let b = bitcoin::PublicKey::from_str(
1654            "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3",
1655        )
1656        .unwrap();
1657        let sig_b = secp256k1::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap();
1658
1659        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&format!(
1660            "wsh(and_v(v:pk({A}),pk({B})))",
1661            A = a,
1662            B = b
1663        ))
1664        .unwrap();
1665
1666        let mut txin = bitcoin::TxIn {
1667            previous_output: bitcoin::OutPoint::default(),
1668            script_sig: bitcoin::ScriptBuf::new(),
1669            sequence: Sequence::ZERO,
1670            witness: Witness::default(),
1671        };
1672        let satisfier = {
1673            let mut satisfier = BTreeMap::new();
1674
1675            satisfier.insert(
1676                a,
1677                bitcoin::ecdsa::Signature { signature: sig_a, sighash_type: EcdsaSighashType::All },
1678            );
1679            satisfier.insert(
1680                b,
1681                bitcoin::ecdsa::Signature { signature: sig_b, sighash_type: EcdsaSighashType::All },
1682            );
1683
1684            satisfier
1685        };
1686
1687        // act
1688        descriptor.satisfy(&mut txin, &satisfier).unwrap();
1689
1690        // assert
1691        let wit = txin.witness.to_vec();
1692        let witness0 = &wit[0];
1693        let witness1 = &wit[1];
1694
1695        let sig0 = secp256k1::ecdsa::Signature::from_der(&witness0[..witness0.len() - 1]).unwrap();
1696        let sig1 = secp256k1::ecdsa::Signature::from_der(&witness1[..witness1.len() - 1]).unwrap();
1697
1698        // why are we asserting this way?
1699        // The witness stack is evaluated from top to bottom. Given an `and` instruction, the left arm of the and is going to evaluate first,
1700        // meaning the next witness element (on a three element stack, that is the middle one) needs to be the signature for the left side of the `and`.
1701        // The left side of the `and` performs a CHECKSIG against public key `a` so `sig1` needs to be `sig_a` and `sig0` needs to be `sig_b`.
1702        assert_eq!(sig1, sig_a);
1703        assert_eq!(sig0, sig_b);
1704    }
1705
1706    #[test]
1707    fn test_scriptcode() {
1708        // P2WPKH (from bip143 test vectors)
1709        let descriptor = Descriptor::<PublicKey>::from_str(
1710            "wpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
1711        )
1712        .unwrap();
1713        assert_eq!(
1714            *descriptor.script_code().unwrap().as_bytes(),
1715            hex::decode_to_vec("76a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac").unwrap()[..]
1716        );
1717
1718        // P2SH-P2WPKH (from bip143 test vectors)
1719        let descriptor = Descriptor::<PublicKey>::from_str(
1720            "sh(wpkh(03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873))",
1721        )
1722        .unwrap();
1723        assert_eq!(
1724            *descriptor.script_code().unwrap().as_bytes(),
1725            hex::decode_to_vec("76a91479091972186c449eb1ded22b78e40d009bdf008988ac").unwrap()[..]
1726        );
1727
1728        // P2WSH (from bitcoind's `createmultisig`)
1729        let descriptor = Descriptor::<PublicKey>::from_str(
1730            "wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626))",
1731        )
1732        .unwrap();
1733        assert_eq!(
1734            *descriptor
1735                .script_code().unwrap()
1736                .as_bytes(),
1737            hex::decode_to_vec("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae").unwrap()[..]
1738        );
1739
1740        // P2SH-P2WSH (from bitcoind's `createmultisig`)
1741        let descriptor = Descriptor::<PublicKey>::from_str("sh(wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626)))").unwrap();
1742        assert_eq!(
1743            *descriptor
1744                .script_code().unwrap()
1745                .as_bytes(),
1746            hex::decode_to_vec("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae")
1747                .unwrap()[..]
1748        );
1749    }
1750
1751    #[test]
1752    fn parse_descriptor_key() {
1753        // With a wildcard
1754        let key = "[78412e3a/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
1755        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1756            origin: Some((
1757                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1758                (&[
1759                    bip32::ChildNumber::from_hardened_idx(44).unwrap(),
1760                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1761                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1762                ][..])
1763                .into(),
1764            )),
1765            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1766            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1767            wildcard: Wildcard::Unhardened,
1768        });
1769        assert_eq!(expected, key.parse().unwrap());
1770        assert_eq!(format!("{}", expected), key);
1771
1772        // Without origin
1773        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1";
1774        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1775            origin: None,
1776            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1777            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1778            wildcard: Wildcard::None,
1779        });
1780        assert_eq!(expected, key.parse().unwrap());
1781        assert_eq!(format!("{}", expected), key);
1782
1783        // Testnet tpub
1784        let key = "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed/1";
1785        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1786            origin: None,
1787            xkey: bip32::Xpub::from_str("tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed").unwrap(),
1788            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1789            wildcard: Wildcard::None,
1790        });
1791        assert_eq!(expected, key.parse().unwrap());
1792        assert_eq!(format!("{}", expected), key);
1793
1794        // Without derivation path
1795        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
1796        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1797            origin: None,
1798            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1799            derivation_path: bip32::DerivationPath::from(&[][..]),
1800            wildcard: Wildcard::None,
1801        });
1802        assert_eq!(expected, key.parse().unwrap());
1803        assert_eq!(format!("{}", expected), key);
1804
1805        // Raw (compressed) pubkey
1806        let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8";
1807        let expected = DescriptorPublicKey::Single(SinglePub {
1808            key: SinglePubKey::FullKey(
1809                bitcoin::PublicKey::from_str(
1810                    "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
1811                )
1812                .unwrap(),
1813            ),
1814            origin: None,
1815        });
1816        assert_eq!(expected, key.parse().unwrap());
1817        assert_eq!(format!("{}", expected), key);
1818
1819        // Raw (uncompressed) pubkey
1820        let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a";
1821        let expected = DescriptorPublicKey::Single(SinglePub {
1822            key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str(
1823                "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a",
1824            )
1825            .unwrap()),
1826            origin: None,
1827        });
1828        assert_eq!(expected, key.parse().unwrap());
1829        assert_eq!(format!("{}", expected), key);
1830
1831        // Raw pubkey with origin
1832        let desc =
1833            "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8";
1834        let expected = DescriptorPublicKey::Single(SinglePub {
1835            key: SinglePubKey::FullKey(
1836                bitcoin::PublicKey::from_str(
1837                    "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8",
1838                )
1839                .unwrap(),
1840            ),
1841            origin: Some((
1842                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1843                (&[
1844                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1845                    bip32::ChildNumber::from_normal_idx(42).unwrap(),
1846                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1847                ][..])
1848                    .into(),
1849            )),
1850        });
1851        assert_eq!(expected, desc.parse().expect("Parsing desc"));
1852        assert_eq!(format!("{}", expected), desc);
1853    }
1854
1855    #[test]
1856    fn test_sortedmulti() {
1857        fn _test_sortedmulti(raw_desc_one: &str, raw_desc_two: &str, raw_addr_expected: &str) {
1858            let secp_ctx = secp256k1::Secp256k1::verification_only();
1859            let index = 5;
1860
1861            // Parse descriptor
1862            let desc_one = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_one).unwrap();
1863            let desc_two = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_two).unwrap();
1864
1865            // Same string formatting
1866            assert_eq!(desc_one.to_string(), raw_desc_one);
1867            assert_eq!(desc_two.to_string(), raw_desc_two);
1868
1869            // Same address
1870            let addr_one = desc_one
1871                .at_derivation_index(index)
1872                .unwrap()
1873                .derived_descriptor(&secp_ctx)
1874                .address(bitcoin::Network::Bitcoin)
1875                .unwrap();
1876            let addr_two = desc_two
1877                .at_derivation_index(index)
1878                .unwrap()
1879                .derived_descriptor(&secp_ctx)
1880                .address(bitcoin::Network::Bitcoin)
1881                .unwrap();
1882            let addr_expected = bitcoin::Address::from_str(raw_addr_expected)
1883                .unwrap()
1884                .assume_checked();
1885            assert_eq!(addr_one, addr_expected);
1886            assert_eq!(addr_two, addr_expected);
1887        }
1888
1889        // P2SH and pubkeys
1890        _test_sortedmulti(
1891            "sh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#uetvewm2",
1892            "sh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#7l8smyg9",
1893            "3JZJNxvDKe6Y55ZaF5223XHwfF2eoMNnoV",
1894        );
1895
1896        // P2WSH and single-xpub descriptor
1897        _test_sortedmulti(
1898            "wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#7etm7zk7",
1899            "wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#ppmeel9k",
1900            "bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a",
1901        );
1902
1903        // P2WSH-P2SH and ranged descriptor
1904        _test_sortedmulti(
1905            "sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#u60cee0u",
1906            "sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#75dkf44w",
1907            "325zcVBN5o2eqqqtGwPjmtDd8dJRyYP82s",
1908        );
1909    }
1910
1911    #[test]
1912    fn test_parse_descriptor() {
1913        let secp = &secp256k1::Secp256k1::signing_only();
1914        let (descriptor, key_map) = Descriptor::parse_descriptor(secp, "wpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
1915        assert_eq!(descriptor.to_string(), "wpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#nhdxg96s");
1916        assert_eq!(key_map.len(), 1);
1917
1918        // https://github.com/bitcoin/bitcoin/blob/7ae86b3c6845873ca96650fc69beb4ae5285c801/src/test/descriptor_tests.cpp#L355-L360
1919        macro_rules! check_invalid_checksum {
1920            ($secp: ident,$($desc: expr),*) => {
1921                use crate::{ParseError, ParseTreeError};
1922                $(
1923                    match Descriptor::parse_descriptor($secp, $desc) {
1924                        Err(Error::Parse(ParseError::Tree(ParseTreeError::Checksum(_)))) => {},
1925                        Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
1926                        _ => panic!("Invalid checksum treated as valid: {}", $desc),
1927                    };
1928                )*
1929            };
1930        }
1931        check_invalid_checksum!(secp,
1932            "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#",
1933            "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#",
1934            "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfyq",
1935            "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5tq",
1936            "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
1937            "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5",
1938            "sh(multi(3,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy",
1939            "sh(multi(3,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t",
1940            "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjq09x4t",
1941            "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))##ggssrxfy",
1942            "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
1943        );
1944
1945        Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy").expect("Valid descriptor with checksum");
1946        Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t").expect("Valid descriptor with checksum");
1947    }
1948
1949    #[test]
1950    #[cfg(feature = "compiler")]
1951    fn parse_and_derive() {
1952        let descriptor_str = "thresh(2,\
1953pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*),\
1954pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1955pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1956        let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1957        let descriptor = Descriptor::new_sh(policy.compile().unwrap()).unwrap();
1958        let definite_descriptor = descriptor.at_derivation_index(42).unwrap();
1959
1960        let res_descriptor_str = "thresh(2,\
1961pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\
1962pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1963pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1964        let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
1965            res_descriptor_str.parse().unwrap();
1966        let res_descriptor = Descriptor::new_sh(res_policy.compile().unwrap()).unwrap();
1967
1968        assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string());
1969    }
1970
1971    #[test]
1972    fn parse_with_secrets() {
1973        let secp = &secp256k1::Secp256k1::signing_only();
1974        let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#v20xlvm9";
1975        let (descriptor, keymap) =
1976            Descriptor::<DescriptorPublicKey>::parse_descriptor(secp, descriptor_str).unwrap();
1977
1978        let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#u37l7u8u";
1979        assert_eq!(expected, descriptor.to_string());
1980        assert_eq!(keymap.len(), 1);
1981
1982        // try to turn it back into a string with the secrets
1983        assert_eq!(descriptor_str, descriptor.to_string_with_secret(&keymap));
1984    }
1985
1986    #[test]
1987    fn checksum_for_nested_sh() {
1988        let descriptor_str = "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))";
1989        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1990        assert_eq!(descriptor.to_string(), "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))#tjp2zm88");
1991
1992        let descriptor_str = "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))";
1993        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1994        assert_eq!(descriptor.to_string(), "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))#6c6hwr22");
1995    }
1996
1997    #[test]
1998    fn test_xonly_keys() {
1999        let comp_key = "0308c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2000        let x_only_key = "08c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2001
2002        // Both x-only keys and comp keys allowed in tr
2003        Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", comp_key)).unwrap();
2004        Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", x_only_key)).unwrap();
2005
2006        // Only compressed keys allowed in wsh
2007        Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
2008        Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", x_only_key))
2009            .unwrap_err();
2010    }
2011
2012    #[test]
2013    fn test_find_derivation_index_for_spk() {
2014        let secp = secp256k1::Secp256k1::verification_only();
2015        let descriptor = Descriptor::from_str("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
2016        let script_at_0_1 = ScriptBuf::from_hex(
2017            "5120a82f29944d65b86ae6b5e5cc75e294ead6c59391a1edc5e016e3498c67fc7bbb",
2018        )
2019        .unwrap();
2020        let expected_concrete = Descriptor::from_str(
2021            "tr(0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145)",
2022        )
2023        .unwrap();
2024
2025        assert_eq!(descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..1), Ok(None));
2026        assert_eq!(
2027            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..2),
2028            Ok(Some((1, expected_concrete.clone())))
2029        );
2030        assert_eq!(
2031            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..10),
2032            Ok(Some((1, expected_concrete)))
2033        );
2034    }
2035
2036    #[test]
2037    fn display_alternate() {
2038        let bare = StdDescriptor::from_str(
2039            "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2040        )
2041        .unwrap();
2042        assert_eq!(
2043            format!("{}", bare),
2044            "pk(020000000000000000000000000000000000000000000000000000000000000002)#7yxkn84h",
2045        );
2046        assert_eq!(
2047            format!("{:#}", bare),
2048            "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2049        );
2050
2051        let pkh = StdDescriptor::from_str(
2052            "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2053        )
2054        .unwrap();
2055        assert_eq!(
2056            format!("{}", pkh),
2057            "pkh(020000000000000000000000000000000000000000000000000000000000000002)#ma7nspkf",
2058        );
2059        assert_eq!(
2060            format!("{:#}", pkh),
2061            "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2062        );
2063
2064        let wpkh = StdDescriptor::from_str(
2065            "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2066        )
2067        .unwrap();
2068        assert_eq!(
2069            format!("{}", wpkh),
2070            "wpkh(020000000000000000000000000000000000000000000000000000000000000002)#d3xz2xye",
2071        );
2072        assert_eq!(
2073            format!("{:#}", wpkh),
2074            "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2075        );
2076
2077        let shwpkh = StdDescriptor::from_str(
2078            "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2079        )
2080        .unwrap();
2081        assert_eq!(
2082            format!("{}", shwpkh),
2083            "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))#45zpjtet",
2084        );
2085        assert_eq!(
2086            format!("{:#}", shwpkh),
2087            "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2088        );
2089
2090        let wsh = StdDescriptor::from_str("wsh(1)").unwrap();
2091        assert_eq!(format!("{}", wsh), "wsh(1)#mrg7xj7p");
2092        assert_eq!(format!("{:#}", wsh), "wsh(1)");
2093
2094        let sh = StdDescriptor::from_str("sh(1)").unwrap();
2095        assert_eq!(format!("{}", sh), "sh(1)#l8r75ggs");
2096        assert_eq!(format!("{:#}", sh), "sh(1)");
2097
2098        let shwsh = StdDescriptor::from_str("sh(wsh(1))").unwrap();
2099        assert_eq!(format!("{}", shwsh), "sh(wsh(1))#hcyfl07f");
2100        assert_eq!(format!("{:#}", shwsh), "sh(wsh(1))");
2101
2102        let tr = StdDescriptor::from_str(
2103            "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2104        )
2105        .unwrap();
2106        assert_eq!(
2107            format!("{}", tr),
2108            "tr(020000000000000000000000000000000000000000000000000000000000000002)#8hc7wq5h",
2109        );
2110        assert_eq!(
2111            format!("{:#}", tr),
2112            "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2113        );
2114    }
2115
2116    #[test]
2117    fn multipath_descriptors() {
2118        // We can parse a multipath descriptors, and make it into separate single-path descriptors.
2119        let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))").unwrap();
2120        assert!(desc.is_multipath());
2121        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2122            Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))").unwrap(),
2123            Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))").unwrap(),
2124            Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/20/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/987/*)))").unwrap()
2125        ]);
2126
2127        // Even if only one of the keys is multipath.
2128        let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2129        assert!(desc.is_multipath());
2130        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2131            Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2132            Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2133        ]);
2134
2135        // We can detect regular single-path descriptors.
2136        let notmulti_desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2137        assert!(!notmulti_desc.is_multipath());
2138        assert_eq!(notmulti_desc.clone().into_single_descriptors().unwrap(), vec![notmulti_desc]);
2139
2140        // We refuse to parse multipath descriptors with a mismatch in the number of derivation paths between keys.
2141        Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))").unwrap_err();
2142        Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))").unwrap_err();
2143    }
2144
2145    #[test]
2146    fn regression_736() {
2147        Descriptor::<DescriptorPublicKey>::from_str(
2148            "tr(0000000000000000000000000000000000000000000000000000000000000002,)",
2149        )
2150        .unwrap_err();
2151    }
2152
2153    #[test]
2154    fn regression_734() {
2155        Descriptor::<DescriptorPublicKey>::from_str(
2156            "wsh(or_i(pk(0202baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a),1))",
2157        )
2158        .unwrap();
2159        Descriptor::<DescriptorPublicKey>::from_str(
2160            "sh(or_i(pk(0202baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a),1))",
2161        )
2162        .unwrap();
2163        Descriptor::<DescriptorPublicKey>::from_str(
2164            "tr(02baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a,1)",
2165        )
2166        .unwrap_err();
2167    }
2168
2169    #[test]
2170    fn tr_lift() {
2171        use crate::policy::Liftable as _;
2172
2173        // Taproot structure is erased but key order preserved..
2174        let desc = Descriptor::<String>::from_str("tr(ROOT,{pk(A1),{pk(B1),pk(B2)}})").unwrap();
2175        let lift = desc.lift().unwrap();
2176        assert_eq!(lift.to_string(), "or(pk(ROOT),or(pk(A1),pk(B1),pk(B2)))",);
2177        let desc = Descriptor::<String>::from_str("tr(ROOT,{{pk(A1),pk(B1)},pk(B2)})").unwrap();
2178        let lift = desc.lift().unwrap();
2179        assert_eq!(lift.to_string(), "or(pk(ROOT),or(pk(A1),pk(B1),pk(B2)))",);
2180
2181        // And normalization happens
2182        let desc = Descriptor::<String>::from_str("tr(ROOT,{0,{0,0}})").unwrap();
2183        let lift = desc.lift().unwrap();
2184        assert_eq!(lift.to_string(), "or(pk(ROOT),UNSATISFIABLE)",);
2185    }
2186
2187    #[test]
2188    fn test_context_pks() {
2189        let comp_key = bitcoin::PublicKey::from_str(
2190            "02015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2191        )
2192        .unwrap();
2193        let x_only_key = bitcoin::key::XOnlyPublicKey::from_str(
2194            "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2195        )
2196        .unwrap();
2197        let uncomp_key = bitcoin::PublicKey::from_str("04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4").unwrap();
2198
2199        type Desc = Descriptor<DescriptorPublicKey>;
2200
2201        // Legacy tests, x-only keys are not supported
2202        Desc::from_str(&format!("sh(pk({}))", comp_key)).unwrap();
2203        Desc::from_str(&format!("sh(pk({}))", uncomp_key)).unwrap();
2204        Desc::from_str(&format!("sh(pk({}))", x_only_key)).unwrap_err();
2205
2206        // bare tests, x-only keys not supported
2207        Desc::from_str(&format!("pk({})", comp_key)).unwrap();
2208        Desc::from_str(&format!("pk({})", uncomp_key)).unwrap();
2209        Desc::from_str(&format!("pk({})", x_only_key)).unwrap_err();
2210
2211        // pkh tests, x-only keys not supported
2212        Desc::from_str(&format!("pkh({})", comp_key)).unwrap();
2213        Desc::from_str(&format!("pkh({})", uncomp_key)).unwrap();
2214        Desc::from_str(&format!("pkh({})", x_only_key)).unwrap_err();
2215
2216        // wpkh tests, uncompressed and x-only keys not supported
2217        Desc::from_str(&format!("wpkh({})", comp_key)).unwrap();
2218        Desc::from_str(&format!("wpkh({})", uncomp_key)).unwrap_err();
2219        Desc::from_str(&format!("wpkh({})", x_only_key)).unwrap_err();
2220
2221        // Segwitv0 tests, uncompressed and x-only keys not supported
2222        Desc::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
2223        Desc::from_str(&format!("wsh(pk({}))", uncomp_key)).unwrap_err();
2224        Desc::from_str(&format!("wsh(pk({}))", x_only_key)).unwrap_err();
2225
2226        // Tap tests, key path
2227        Desc::from_str(&format!("tr({})", comp_key)).unwrap();
2228        Desc::from_str(&format!("tr({})", uncomp_key)).unwrap_err();
2229        Desc::from_str(&format!("tr({})", x_only_key)).unwrap();
2230
2231        // Tap tests, script path
2232        Desc::from_str(&format!("tr({},pk({}))", x_only_key, comp_key)).unwrap();
2233        Desc::from_str(&format!("tr({},pk({}))", x_only_key, uncomp_key)).unwrap_err();
2234        Desc::from_str(&format!("tr({},pk({}))", x_only_key, x_only_key)).unwrap();
2235    }
2236
2237    #[test]
2238    fn regression_806() {
2239        let secp = secp256k1::Secp256k1::signing_only();
2240        type Desc = Descriptor<DescriptorPublicKey>;
2241        // OK
2242        Desc::from_str("pkh(111111111111111111111111111111110000008375319363688624584A111111)")
2243            .unwrap_err();
2244        // ERR: crashes in translate_pk
2245        Desc::parse_descriptor(
2246            &secp,
2247            "pkh(111111111111111111111111111111110000008375319363688624584A111111)",
2248        )
2249        .unwrap_err();
2250    }
2251
2252    #[test]
2253    fn convert_public_key_descriptor_to_definite_key() {
2254        let descriptor_str = "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))";
2255        let full_pk_descriptor: Descriptor<PublicKey> =
2256            Descriptor::from_str(descriptor_str).unwrap();
2257
2258        struct TranslateFullPk;
2259
2260        impl Translator<bitcoin::PublicKey> for TranslateFullPk {
2261            type TargetPk = DefiniteDescriptorKey;
2262            type Error = core::convert::Infallible;
2263
2264            fn pk(
2265                &mut self,
2266                pk: &bitcoin::PublicKey,
2267            ) -> Result<DefiniteDescriptorKey, Self::Error> {
2268                Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2269                    .expect("DescriptorPublicKey from PublicKey has no wildcards"))
2270            }
2271
2272            translate_hash_clone!(bitcoin::PublicKey, DefiniteDescriptorKey, Self::Error);
2273        }
2274
2275        let converted_descriptor = full_pk_descriptor
2276            .translate_pk(&mut TranslateFullPk)
2277            .expect("infallible");
2278
2279        assert_eq!(full_pk_descriptor.to_string(), converted_descriptor.to_string());
2280
2281        let xonly_descriptor_str = "tr(1d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,pk(02c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))";
2282        let xonly_pk_descriptor: Descriptor<XOnlyPublicKey> =
2283            Descriptor::from_str(xonly_descriptor_str).unwrap();
2284
2285        struct TranslateXOnlyPk;
2286
2287        impl Translator<XOnlyPublicKey> for TranslateXOnlyPk {
2288            type TargetPk = DefiniteDescriptorKey;
2289            type Error = core::convert::Infallible;
2290
2291            fn pk(&mut self, pk: &XOnlyPublicKey) -> Result<DefiniteDescriptorKey, Self::Error> {
2292                Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2293                    .expect("DescriptorPublicKey from XOnlyPublicKey has no wildcards"))
2294            }
2295
2296            translate_hash_clone!(XOnlyPublicKey, DefiniteDescriptorKey, Self::Error);
2297        }
2298
2299        let xonly_converted_descriptor = xonly_pk_descriptor
2300            .translate_pk(&mut TranslateXOnlyPk)
2301            .expect("infallible");
2302
2303        assert_eq!(xonly_pk_descriptor.to_string(), xonly_converted_descriptor.to_string());
2304    }
2305
2306    #[test]
2307    fn test_iter_pk() {
2308        // Test Bare descriptor
2309        let bare_desc = Descriptor::<PublicKey>::from_str(
2310            "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2311        )
2312        .unwrap();
2313        let keys: Vec<_> = bare_desc.iter_pk().collect();
2314        assert_eq!(keys.len(), 1);
2315        assert_eq!(
2316            keys[0].to_string(),
2317            "020000000000000000000000000000000000000000000000000000000000000002"
2318        );
2319
2320        // Test Pkh descriptor
2321        let pkh_desc = Descriptor::<PublicKey>::from_str(
2322            "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2323        )
2324        .unwrap();
2325        let keys: Vec<_> = pkh_desc.iter_pk().collect();
2326        assert_eq!(keys.len(), 1);
2327        assert_eq!(
2328            keys[0].to_string(),
2329            "020000000000000000000000000000000000000000000000000000000000000002"
2330        );
2331
2332        // Test Wpkh descriptor
2333        let wpkh_desc = Descriptor::<PublicKey>::from_str(
2334            "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2335        )
2336        .unwrap();
2337        let keys: Vec<_> = wpkh_desc.iter_pk().collect();
2338        assert_eq!(keys.len(), 1);
2339        assert_eq!(
2340            keys[0].to_string(),
2341            "020000000000000000000000000000000000000000000000000000000000000002"
2342        );
2343
2344        // Test Sh descriptor with a miniscript
2345        let sh_desc = Descriptor::<PublicKey>::from_str(
2346            "sh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2347        ).unwrap();
2348        let keys: Vec<_> = sh_desc.iter_pk().collect();
2349        assert_eq!(keys.len(), 2);
2350        assert_eq!(
2351            keys[0].to_string(),
2352            "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2353        );
2354        assert_eq!(
2355            keys[1].to_string(),
2356            "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2357        );
2358
2359        // Test Sh-Wpkh descriptor
2360        let shwpkh_desc = Descriptor::<PublicKey>::from_str(
2361            "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2362        )
2363        .unwrap();
2364        let keys: Vec<_> = shwpkh_desc.iter_pk().collect();
2365        assert_eq!(keys.len(), 1);
2366        assert_eq!(
2367            keys[0].to_string(),
2368            "020000000000000000000000000000000000000000000000000000000000000002"
2369        );
2370
2371        // Test Sh-Wsh descriptor
2372        let shwsh_desc = Descriptor::<PublicKey>::from_str(
2373            "sh(wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))))"
2374        ).unwrap();
2375        let keys: Vec<_> = shwsh_desc.iter_pk().collect();
2376        assert_eq!(keys.len(), 2);
2377        assert_eq!(
2378            keys[0].to_string(),
2379            "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2380        );
2381        assert_eq!(
2382            keys[1].to_string(),
2383            "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2384        );
2385
2386        // Test Wsh descriptor
2387        let wsh_desc = Descriptor::<PublicKey>::from_str(
2388            "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2389        ).unwrap();
2390        let keys: Vec<_> = wsh_desc.iter_pk().collect();
2391        assert_eq!(keys.len(), 2);
2392        assert_eq!(
2393            keys[0].to_string(),
2394            "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2395        );
2396        assert_eq!(
2397            keys[1].to_string(),
2398            "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2399        );
2400
2401        // Test SortedMulti descriptors
2402        let sortedmulti_desc = Descriptor::<PublicKey>::from_str(
2403            "sh(sortedmulti(2,021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))"
2404        ).unwrap();
2405        let keys: Vec<_> = sortedmulti_desc.iter_pk().collect();
2406        assert_eq!(keys.len(), 3);
2407        // Keys are sorted in the output
2408        assert!(keys.iter().any(|k| k.to_string()
2409            == "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"));
2410        assert!(keys.iter().any(|k| k.to_string()
2411            == "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"));
2412        assert!(keys.iter().any(|k| k.to_string()
2413            == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556"));
2414
2415        // Test Taproot descriptor with only key path
2416        let tr_key_only_desc = Descriptor::<PublicKey>::from_str(
2417            "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2418        )
2419        .unwrap();
2420        let keys: Vec<_> = tr_key_only_desc.iter_pk().collect();
2421        assert_eq!(keys.len(), 1);
2422        assert_eq!(
2423            keys[0].to_string(),
2424            "020000000000000000000000000000000000000000000000000000000000000002"
2425        );
2426
2427        // Test Taproot descriptor with script path
2428        // The internal key should be yielded first
2429        let internal_key = "020000000000000000000000000000000000000000000000000000000000000002";
2430        let script_key1 = "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b";
2431        let script_key2 = "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6";
2432
2433        let tr_with_script_desc = Descriptor::<PublicKey>::from_str(&format!(
2434            "tr({},{{pk({}),pk({})}})",
2435            internal_key, script_key1, script_key2,
2436        ))
2437        .unwrap();
2438
2439        let keys: Vec<_> = tr_with_script_desc.iter_pk().collect();
2440        assert_eq!(keys.len(), 3);
2441
2442        // Verify internal key is first
2443        assert_eq!(keys[0].to_string(), internal_key);
2444
2445        // Verify other keys are present (order after internal key is not guaranteed)
2446        assert!(keys[1..].iter().any(|k| k.to_string() == script_key1));
2447        assert!(keys[1..].iter().any(|k| k.to_string() == script_key2));
2448
2449        // Test Taproot descriptor with complex script tree
2450        let tr_complex_desc = Descriptor::<PublicKey>::from_str(&format!(
2451            "tr({},{{pk({}),{{pk({}),or_d(pk({}),pk({}))}}}})",
2452            internal_key,
2453            script_key1,
2454            script_key2,
2455            "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556",
2456            "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
2457        ))
2458        .unwrap();
2459
2460        let keys: Vec<_> = tr_complex_desc.iter_pk().collect();
2461        assert_eq!(keys.len(), 5);
2462
2463        // Verify internal key is first
2464        assert_eq!(keys[0].to_string(), internal_key);
2465
2466        // Verify all other keys are present
2467        assert!(keys[1..].iter().any(|k| k.to_string() == script_key1));
2468        assert!(keys[1..].iter().any(|k| k.to_string() == script_key2));
2469        assert!(keys[1..].iter().any(|k| k.to_string()
2470            == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556"));
2471        assert!(keys[1..].iter().any(|k| k.to_string()
2472            == "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"));
2473    }
2474
2475    // Helper function to provide unique test keys for multi-key scenarios
2476    fn test_keys() -> (Vec<&'static str>, Vec<&'static str>, Vec<&'static str>) {
2477        // Unique mainnet xpubs
2478        let mainnet_xpubs = vec![
2479            "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
2480            "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
2481            "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
2482            "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
2483        ];
2484
2485        // Unique testnet tpubs
2486        let testnet_tpubs = vec![
2487            "tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi",
2488            "tpubD6NzVbkrYhZ4WQdzxL7NmJN7b85ePo4p6RSj9QQHF7te2RR9iUeVSGgnGkoUsB9LBRosgvNbjRv9bcsJgzgBd7QKuxDm23ZewkTRzNSLEDr",
2489            "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed",
2490            "tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz",
2491        ];
2492
2493        // Unique single public keys
2494        let single_keys = vec![
2495            "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b",
2496            "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357",
2497            "022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01",
2498            "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb",
2499        ];
2500
2501        (mainnet_xpubs, testnet_tpubs, single_keys)
2502    }
2503
2504    #[test]
2505    fn test_descriptor_pubkey_xkey_network() {
2506        use core::str::FromStr;
2507
2508        use bitcoin::NetworkKind;
2509
2510        use crate::descriptor::{DescriptorPublicKey, XKeyNetwork};
2511
2512        let (mainnet_xpubs, testnet_tpubs, single_keys) = test_keys();
2513
2514        // Basic single key scenarios
2515        let basic_tests = vec![
2516            // Single mainnet xpub
2517            (format!("wpkh({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2518            // Single testnet tpub
2519            (format!("wpkh({})", testnet_tpubs[0]), XKeyNetwork::Single(NetworkKind::Test)),
2520            // Single public key (no extended keys)
2521            (format!("wpkh({})", single_keys[0]), XKeyNetwork::NoXKeys),
2522        ];
2523
2524        for (desc_str, expected) in basic_tests {
2525            let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2526            assert_eq!(desc.xkey_network(), expected, "Failed for basic descriptor: {}", desc_str);
2527        }
2528
2529        // Multi-key descriptor combinations with unique keys
2530        let multi_key_tests = vec![
2531            // Mixed networks: mainnet + testnet
2532            (
2533                format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], testnet_tpubs[0]),
2534                XKeyNetwork::Mixed,
2535            ),
2536            // Consistent mainnet keys
2537            (
2538                format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], mainnet_xpubs[1]),
2539                XKeyNetwork::Single(NetworkKind::Main),
2540            ),
2541            // Consistent testnet multisig
2542            (
2543                format!(
2544                    "wsh(multi(2,{},{},{}))",
2545                    testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2]
2546                ),
2547                XKeyNetwork::Single(NetworkKind::Test),
2548            ),
2549            // Sorted multisig with mixed key types
2550            (
2551                format!(
2552                    "wsh(sortedmulti(2,{},{},{}))",
2553                    mainnet_xpubs[0], testnet_tpubs[0], single_keys[0]
2554                ),
2555                XKeyNetwork::Mixed,
2556            ),
2557            // 3-of-4 multisig with all mainnet keys
2558            (
2559                format!(
2560                    "wsh(multi(3,{},{},{},{}))",
2561                    mainnet_xpubs[0], mainnet_xpubs[1], mainnet_xpubs[2], mainnet_xpubs[3]
2562                ),
2563                XKeyNetwork::Single(NetworkKind::Main),
2564            ),
2565        ];
2566
2567        for (desc_str, expected) in multi_key_tests {
2568            let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2569            assert_eq!(
2570                desc.xkey_network(),
2571                expected,
2572                "Failed for multi-key descriptor: {}",
2573                desc_str
2574            );
2575        }
2576
2577        // Threshold and logical operator tests
2578        let threshold_tests = vec![
2579            // Threshold with mixed key types
2580            (
2581                format!(
2582                    "wsh(thresh(2,c:pk_k({}),sc:pk_k({}),sc:pk_k({})))",
2583                    single_keys[0], mainnet_xpubs[0], testnet_tpubs[0]
2584                ),
2585                XKeyNetwork::Mixed,
2586            ),
2587            // OR with mixed networks
2588            (
2589                format!("wsh(or_d(pk({}),pk({})))", mainnet_xpubs[0], testnet_tpubs[0]),
2590                XKeyNetwork::Mixed,
2591            ),
2592            // AND with consistent mainnet keys
2593            (
2594                format!("wsh(and_v(v:pk({}),pk({})))", mainnet_xpubs[0], mainnet_xpubs[1]),
2595                XKeyNetwork::Single(NetworkKind::Main),
2596            ),
2597            // Complex threshold with all testnet keys
2598            (
2599                format!(
2600                    "wsh(thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({})))",
2601                    testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2], testnet_tpubs[3]
2602                ),
2603                XKeyNetwork::Single(NetworkKind::Test),
2604            ),
2605        ];
2606
2607        for (desc_str, expected) in threshold_tests {
2608            let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2609            assert_eq!(
2610                desc.xkey_network(),
2611                expected,
2612                "Failed for threshold descriptor: {}",
2613                desc_str
2614            );
2615        }
2616
2617        // Taproot and complex miniscript tests
2618        let complex_tests = vec![
2619            // Taproot with mixed networks
2620            (format!("tr({},pk({}))", mainnet_xpubs[0], testnet_tpubs[0]), XKeyNetwork::Mixed),
2621            // Taproot with consistent mainnet keys
2622            (format!("tr({},pk({}))", mainnet_xpubs[0], mainnet_xpubs[1]), XKeyNetwork::Single(NetworkKind::Main)),
2623            // HTLC-like pattern with mixed networks
2624            (format!("wsh(andor(pk({}),sha256(1111111111111111111111111111111111111111111111111111111111111111),and_v(v:pkh({}),older(144))))", mainnet_xpubs[0], testnet_tpubs[0]), XKeyNetwork::Mixed),
2625            // Multi-path spending with testnet keys
2626            (format!("wsh(or_d(multi(2,{},{}),and_v(v:pk({}),older(1000))))", testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2]), XKeyNetwork::Single(NetworkKind::Test)),
2627            // Nested conditions with only single keys
2628            (format!("wsh(thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({})))", single_keys[0], single_keys[1], single_keys[2], single_keys[3]), XKeyNetwork::NoXKeys),
2629            // Complex pattern with mainnet keys
2630            (format!("wsh(or_d(multi(2,{},{}),and_v(v:pk({}),older(1000))))", mainnet_xpubs[0], mainnet_xpubs[1], mainnet_xpubs[2]), XKeyNetwork::Single(NetworkKind::Main)),
2631        ];
2632
2633        for (desc_str, expected) in complex_tests {
2634            let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2635            assert_eq!(
2636                desc.xkey_network(),
2637                expected,
2638                "Failed for complex descriptor: {}",
2639                desc_str
2640            );
2641        }
2642    }
2643
2644    #[test]
2645    fn test_definite_descriptor_key_xkey_network() {
2646        use core::str::FromStr;
2647
2648        use bitcoin::NetworkKind;
2649
2650        use crate::descriptor::{DefiniteDescriptorKey, XKeyNetwork};
2651
2652        let (mainnet_xpubs, testnet_tpubs, single_keys) = test_keys();
2653
2654        // DefiniteDescriptorKey tests (no wildcards, specific derivation paths)
2655        let definite_key_tests = vec![
2656            // Basic single key scenarios
2657            (format!("wpkh({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2658            (format!("wpkh({})", testnet_tpubs[0]), XKeyNetwork::Single(NetworkKind::Test)),
2659            (format!("wpkh({})", single_keys[0]), XKeyNetwork::NoXKeys),
2660            // Multi-key scenarios with specific derivation paths
2661            (
2662                format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], testnet_tpubs[0]),
2663                XKeyNetwork::Mixed,
2664            ),
2665            (
2666                format!("wsh(multi(2,{}/0,{}/1))", testnet_tpubs[0], testnet_tpubs[1]),
2667                XKeyNetwork::Single(NetworkKind::Test),
2668            ),
2669            (
2670                format!("wsh(multi(2,{}/0,{}/1))", mainnet_xpubs[0], mainnet_xpubs[1]),
2671                XKeyNetwork::Single(NetworkKind::Main),
2672            ),
2673            // Sorted multisig with specific paths
2674            (
2675                format!(
2676                    "wsh(sortedmulti(2,{}/0,{}/1,{}))",
2677                    mainnet_xpubs[0], testnet_tpubs[0], single_keys[0]
2678                ),
2679                XKeyNetwork::Mixed,
2680            ),
2681            // Taproot scenarios
2682            (format!("tr({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2683            (
2684                format!("tr({},pk({}/0))", mainnet_xpubs[0], testnet_tpubs[0]),
2685                XKeyNetwork::Mixed,
2686            ),
2687        ];
2688
2689        for (desc_str, expected) in definite_key_tests {
2690            let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc_str).unwrap();
2691            assert_eq!(
2692                desc.xkey_network(),
2693                expected,
2694                "Failed for DefiniteDescriptorKey: {}",
2695                desc_str
2696            );
2697        }
2698    }
2699}