1use 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 self::checksum::verify_checksum;
25use crate::miniscript::decode::Terminal;
26use crate::miniscript::{satisfy, Legacy, Miniscript, Segwitv0};
27use crate::plan::{AssetProvider, Plan};
28use crate::prelude::*;
29use crate::{
30 expression, hash256, BareCtx, Error, ForEachKey, FromStrKey, MiniscriptKey, Satisfier,
31 ToPublicKey, TranslateErr, TranslatePk, Translator,
32};
33
34mod bare;
35mod segwitv0;
36mod sh;
37mod sortedmulti;
38mod tr;
39
40pub use self::bare::{Bare, Pkh};
42pub use self::segwitv0::{Wpkh, Wsh, WshInner};
43pub use self::sh::{Sh, ShInner};
44pub use self::sortedmulti::SortedMultiVec;
45pub use self::tr::{TapTree, Tr};
46
47pub mod checksum;
48mod key;
49mod key_map;
50
51pub use self::key::{
52 ConversionError, DefiniteDescriptorKey, DerivPaths, DescriptorKeyParseError,
53 DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, InnerXKey,
54 SinglePriv, SinglePub, SinglePubKey, Wildcard,
55};
56pub use self::key_map::KeyMapWrapper;
57
58pub type KeyMap = BTreeMap<DescriptorPublicKey, DescriptorSecretKey>;
65
66#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
68pub enum Descriptor<Pk: MiniscriptKey> {
69 Bare(Bare<Pk>),
71 Pkh(Pkh<Pk>),
73 Wpkh(Wpkh<Pk>),
75 Sh(Sh<Pk>),
77 Wsh(Wsh<Pk>),
79 Tr(Tr<Pk>),
81}
82
83impl<Pk: MiniscriptKey> From<Bare<Pk>> for Descriptor<Pk> {
84 #[inline]
85 fn from(inner: Bare<Pk>) -> Self { Descriptor::Bare(inner) }
86}
87
88impl<Pk: MiniscriptKey> From<Pkh<Pk>> for Descriptor<Pk> {
89 #[inline]
90 fn from(inner: Pkh<Pk>) -> Self { Descriptor::Pkh(inner) }
91}
92
93impl<Pk: MiniscriptKey> From<Wpkh<Pk>> for Descriptor<Pk> {
94 #[inline]
95 fn from(inner: Wpkh<Pk>) -> Self { Descriptor::Wpkh(inner) }
96}
97
98impl<Pk: MiniscriptKey> From<Sh<Pk>> for Descriptor<Pk> {
99 #[inline]
100 fn from(inner: Sh<Pk>) -> Self { Descriptor::Sh(inner) }
101}
102
103impl<Pk: MiniscriptKey> From<Wsh<Pk>> for Descriptor<Pk> {
104 #[inline]
105 fn from(inner: Wsh<Pk>) -> Self { Descriptor::Wsh(inner) }
106}
107
108impl<Pk: MiniscriptKey> From<Tr<Pk>> for Descriptor<Pk> {
109 #[inline]
110 fn from(inner: Tr<Pk>) -> Self { Descriptor::Tr(inner) }
111}
112
113#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
115pub enum DescriptorType {
116 Bare,
118 Sh,
120 Pkh,
122 Wpkh,
124 Wsh,
126 ShWsh,
128 ShWpkh,
130 ShSortedMulti,
132 WshSortedMulti,
134 ShWshSortedMulti,
136 Tr,
138}
139
140impl DescriptorType {
141 pub fn segwit_version(&self) -> Option<WitnessVersion> {
145 use self::DescriptorType::*;
146 match self {
147 Tr => Some(WitnessVersion::V1),
148 Wpkh | ShWpkh | Wsh | ShWsh | ShWshSortedMulti | WshSortedMulti => {
149 Some(WitnessVersion::V0)
150 }
151 Bare | Sh | Pkh | ShSortedMulti => None,
152 }
153 }
154}
155
156impl<Pk: MiniscriptKey> Descriptor<Pk> {
157 pub fn new_pk(pk: Pk) -> Self {
161 let ms: Miniscript<Pk, BareCtx> = Miniscript::from_ast(Terminal::Check(Arc::new(
163 Miniscript::from_ast(Terminal::PkK(pk)).expect("Type check cannot fail"),
164 )))
165 .expect("Type check cannot fail");
166 Descriptor::Bare(Bare::new(ms).expect("Context checks cannot fail for p2pk"))
167 }
168
169 pub fn new_pkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Pkh(Pkh::new(pk)?)) }
171
172 pub fn new_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Wpkh(Wpkh::new(pk)?)) }
175
176 pub fn new_sh_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Sh(Sh::new_wpkh(pk)?)) }
179
180 pub fn new_sh(ms: Miniscript<Pk, Legacy>) -> Result<Self, Error> {
186 Ok(Descriptor::Sh(Sh::new(ms)?))
187 }
188
189 pub fn new_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
193 Ok(Descriptor::Wsh(Wsh::new(ms)?))
194 }
195
196 pub fn new_sh_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
200 Ok(Descriptor::Sh(Sh::new_wsh(ms)?))
201 }
202
203 pub fn new_bare(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
207 Ok(Descriptor::Bare(Bare::new(ms)?))
208 }
209
210 pub fn new_sh_with_wpkh(wpkh: Wpkh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wpkh(wpkh)) }
214
215 pub fn new_sh_with_wsh(wsh: Wsh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wsh(wsh)) }
217
218 pub fn new_sh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
224 Ok(Descriptor::Sh(Sh::new_sortedmulti(k, pks)?))
225 }
226
227 pub fn new_sh_wsh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
231 Ok(Descriptor::Sh(Sh::new_wsh_sortedmulti(k, pks)?))
232 }
233
234 pub fn new_wsh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
237 Ok(Descriptor::Wsh(Wsh::new_sortedmulti(k, pks)?))
238 }
239
240 pub fn new_tr(key: Pk, script: Option<tr::TapTree<Pk>>) -> Result<Self, Error> {
243 Ok(Descriptor::Tr(Tr::new(key, script)?))
244 }
245
246 pub fn desc_type(&self) -> DescriptorType {
248 match *self {
249 Descriptor::Bare(ref _bare) => DescriptorType::Bare,
250 Descriptor::Pkh(ref _pkh) => DescriptorType::Pkh,
251 Descriptor::Wpkh(ref _wpkh) => DescriptorType::Wpkh,
252 Descriptor::Sh(ref sh) => match sh.as_inner() {
253 ShInner::Wsh(ref wsh) => match wsh.as_inner() {
254 WshInner::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
255 WshInner::Ms(ref _ms) => DescriptorType::ShWsh,
256 },
257 ShInner::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
258 ShInner::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
259 ShInner::Ms(ref _ms) => DescriptorType::Sh,
260 },
261 Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
262 WshInner::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
263 WshInner::Ms(ref _ms) => DescriptorType::Wsh,
264 },
265 Descriptor::Tr(ref _tr) => DescriptorType::Tr,
266 }
267 }
268
269 pub fn sanity_check(&self) -> Result<(), Error> {
279 match *self {
280 Descriptor::Bare(ref bare) => bare.sanity_check(),
281 Descriptor::Pkh(_) => Ok(()),
282 Descriptor::Wpkh(ref wpkh) => wpkh.sanity_check(),
283 Descriptor::Wsh(ref wsh) => wsh.sanity_check(),
284 Descriptor::Sh(ref sh) => sh.sanity_check(),
285 Descriptor::Tr(ref tr) => tr.sanity_check(),
286 }
287 }
288
289 pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
328 let weight = match *self {
329 Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
330 Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),
331 Descriptor::Wpkh(ref wpkh) => wpkh.max_weight_to_satisfy(),
332 Descriptor::Wsh(ref wsh) => wsh.max_weight_to_satisfy()?,
333 Descriptor::Sh(ref sh) => sh.max_weight_to_satisfy()?,
334 Descriptor::Tr(ref tr) => tr.max_weight_to_satisfy()?,
335 };
336 Ok(weight)
337 }
338
339 #[deprecated(
349 since = "10.0.0",
350 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."
351 )]
352 #[allow(deprecated)]
353 pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
354 let weight = match *self {
355 Descriptor::Bare(ref bare) => bare.max_satisfaction_weight()?,
356 Descriptor::Pkh(ref pkh) => pkh.max_satisfaction_weight(),
357 Descriptor::Wpkh(ref wpkh) => wpkh.max_satisfaction_weight(),
358 Descriptor::Wsh(ref wsh) => wsh.max_satisfaction_weight()?,
359 Descriptor::Sh(ref sh) => sh.max_satisfaction_weight()?,
360 Descriptor::Tr(ref tr) => tr.max_satisfaction_weight()?,
361 };
362 Ok(weight)
363 }
364}
365
366impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
367 pub fn address(&self, network: Network) -> Result<Address, Error> {
374 match *self {
375 Descriptor::Bare(_) => Err(Error::BareDescriptorAddr),
376 Descriptor::Pkh(ref pkh) => Ok(pkh.address(network)),
377 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.address(network)),
378 Descriptor::Wsh(ref wsh) => Ok(wsh.address(network)),
379 Descriptor::Sh(ref sh) => Ok(sh.address(network)),
380 Descriptor::Tr(ref tr) => Ok(tr.address(network)),
381 }
382 }
383
384 pub fn script_pubkey(&self) -> ScriptBuf {
386 match *self {
387 Descriptor::Bare(ref bare) => bare.script_pubkey(),
388 Descriptor::Pkh(ref pkh) => pkh.script_pubkey(),
389 Descriptor::Wpkh(ref wpkh) => wpkh.script_pubkey(),
390 Descriptor::Wsh(ref wsh) => wsh.script_pubkey(),
391 Descriptor::Sh(ref sh) => sh.script_pubkey(),
392 Descriptor::Tr(ref tr) => tr.script_pubkey(),
393 }
394 }
395
396 pub fn unsigned_script_sig(&self) -> ScriptBuf {
404 match *self {
405 Descriptor::Bare(_) => ScriptBuf::new(),
406 Descriptor::Pkh(_) => ScriptBuf::new(),
407 Descriptor::Wpkh(_) => ScriptBuf::new(),
408 Descriptor::Wsh(_) => ScriptBuf::new(),
409 Descriptor::Sh(ref sh) => sh.unsigned_script_sig(),
410 Descriptor::Tr(_) => ScriptBuf::new(),
411 }
412 }
413
414 pub fn explicit_script(&self) -> Result<ScriptBuf, Error> {
421 match *self {
422 Descriptor::Bare(ref bare) => Ok(bare.script_pubkey()),
423 Descriptor::Pkh(ref pkh) => Ok(pkh.script_pubkey()),
424 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.script_pubkey()),
425 Descriptor::Wsh(ref wsh) => Ok(wsh.inner_script()),
426 Descriptor::Sh(ref sh) => Ok(sh.inner_script()),
427 Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
428 }
429 }
430
431 pub fn script_code(&self) -> Result<ScriptBuf, Error> {
439 match *self {
440 Descriptor::Bare(ref bare) => Ok(bare.ecdsa_sighash_script_code()),
441 Descriptor::Pkh(ref pkh) => Ok(pkh.ecdsa_sighash_script_code()),
442 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.ecdsa_sighash_script_code()),
443 Descriptor::Wsh(ref wsh) => Ok(wsh.ecdsa_sighash_script_code()),
444 Descriptor::Sh(ref sh) => Ok(sh.ecdsa_sighash_script_code()),
445 Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
446 }
447 }
448
449 pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
453 where
454 S: Satisfier<Pk>,
455 {
456 match *self {
457 Descriptor::Bare(ref bare) => bare.get_satisfaction(satisfier),
458 Descriptor::Pkh(ref pkh) => pkh.get_satisfaction(satisfier),
459 Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction(satisfier),
460 Descriptor::Wsh(ref wsh) => wsh.get_satisfaction(satisfier),
461 Descriptor::Sh(ref sh) => sh.get_satisfaction(satisfier),
462 Descriptor::Tr(ref tr) => tr.get_satisfaction(&satisfier),
463 }
464 }
465
466 pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
470 where
471 S: Satisfier<Pk>,
472 {
473 match *self {
474 Descriptor::Bare(ref bare) => bare.get_satisfaction_mall(satisfier),
475 Descriptor::Pkh(ref pkh) => pkh.get_satisfaction_mall(satisfier),
476 Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction_mall(satisfier),
477 Descriptor::Wsh(ref wsh) => wsh.get_satisfaction_mall(satisfier),
478 Descriptor::Sh(ref sh) => sh.get_satisfaction_mall(satisfier),
479 Descriptor::Tr(ref tr) => tr.get_satisfaction_mall(&satisfier),
480 }
481 }
482
483 pub fn satisfy<S>(&self, txin: &mut TxIn, satisfier: S) -> Result<(), Error>
487 where
488 S: Satisfier<Pk>,
489 {
490 let (witness, script_sig) = self.get_satisfaction(satisfier)?;
491 txin.witness = Witness::from_slice(&witness);
492 txin.script_sig = script_sig;
493 Ok(())
494 }
495}
496
497impl Descriptor<DefiniteDescriptorKey> {
498 pub fn plan<P>(self, provider: &P) -> Result<Plan, Self>
502 where
503 P: AssetProvider<DefiniteDescriptorKey>,
504 {
505 let satisfaction = match self {
506 Descriptor::Bare(ref bare) => bare.plan_satisfaction(provider),
507 Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction(provider),
508 Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction(provider),
509 Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction(provider),
510 Descriptor::Sh(ref sh) => sh.plan_satisfaction(provider),
511 Descriptor::Tr(ref tr) => tr.plan_satisfaction(provider),
512 };
513
514 if let satisfy::Witness::Stack(stack) = satisfaction.stack {
515 Ok(Plan {
516 descriptor: self,
517 template: stack,
518 absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
519 relative_timelock: satisfaction.relative_timelock.map(Into::into),
520 })
521 } else {
522 Err(self)
523 }
524 }
525
526 pub fn plan_mall<P>(self, provider: &P) -> Result<Plan, Self>
530 where
531 P: AssetProvider<DefiniteDescriptorKey>,
532 {
533 let satisfaction = match self {
534 Descriptor::Bare(ref bare) => bare.plan_satisfaction_mall(provider),
535 Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction_mall(provider),
536 Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction_mall(provider),
537 Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider),
538 Descriptor::Sh(ref sh) => sh.plan_satisfaction_mall(provider),
539 Descriptor::Tr(ref tr) => tr.plan_satisfaction_mall(provider),
540 };
541
542 if let satisfy::Witness::Stack(stack) = satisfaction.stack {
543 Ok(Plan {
544 descriptor: self,
545 template: stack,
546 absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
547 relative_timelock: satisfaction.relative_timelock.map(Into::into),
549 })
550 } else {
551 Err(self)
552 }
553 }
554}
555
556impl<P, Q> TranslatePk<P, Q> for Descriptor<P>
557where
558 P: MiniscriptKey,
559 Q: MiniscriptKey,
560{
561 type Output = Descriptor<Q>;
562
563 fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>>
565 where
566 T: Translator<P, Q, E>,
567 {
568 let desc = match *self {
569 Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?),
570 Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?),
571 Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?),
572 Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?),
573 Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?),
574 Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?),
575 };
576 Ok(desc)
577 }
578}
579
580impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
581 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
582 match *self {
583 Descriptor::Bare(ref bare) => bare.for_each_key(pred),
584 Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),
585 Descriptor::Wpkh(ref wpkh) => wpkh.for_each_key(pred),
586 Descriptor::Wsh(ref wsh) => wsh.for_each_key(pred),
587 Descriptor::Sh(ref sh) => sh.for_each_key(pred),
588 Descriptor::Tr(ref tr) => tr.for_each_key(pred),
589 }
590 }
591}
592
593impl Descriptor<DescriptorPublicKey> {
594 #[deprecated(note = "use has_wildcards instead")]
596 pub fn is_deriveable(&self) -> bool { self.has_wildcard() }
597
598 pub fn has_wildcard(&self) -> bool { self.for_any_key(|key| key.has_wildcard()) }
600
601 pub fn at_derivation_index(
607 &self,
608 index: u32,
609 ) -> Result<Descriptor<DefiniteDescriptorKey>, ConversionError> {
610 struct Derivator(u32);
611
612 impl Translator<DescriptorPublicKey, DefiniteDescriptorKey, ConversionError> for Derivator {
613 fn pk(
614 &mut self,
615 pk: &DescriptorPublicKey,
616 ) -> Result<DefiniteDescriptorKey, ConversionError> {
617 pk.clone().at_derivation_index(self.0)
618 }
619
620 translate_hash_clone!(DescriptorPublicKey, DescriptorPublicKey, ConversionError);
621 }
622 self.translate_pk(&mut Derivator(index))
623 .map_err(|e| e.expect_translator_err("No Context errors while translating"))
624 }
625
626 #[deprecated(note = "use at_derivation_index instead")]
627 pub fn derive(&self, index: u32) -> Result<Descriptor<DefiniteDescriptorKey>, ConversionError> {
629 self.at_derivation_index(index)
630 }
631
632 pub fn derived_descriptor<C: secp256k1::Verification>(
659 &self,
660 secp: &secp256k1::Secp256k1<C>,
661 index: u32,
662 ) -> Result<Descriptor<bitcoin::PublicKey>, ConversionError> {
663 self.at_derivation_index(index)?.derived_descriptor(secp)
664 }
665
666 pub fn parse_descriptor<C: secp256k1::Signing>(
671 secp: &secp256k1::Secp256k1<C>,
672 s: &str,
673 ) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap), Error> {
674 fn parse_key<C: secp256k1::Signing>(
675 s: &str,
676 key_map: &mut KeyMap,
677 secp: &secp256k1::Secp256k1<C>,
678 ) -> Result<DescriptorPublicKey, Error> {
679 let (public_key, secret_key) = match DescriptorSecretKey::from_str(s) {
680 Ok(sk) => (
681 sk.to_public(secp)
682 .map_err(|e| Error::Unexpected(e.to_string()))?,
683 Some(sk),
684 ),
685 Err(_) => (
686 DescriptorPublicKey::from_str(s)
687 .map_err(|e| Error::Unexpected(e.to_string()))?,
688 None,
689 ),
690 };
691
692 if let Some(secret_key) = secret_key {
693 key_map.insert(public_key.clone(), secret_key);
694 }
695
696 Ok(public_key)
697 }
698
699 let mut keymap_pk = KeyMapWrapper(BTreeMap::new(), secp);
700
701 struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>);
702
703 impl<'a, C: secp256k1::Signing> Translator<String, DescriptorPublicKey, Error>
704 for KeyMapWrapper<'a, C>
705 {
706 fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> {
707 parse_key(pk, &mut self.0, self.1)
708 }
709
710 fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Error> {
711 let hash =
712 sha256::Hash::from_str(sha256).map_err(|e| Error::Unexpected(e.to_string()))?;
713 Ok(hash)
714 }
715
716 fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
717 let hash = hash256::Hash::from_str(hash256)
718 .map_err(|e| Error::Unexpected(e.to_string()))?;
719 Ok(hash)
720 }
721
722 fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Error> {
723 let hash = ripemd160::Hash::from_str(ripemd160)
724 .map_err(|e| Error::Unexpected(e.to_string()))?;
725 Ok(hash)
726 }
727
728 fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Error> {
729 let hash = hash160::Hash::from_str(hash160)
730 .map_err(|e| Error::Unexpected(e.to_string()))?;
731 Ok(hash)
732 }
733 }
734
735 let descriptor = Descriptor::<String>::from_str(s)?;
736 let descriptor = descriptor
737 .translate_pk(&mut keymap_pk)
738 .map_err(TranslateErr::flatten)?;
739
740 Ok((descriptor, keymap_pk.0))
741 }
742
743 pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String {
745 struct KeyMapLookUp<'a>(&'a KeyMap);
746
747 impl<'a> Translator<DescriptorPublicKey, String, ()> for KeyMapLookUp<'a> {
748 fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, ()> {
749 key_to_string(pk, self.0)
750 }
751
752 fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, ()> {
753 Ok(sha256.to_string())
754 }
755
756 fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, ()> {
757 Ok(hash256.to_string())
758 }
759
760 fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, ()> {
761 Ok(ripemd160.to_string())
762 }
763
764 fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, ()> {
765 Ok(hash160.to_string())
766 }
767 }
768
769 fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> Result<String, ()> {
770 Ok(match key_map.get(pk) {
771 Some(secret) => secret.to_string(),
772 None => pk.to_string(),
773 })
774 }
775
776 let descriptor = self
777 .translate_pk(&mut KeyMapLookUp(key_map))
778 .expect("Translation to string cannot fail");
779
780 descriptor.to_string()
781 }
782
783 pub fn find_derivation_index_for_spk<C: secp256k1::Verification>(
791 &self,
792 secp: &secp256k1::Secp256k1<C>,
793 script_pubkey: &Script,
794 range: Range<u32>,
795 ) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey>)>, ConversionError> {
796 let range = if self.has_wildcard() { range } else { 0..1 };
797
798 for i in range {
799 let concrete = self.derived_descriptor(secp, i)?;
800 if &concrete.script_pubkey() == script_pubkey {
801 return Ok(Some((i, concrete)));
802 }
803 }
804
805 Ok(None)
806 }
807
808 pub fn is_multipath(&self) -> bool { self.for_any_key(DescriptorPublicKey::is_multipath) }
810
811 #[allow(clippy::blocks_in_conditions)]
816 pub fn into_single_descriptors(self) -> Result<Vec<Descriptor<DescriptorPublicKey>>, Error> {
817 let mut descriptors = Vec::new();
819 if !self.for_any_key(|key| {
821 if !descriptors.is_empty() {
824 return true;
825 }
826
827 match key {
828 DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => false,
829 DescriptorPublicKey::MultiXPub(xpub) => {
830 for _ in 0..xpub.derivation_paths.paths().len() {
831 descriptors.push(self.clone());
832 }
833 true
834 }
835 }
836 }) {
837 return Ok(vec![self]);
839 }
840 assert!(!descriptors.is_empty());
841
842 struct IndexChoser(usize);
844 impl Translator<DescriptorPublicKey, DescriptorPublicKey, Error> for IndexChoser {
845 fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> {
846 match pk {
847 DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => {
848 Ok(pk.clone())
849 }
850 DescriptorPublicKey::MultiXPub(_) => pk
851 .clone()
852 .into_single_keys()
853 .get(self.0)
854 .cloned()
855 .ok_or(Error::MultipathDescLenMismatch),
856 }
857 }
858 translate_hash_clone!(DescriptorPublicKey, DescriptorPublicKey, Error);
859 }
860
861 for (i, desc) in descriptors.iter_mut().enumerate() {
862 let mut index_choser = IndexChoser(i);
863 *desc = desc
864 .translate_pk(&mut index_choser)
865 .map_err(|e| e.expect_translator_err("No Context errors possible"))?;
866 }
867
868 Ok(descriptors)
869 }
870}
871
872impl Descriptor<DefiniteDescriptorKey> {
873 pub fn derived_descriptor<C: secp256k1::Verification>(
896 &self,
897 secp: &secp256k1::Secp256k1<C>,
898 ) -> Result<Descriptor<bitcoin::PublicKey>, ConversionError> {
899 struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
900
901 impl<'a, C: secp256k1::Verification>
902 Translator<DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError>
903 for Derivator<'a, C>
904 {
905 fn pk(
906 &mut self,
907 pk: &DefiniteDescriptorKey,
908 ) -> Result<bitcoin::PublicKey, ConversionError> {
909 pk.derive_public_key(self.0)
910 }
911
912 translate_hash_clone!(DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError);
913 }
914
915 let derived = self.translate_pk(&mut Derivator(secp));
916 match derived {
917 Ok(derived) => Ok(derived),
918 Err(e) => Err(e.expect_translator_err("No Context errors when deriving keys")),
919 }
920 }
921}
922
923impl<Pk: FromStrKey> crate::expression::FromTree for Descriptor<Pk> {
924 fn from_tree(top: &expression::Tree) -> Result<Descriptor<Pk>, Error> {
926 Ok(match (top.name, top.args.len() as u32) {
927 ("pkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
928 ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),
929 ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?),
930 ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),
931 ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?),
932 _ => Descriptor::Bare(Bare::from_tree(top)?),
933 })
934 }
935}
936
937impl<Pk: FromStrKey> FromStr for Descriptor<Pk> {
938 type Err = Error;
939 fn from_str(s: &str) -> Result<Descriptor<Pk>, Error> {
940 let desc = if s.starts_with("tr(") {
944 Ok(Descriptor::Tr(Tr::from_str(s)?))
945 } else {
946 let desc_str = verify_checksum(s)?;
947 let top = expression::Tree::from_str(desc_str)?;
948 expression::FromTree::from_tree(&top)
949 }?;
950
951 Ok(desc)
952 }
953}
954
955impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
956 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
957 match *self {
958 Descriptor::Bare(ref sub) => fmt::Debug::fmt(sub, f),
959 Descriptor::Pkh(ref pkh) => fmt::Debug::fmt(pkh, f),
960 Descriptor::Wpkh(ref wpkh) => fmt::Debug::fmt(wpkh, f),
961 Descriptor::Sh(ref sub) => fmt::Debug::fmt(sub, f),
962 Descriptor::Wsh(ref sub) => fmt::Debug::fmt(sub, f),
963 Descriptor::Tr(ref tr) => fmt::Debug::fmt(tr, f),
964 }
965 }
966}
967
968impl<Pk: MiniscriptKey> fmt::Display for Descriptor<Pk> {
969 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
970 match *self {
971 Descriptor::Bare(ref sub) => fmt::Display::fmt(sub, f),
972 Descriptor::Pkh(ref pkh) => fmt::Display::fmt(pkh, f),
973 Descriptor::Wpkh(ref wpkh) => fmt::Display::fmt(wpkh, f),
974 Descriptor::Sh(ref sub) => fmt::Display::fmt(sub, f),
975 Descriptor::Wsh(ref sub) => fmt::Display::fmt(sub, f),
976 Descriptor::Tr(ref tr) => fmt::Display::fmt(tr, f),
977 }
978 }
979}
980
981serde_string_impl_pk!(Descriptor, "a script descriptor");
982
983macro_rules! write_descriptor {
984 ($fmt:expr, $s:literal $(, $args:expr)*) => {
985 {
986 use fmt::Write as _;
987
988 let mut wrapped_f = $crate::descriptor::checksum::Formatter::new($fmt);
989 write!(wrapped_f, $s $(, $args)*)?;
990 wrapped_f.write_checksum_if_not_alt()?;
991
992 fmt::Result::Ok(())
993 }
994 }
995}
996pub(crate) use write_descriptor;
997
998#[cfg(test)]
999mod tests {
1000 use core::convert::TryFrom;
1001
1002 use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV};
1003 use bitcoin::blockdata::script::Instruction;
1004 use bitcoin::blockdata::{opcodes, script};
1005 use bitcoin::hashes::hex::FromHex;
1006 use bitcoin::hashes::Hash;
1007 use bitcoin::script::PushBytes;
1008 use bitcoin::sighash::EcdsaSighashType;
1009 use bitcoin::{bip32, PublicKey, Sequence, XOnlyPublicKey};
1010
1011 use super::checksum::desc_checksum;
1012 use super::*;
1013 use crate::hex_script;
1014 #[cfg(feature = "compiler")]
1015 use crate::policy;
1016
1017 type StdDescriptor = Descriptor<PublicKey>;
1018 const TEST_PK: &str = "pk(020000000000000000000000000000000000000000000000000000000000000002)";
1019
1020 fn roundtrip_descriptor(s: &str) {
1021 let desc = Descriptor::<String>::from_str(s).unwrap();
1022 let output = desc.to_string();
1023 let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1024 assert_eq!(
1025 format!("{}#{}", &normalize_aliases, desc_checksum(&normalize_aliases).unwrap()),
1026 output
1027 );
1028 }
1029
1030 #[test]
1031 fn desc_rtt_tests() {
1032 roundtrip_descriptor("c:pk_k()");
1033 roundtrip_descriptor("wsh(pk())");
1034 roundtrip_descriptor("wsh(c:pk_k())");
1035 roundtrip_descriptor("c:pk_h()");
1036 }
1037 #[test]
1038 fn parse_descriptor() {
1039 StdDescriptor::from_str("(").unwrap_err();
1040 StdDescriptor::from_str("(x()").unwrap_err();
1041 StdDescriptor::from_str("(\u{7f}()3").unwrap_err();
1042 StdDescriptor::from_str("pk()").unwrap_err();
1043 StdDescriptor::from_str("nl:0").unwrap_err(); assert_eq!(
1045 StdDescriptor::from_str("sh(sortedmulti)")
1046 .unwrap_err()
1047 .to_string(),
1048 "expected threshold, found terminal",
1049 ); assert_eq!(
1051 StdDescriptor::from_str(&format!("sh(sortedmulti(2,{}))", &TEST_PK[3..69]))
1052 .unwrap_err()
1053 .to_string(),
1054 "invalid threshold 2-of-1; cannot have k > n",
1055 ); StdDescriptor::from_str(TEST_PK).unwrap();
1058
1059 let uncompressed_pk =
1060 "0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1061
1062 StdDescriptor::from_str(&format!("pk({})", uncompressed_pk)).unwrap();
1064 StdDescriptor::from_str(&format!("pkh({})", uncompressed_pk)).unwrap();
1065 StdDescriptor::from_str(&format!("sh(pk({}))", uncompressed_pk)).unwrap();
1066 StdDescriptor::from_str(&format!("wpkh({})", uncompressed_pk)).unwrap_err();
1067 StdDescriptor::from_str(&format!("sh(wpkh({}))", uncompressed_pk)).unwrap_err();
1068 StdDescriptor::from_str(&format!("wsh(pk{})", uncompressed_pk)).unwrap_err();
1069 StdDescriptor::from_str(&format!("sh(wsh(pk{}))", uncompressed_pk)).unwrap_err();
1070 StdDescriptor::from_str(&format!("or_i(pk({}),pk({}))", uncompressed_pk, uncompressed_pk))
1071 .unwrap_err();
1072 }
1073
1074 #[test]
1075 pub fn script_pubkey() {
1076 let bare = StdDescriptor::from_str(
1077 "multi(1,020000000000000000000000000000000000000000000000000000000000000002)",
1078 )
1079 .unwrap();
1080 assert_eq!(
1081 bare.script_pubkey(),
1082 hex_script(
1083 "512102000000000000000000000000000000000000000000000000000000000000000251ae"
1084 )
1085 );
1086 assert_eq!(
1087 bare.address(Network::Bitcoin).unwrap_err().to_string(),
1088 "Bare descriptors don't have address"
1089 );
1090
1091 let pk = StdDescriptor::from_str(TEST_PK).unwrap();
1092 assert_eq!(
1093 pk.script_pubkey(),
1094 ScriptBuf::from(vec![
1095 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xac,
1098 ])
1099 );
1100
1101 let pkh = StdDescriptor::from_str(
1102 "pkh(\
1103 020000000000000000000000000000000000000000000000000000000000000002\
1104 )",
1105 )
1106 .unwrap();
1107 assert_eq!(
1108 pkh.script_pubkey(),
1109 script::Builder::new()
1110 .push_opcode(opcodes::all::OP_DUP)
1111 .push_opcode(opcodes::all::OP_HASH160)
1112 .push_slice(
1113 hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1114 .unwrap()
1115 .to_byte_array()
1116 )
1117 .push_opcode(opcodes::all::OP_EQUALVERIFY)
1118 .push_opcode(opcodes::all::OP_CHECKSIG)
1119 .into_script()
1120 );
1121 assert_eq!(
1122 pkh.address(Network::Bitcoin,).unwrap().to_string(),
1123 "1D7nRvrRgzCg9kYBwhPH3j3Gs6SmsRg3Wq"
1124 );
1125
1126 let wpkh = StdDescriptor::from_str(
1127 "wpkh(\
1128 020000000000000000000000000000000000000000000000000000000000000002\
1129 )",
1130 )
1131 .unwrap();
1132 assert_eq!(
1133 wpkh.script_pubkey(),
1134 script::Builder::new()
1135 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1136 .push_slice(
1137 hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1138 .unwrap()
1139 .to_byte_array()
1140 )
1141 .into_script()
1142 );
1143 assert_eq!(
1144 wpkh.address(Network::Bitcoin,).unwrap().to_string(),
1145 "bc1qsn57m9drscflq5nl76z6ny52hck5w4x5wqd9yt"
1146 );
1147
1148 let shwpkh = StdDescriptor::from_str(
1149 "sh(wpkh(\
1150 020000000000000000000000000000000000000000000000000000000000000002\
1151 ))",
1152 )
1153 .unwrap();
1154 assert_eq!(
1155 shwpkh.script_pubkey(),
1156 script::Builder::new()
1157 .push_opcode(opcodes::all::OP_HASH160)
1158 .push_slice(
1159 hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",)
1160 .unwrap()
1161 .to_byte_array()
1162 )
1163 .push_opcode(opcodes::all::OP_EQUAL)
1164 .into_script()
1165 );
1166 assert_eq!(
1167 shwpkh.address(Network::Bitcoin,).unwrap().to_string(),
1168 "3PjMEzoveVbvajcnDDuxcJhsuqPHgydQXq"
1169 );
1170
1171 let sh = StdDescriptor::from_str(
1172 "sh(c:pk_k(\
1173 020000000000000000000000000000000000000000000000000000000000000002\
1174 ))",
1175 )
1176 .unwrap();
1177 assert_eq!(
1178 sh.script_pubkey(),
1179 script::Builder::new()
1180 .push_opcode(opcodes::all::OP_HASH160)
1181 .push_slice(
1182 hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",)
1183 .unwrap()
1184 .to_byte_array()
1185 )
1186 .push_opcode(opcodes::all::OP_EQUAL)
1187 .into_script()
1188 );
1189 assert_eq!(
1190 sh.address(Network::Bitcoin,).unwrap().to_string(),
1191 "3HDbdvM9CQ6ASnQFUkWw6Z4t3qNwMesJE9"
1192 );
1193
1194 let wsh = StdDescriptor::from_str(
1195 "wsh(c:pk_k(\
1196 020000000000000000000000000000000000000000000000000000000000000002\
1197 ))",
1198 )
1199 .unwrap();
1200 assert_eq!(
1201 wsh.script_pubkey(),
1202 script::Builder::new()
1203 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1204 .push_slice(
1205 sha256::Hash::from_str(
1206 "\
1207 f9379edc8983152dc781747830075bd5\
1208 3896e4b0ce5bff73777fd77d124ba085\
1209 "
1210 )
1211 .unwrap()
1212 .to_byte_array()
1213 )
1214 .into_script()
1215 );
1216 assert_eq!(
1217 wsh.address(Network::Bitcoin,).unwrap().to_string(),
1218 "bc1qlymeahyfsv2jm3upw3urqp6m65ufde9seedl7umh0lth6yjt5zzsk33tv6"
1219 );
1220
1221 let shwsh = StdDescriptor::from_str(
1222 "sh(wsh(c:pk_k(\
1223 020000000000000000000000000000000000000000000000000000000000000002\
1224 )))",
1225 )
1226 .unwrap();
1227 assert_eq!(
1228 shwsh.script_pubkey(),
1229 script::Builder::new()
1230 .push_opcode(opcodes::all::OP_HASH160)
1231 .push_slice(
1232 hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",)
1233 .unwrap()
1234 .to_byte_array()
1235 )
1236 .push_opcode(opcodes::all::OP_EQUAL)
1237 .into_script()
1238 );
1239 assert_eq!(
1240 shwsh.address(Network::Bitcoin,).unwrap().to_string(),
1241 "38cTksiyPT2b1uGRVbVqHdDhW9vKs84N6Z"
1242 );
1243 }
1244
1245 #[test]
1246 fn satisfy() {
1247 let secp = secp256k1::Secp256k1::new();
1248 let sk =
1249 secp256k1::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap();
1250 let pk = bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, &sk));
1251 let msg = secp256k1::Message::from_digest_slice(&b"michael was a message, amusingly"[..])
1252 .expect("32 bytes");
1253 let sig = secp.sign_ecdsa(&msg, &sk);
1254 let mut sigser = sig.serialize_der().to_vec();
1255 sigser.push(0x01); struct SimpleSat {
1258 sig: secp256k1::ecdsa::Signature,
1259 pk: bitcoin::PublicKey,
1260 }
1261
1262 impl Satisfier<bitcoin::PublicKey> for SimpleSat {
1263 fn lookup_ecdsa_sig(
1264 &self,
1265 pk: &bitcoin::PublicKey,
1266 ) -> Option<bitcoin::ecdsa::Signature> {
1267 if *pk == self.pk {
1268 Some(bitcoin::ecdsa::Signature {
1269 signature: self.sig,
1270 sighash_type: bitcoin::sighash::EcdsaSighashType::All,
1271 })
1272 } else {
1273 None
1274 }
1275 }
1276 }
1277
1278 let satisfier = SimpleSat { sig, pk };
1279 let ms = ms_str!("c:pk_k({})", pk);
1280
1281 let mut txin = bitcoin::TxIn {
1282 previous_output: bitcoin::OutPoint::default(),
1283 script_sig: bitcoin::ScriptBuf::new(),
1284 sequence: Sequence::from_height(100),
1285 witness: Witness::default(),
1286 };
1287 let bare = Descriptor::new_bare(ms).unwrap();
1288
1289 bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
1290 assert_eq!(
1291 txin,
1292 bitcoin::TxIn {
1293 previous_output: bitcoin::OutPoint::default(),
1294 script_sig: script::Builder::new()
1295 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1296 .into_script(),
1297 sequence: Sequence::from_height(100),
1298 witness: Witness::default(),
1299 }
1300 );
1301 assert_eq!(bare.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1302
1303 let pkh = Descriptor::new_pkh(pk).unwrap();
1304 pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1305 assert_eq!(
1306 txin,
1307 bitcoin::TxIn {
1308 previous_output: bitcoin::OutPoint::default(),
1309 script_sig: script::Builder::new()
1310 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1311 .push_key(&pk)
1312 .into_script(),
1313 sequence: Sequence::from_height(100),
1314 witness: Witness::default(),
1315 }
1316 );
1317 assert_eq!(pkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1318
1319 let wpkh = Descriptor::new_wpkh(pk).unwrap();
1320 wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1321 assert_eq!(
1322 txin,
1323 bitcoin::TxIn {
1324 previous_output: bitcoin::OutPoint::default(),
1325 script_sig: bitcoin::ScriptBuf::new(),
1326 sequence: Sequence::from_height(100),
1327 witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1328 }
1329 );
1330 assert_eq!(wpkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1331
1332 let shwpkh = Descriptor::new_sh_wpkh(pk).unwrap();
1333 shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1334 let redeem_script = script::Builder::new()
1335 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1336 .push_slice(
1337 hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab")
1338 .unwrap()
1339 .to_byte_array(),
1340 )
1341 .into_script();
1342 assert_eq!(
1343 txin,
1344 bitcoin::TxIn {
1345 previous_output: bitcoin::OutPoint::default(),
1346 script_sig: script::Builder::new()
1347 .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1348 .into_script(),
1349 sequence: Sequence::from_height(100),
1350 witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1351 }
1352 );
1353 assert_eq!(
1354 shwpkh.unsigned_script_sig(),
1355 script::Builder::new()
1356 .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1357 .into_script()
1358 );
1359
1360 let ms = ms_str!("c:pk_k({})", pk);
1361 let sh = Descriptor::new_sh(ms.clone()).unwrap();
1362 sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1363 assert_eq!(
1364 txin,
1365 bitcoin::TxIn {
1366 previous_output: bitcoin::OutPoint::default(),
1367 script_sig: script::Builder::new()
1368 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1369 .push_slice(<&PushBytes>::try_from(ms.encode().as_bytes()).unwrap())
1370 .into_script(),
1371 sequence: Sequence::from_height(100),
1372 witness: Witness::default(),
1373 }
1374 );
1375 assert_eq!(sh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1376
1377 let ms = ms_str!("c:pk_k({})", pk);
1378
1379 let wsh = Descriptor::new_wsh(ms.clone()).unwrap();
1380 wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1381 assert_eq!(
1382 txin,
1383 bitcoin::TxIn {
1384 previous_output: bitcoin::OutPoint::default(),
1385 script_sig: bitcoin::ScriptBuf::new(),
1386 sequence: Sequence::from_height(100),
1387 witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1388 }
1389 );
1390 assert_eq!(wsh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1391
1392 let shwsh = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1393 shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1394 assert_eq!(
1395 txin,
1396 bitcoin::TxIn {
1397 previous_output: bitcoin::OutPoint::default(),
1398 script_sig: script::Builder::new()
1399 .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1400 .into_script(),
1401 sequence: Sequence::from_height(100),
1402 witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1403 }
1404 );
1405 assert_eq!(
1406 shwsh.unsigned_script_sig(),
1407 script::Builder::new()
1408 .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1409 .into_script()
1410 );
1411 }
1412
1413 #[test]
1414 fn after_is_cltv() {
1415 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(after(1000))").unwrap();
1416 let script = descriptor.explicit_script().unwrap();
1417
1418 let actual_instructions: Vec<_> = script.instructions().collect();
1419 let check = actual_instructions.last().unwrap();
1420
1421 assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
1422 }
1423
1424 #[test]
1425 fn older_is_csv() {
1426 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(older(1000))").unwrap();
1427 let script = descriptor.explicit_script().unwrap();
1428
1429 let actual_instructions: Vec<_> = script.instructions().collect();
1430 let check = actual_instructions.last().unwrap();
1431
1432 assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
1433 }
1434
1435 #[test]
1436 fn tr_roundtrip_key() {
1437 let script = Tr::<String>::from_str("tr()").unwrap().to_string();
1438 assert_eq!(script, format!("tr()#x4ml3kxd"))
1439 }
1440
1441 #[test]
1442 fn tr_roundtrip_script() {
1443 let descriptor = Tr::<String>::from_str("tr(,{pk(),pk()})")
1444 .unwrap()
1445 .to_string();
1446
1447 assert_eq!(descriptor, "tr(,{pk(),pk()})#7dqr6v8r");
1448
1449 let descriptor = Descriptor::<String>::from_str("tr(A,{pk(B),pk(C)})")
1450 .unwrap()
1451 .to_string();
1452 assert_eq!(descriptor, "tr(A,{pk(B),pk(C)})#y0uc9t6x");
1453 }
1454
1455 #[test]
1456 fn tr_roundtrip_tree() {
1457 let p1 = "020000000000000000000000000000000000000000000000000000000000000001";
1458 let p2 = "020000000000000000000000000000000000000000000000000000000000000002";
1459 let p3 = "020000000000000000000000000000000000000000000000000000000000000003";
1460 let p4 = "020000000000000000000000000000000000000000000000000000000000000004";
1461 let p5 = "03f8551772d66557da28c1de858124f365a8eb30ce6ad79c10e0f4c546d0ab0f82";
1462 let descriptor = Tr::<PublicKey>::from_str(&format!(
1463 "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})",
1464 p1, p2, p3, p4, p5
1465 ))
1466 .unwrap()
1467 .to_string();
1468
1469 assert_eq!(
1471 descriptor,
1472 format!(
1473 "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})#tvu28c0s",
1474 p1, p2, p3, p4, p5
1475 )
1476 )
1477 }
1478
1479 #[test]
1480 fn tr_script_pubkey() {
1481 let key = Descriptor::<bitcoin::PublicKey>::from_str(
1482 "tr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)",
1483 )
1484 .unwrap();
1485 assert_eq!(
1486 key.script_pubkey().to_hex_string(),
1487 "51209c19294f03757da3dc235a5960631e3c55751632f5889b06b7a053bdc0bcfbcb"
1488 )
1489 }
1490
1491 #[test]
1492 fn roundtrip_tests() {
1493 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("multi");
1494 assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal",);
1495 }
1496
1497 #[test]
1498 fn empty_thresh() {
1499 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("thresh");
1500 assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal");
1501 }
1502
1503 #[test]
1504 fn witness_stack_for_andv_is_arranged_in_correct_order() {
1505 let a = bitcoin::PublicKey::from_str(
1507 "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e",
1508 )
1509 .unwrap();
1510 let sig_a = secp256k1::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap();
1511
1512 let b = bitcoin::PublicKey::from_str(
1513 "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3",
1514 )
1515 .unwrap();
1516 let sig_b = secp256k1::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap();
1517
1518 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&format!(
1519 "wsh(and_v(v:pk({A}),pk({B})))",
1520 A = a,
1521 B = b
1522 ))
1523 .unwrap();
1524
1525 let mut txin = bitcoin::TxIn {
1526 previous_output: bitcoin::OutPoint::default(),
1527 script_sig: bitcoin::ScriptBuf::new(),
1528 sequence: Sequence::ZERO,
1529 witness: Witness::default(),
1530 };
1531 let satisfier = {
1532 let mut satisfier = BTreeMap::new();
1533
1534 satisfier.insert(
1535 a,
1536 bitcoin::ecdsa::Signature { signature: sig_a, sighash_type: EcdsaSighashType::All },
1537 );
1538 satisfier.insert(
1539 b,
1540 bitcoin::ecdsa::Signature { signature: sig_b, sighash_type: EcdsaSighashType::All },
1541 );
1542
1543 satisfier
1544 };
1545
1546 descriptor.satisfy(&mut txin, &satisfier).unwrap();
1548
1549 let wit = txin.witness.to_vec();
1551 let witness0 = &wit[0];
1552 let witness1 = &wit[1];
1553
1554 let sig0 = secp256k1::ecdsa::Signature::from_der(&witness0[..witness0.len() - 1]).unwrap();
1555 let sig1 = secp256k1::ecdsa::Signature::from_der(&witness1[..witness1.len() - 1]).unwrap();
1556
1557 assert_eq!(sig1, sig_a);
1562 assert_eq!(sig0, sig_b);
1563 }
1564
1565 #[test]
1566 fn test_scriptcode() {
1567 let descriptor = Descriptor::<PublicKey>::from_str(
1569 "wpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
1570 )
1571 .unwrap();
1572 assert_eq!(
1573 *descriptor.script_code().unwrap().as_bytes(),
1574 Vec::<u8>::from_hex("76a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac").unwrap()[..]
1575 );
1576
1577 let descriptor = Descriptor::<PublicKey>::from_str(
1579 "sh(wpkh(03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873))",
1580 )
1581 .unwrap();
1582 assert_eq!(
1583 *descriptor.script_code().unwrap().as_bytes(),
1584 Vec::<u8>::from_hex("76a91479091972186c449eb1ded22b78e40d009bdf008988ac").unwrap()[..]
1585 );
1586
1587 let descriptor = Descriptor::<PublicKey>::from_str(
1589 "wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626))",
1590 )
1591 .unwrap();
1592 assert_eq!(
1593 *descriptor
1594 .script_code().unwrap()
1595 .as_bytes(),
1596 Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae").unwrap()[..]
1597 );
1598
1599 let descriptor = Descriptor::<PublicKey>::from_str("sh(wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626)))").unwrap();
1601 assert_eq!(
1602 *descriptor
1603 .script_code().unwrap()
1604 .as_bytes(),
1605 Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae")
1606 .unwrap()[..]
1607 );
1608 }
1609
1610 #[test]
1611 fn parse_descriptor_key() {
1612 let key = "[78412e3a/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
1614 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1615 origin: Some((
1616 bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1617 (&[
1618 bip32::ChildNumber::from_hardened_idx(44).unwrap(),
1619 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1620 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1621 ][..])
1622 .into(),
1623 )),
1624 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1625 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1626 wildcard: Wildcard::Unhardened,
1627 });
1628 assert_eq!(expected, key.parse().unwrap());
1629 assert_eq!(format!("{}", expected), key);
1630
1631 let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1";
1633 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1634 origin: None,
1635 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1636 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1637 wildcard: Wildcard::None,
1638 });
1639 assert_eq!(expected, key.parse().unwrap());
1640 assert_eq!(format!("{}", expected), key);
1641
1642 let key = "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed/1";
1644 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1645 origin: None,
1646 xkey: bip32::Xpub::from_str("tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed").unwrap(),
1647 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1648 wildcard: Wildcard::None,
1649 });
1650 assert_eq!(expected, key.parse().unwrap());
1651 assert_eq!(format!("{}", expected), key);
1652
1653 let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
1655 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1656 origin: None,
1657 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1658 derivation_path: bip32::DerivationPath::from(&[][..]),
1659 wildcard: Wildcard::None,
1660 });
1661 assert_eq!(expected, key.parse().unwrap());
1662 assert_eq!(format!("{}", expected), key);
1663
1664 let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8";
1666 let expected = DescriptorPublicKey::Single(SinglePub {
1667 key: SinglePubKey::FullKey(
1668 bitcoin::PublicKey::from_str(
1669 "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
1670 )
1671 .unwrap(),
1672 ),
1673 origin: None,
1674 });
1675 assert_eq!(expected, key.parse().unwrap());
1676 assert_eq!(format!("{}", expected), key);
1677
1678 let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a";
1680 let expected = DescriptorPublicKey::Single(SinglePub {
1681 key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str(
1682 "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a",
1683 )
1684 .unwrap()),
1685 origin: None,
1686 });
1687 assert_eq!(expected, key.parse().unwrap());
1688 assert_eq!(format!("{}", expected), key);
1689
1690 let desc =
1692 "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8";
1693 let expected = DescriptorPublicKey::Single(SinglePub {
1694 key: SinglePubKey::FullKey(
1695 bitcoin::PublicKey::from_str(
1696 "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8",
1697 )
1698 .unwrap(),
1699 ),
1700 origin: Some((
1701 bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1702 (&[
1703 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1704 bip32::ChildNumber::from_normal_idx(42).unwrap(),
1705 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1706 ][..])
1707 .into(),
1708 )),
1709 });
1710 assert_eq!(expected, desc.parse().expect("Parsing desc"));
1711 assert_eq!(format!("{}", expected), desc);
1712 }
1713
1714 #[test]
1715 fn test_sortedmulti() {
1716 fn _test_sortedmulti(raw_desc_one: &str, raw_desc_two: &str, raw_addr_expected: &str) {
1717 let secp_ctx = secp256k1::Secp256k1::verification_only();
1718 let index = 5;
1719
1720 let desc_one = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_one).unwrap();
1722 let desc_two = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_two).unwrap();
1723
1724 assert_eq!(desc_one.to_string(), raw_desc_one);
1726 assert_eq!(desc_two.to_string(), raw_desc_two);
1727
1728 let addr_one = desc_one
1730 .at_derivation_index(index)
1731 .unwrap()
1732 .derived_descriptor(&secp_ctx)
1733 .unwrap()
1734 .address(bitcoin::Network::Bitcoin)
1735 .unwrap();
1736 let addr_two = desc_two
1737 .at_derivation_index(index)
1738 .unwrap()
1739 .derived_descriptor(&secp_ctx)
1740 .unwrap()
1741 .address(bitcoin::Network::Bitcoin)
1742 .unwrap();
1743 let addr_expected = bitcoin::Address::from_str(raw_addr_expected)
1744 .unwrap()
1745 .assume_checked();
1746 assert_eq!(addr_one, addr_expected);
1747 assert_eq!(addr_two, addr_expected);
1748 }
1749
1750 _test_sortedmulti(
1752 "sh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#uetvewm2",
1753 "sh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#7l8smyg9",
1754 "3JZJNxvDKe6Y55ZaF5223XHwfF2eoMNnoV",
1755 );
1756
1757 _test_sortedmulti(
1759 "wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#7etm7zk7",
1760 "wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#ppmeel9k",
1761 "bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a",
1762 );
1763
1764 _test_sortedmulti(
1766 "sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#u60cee0u",
1767 "sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#75dkf44w",
1768 "325zcVBN5o2eqqqtGwPjmtDd8dJRyYP82s",
1769 );
1770 }
1771
1772 #[test]
1773 fn test_parse_descriptor() {
1774 let secp = &secp256k1::Secp256k1::signing_only();
1775 let (descriptor, key_map) = Descriptor::parse_descriptor(secp, "wpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
1776 assert_eq!(descriptor.to_string(), "wpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#nhdxg96s");
1777 assert_eq!(key_map.len(), 1);
1778
1779 macro_rules! check_invalid_checksum {
1781 ($secp: ident,$($desc: expr),*) => {
1782 $(
1783 match Descriptor::parse_descriptor($secp, $desc) {
1784 Err(Error::BadDescriptor(_)) => {},
1785 Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
1786 _ => panic!("Invalid checksum treated as valid: {}", $desc),
1787 };
1788 )*
1789 };
1790 }
1791 check_invalid_checksum!(secp,
1792 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#",
1793 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#",
1794 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfyq",
1795 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5tq",
1796 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
1797 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5",
1798 "sh(multi(3,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy",
1799 "sh(multi(3,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t",
1800 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjq09x4t",
1801 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))##ggssrxfy",
1802 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
1803 );
1804
1805 Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy").expect("Valid descriptor with checksum");
1806 Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t").expect("Valid descriptor with checksum");
1807 }
1808
1809 #[test]
1810 #[cfg(feature = "compiler")]
1811 fn parse_and_derive() {
1812 let descriptor_str = "thresh(2,\
1813pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*),\
1814pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1815pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1816 let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1817 let descriptor = Descriptor::new_sh(policy.compile().unwrap()).unwrap();
1818 let definite_descriptor = descriptor.at_derivation_index(42).unwrap();
1819
1820 let res_descriptor_str = "thresh(2,\
1821pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\
1822pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1823pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1824 let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
1825 res_descriptor_str.parse().unwrap();
1826 let res_descriptor = Descriptor::new_sh(res_policy.compile().unwrap()).unwrap();
1827
1828 assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string());
1829 }
1830
1831 #[test]
1832 fn parse_with_secrets() {
1833 let secp = &secp256k1::Secp256k1::signing_only();
1834 let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#v20xlvm9";
1835 let (descriptor, keymap) =
1836 Descriptor::<DescriptorPublicKey>::parse_descriptor(secp, descriptor_str).unwrap();
1837
1838 let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#u37l7u8u";
1839 assert_eq!(expected, descriptor.to_string());
1840 assert_eq!(keymap.len(), 1);
1841
1842 assert_eq!(descriptor_str, descriptor.to_string_with_secret(&keymap));
1844 }
1845
1846 #[test]
1847 fn checksum_for_nested_sh() {
1848 let descriptor_str = "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))";
1849 let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1850 assert_eq!(descriptor.to_string(), "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))#tjp2zm88");
1851
1852 let descriptor_str = "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))";
1853 let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1854 assert_eq!(descriptor.to_string(), "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))#6c6hwr22");
1855 }
1856
1857 #[test]
1858 fn test_xonly_keys() {
1859 let comp_key = "0308c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
1860 let x_only_key = "08c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
1861
1862 Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", comp_key)).unwrap();
1864 Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", x_only_key)).unwrap();
1865
1866 Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
1868 Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", x_only_key))
1869 .unwrap_err();
1870 }
1871
1872 #[test]
1873 fn test_find_derivation_index_for_spk() {
1874 let secp = secp256k1::Secp256k1::verification_only();
1875 let descriptor = Descriptor::from_str("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
1876 let script_at_0_1 = ScriptBuf::from_hex(
1877 "5120a82f29944d65b86ae6b5e5cc75e294ead6c59391a1edc5e016e3498c67fc7bbb",
1878 )
1879 .unwrap();
1880 let expected_concrete = Descriptor::from_str(
1881 "tr(0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145)",
1882 )
1883 .unwrap();
1884
1885 assert_eq!(descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..1), Ok(None));
1886 assert_eq!(
1887 descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..2),
1888 Ok(Some((1, expected_concrete.clone())))
1889 );
1890 assert_eq!(
1891 descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..10),
1892 Ok(Some((1, expected_concrete)))
1893 );
1894 }
1895
1896 #[test]
1897 fn display_alternate() {
1898 let bare = StdDescriptor::from_str(
1899 "pk(020000000000000000000000000000000000000000000000000000000000000002)",
1900 )
1901 .unwrap();
1902 assert_eq!(
1903 format!("{}", bare),
1904 "pk(020000000000000000000000000000000000000000000000000000000000000002)#7yxkn84h",
1905 );
1906 assert_eq!(
1907 format!("{:#}", bare),
1908 "pk(020000000000000000000000000000000000000000000000000000000000000002)",
1909 );
1910
1911 let pkh = StdDescriptor::from_str(
1912 "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
1913 )
1914 .unwrap();
1915 assert_eq!(
1916 format!("{}", pkh),
1917 "pkh(020000000000000000000000000000000000000000000000000000000000000002)#ma7nspkf",
1918 );
1919 assert_eq!(
1920 format!("{:#}", pkh),
1921 "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
1922 );
1923
1924 let wpkh = StdDescriptor::from_str(
1925 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
1926 )
1927 .unwrap();
1928 assert_eq!(
1929 format!("{}", wpkh),
1930 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)#d3xz2xye",
1931 );
1932 assert_eq!(
1933 format!("{:#}", wpkh),
1934 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
1935 );
1936
1937 let shwpkh = StdDescriptor::from_str(
1938 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
1939 )
1940 .unwrap();
1941 assert_eq!(
1942 format!("{}", shwpkh),
1943 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))#45zpjtet",
1944 );
1945 assert_eq!(
1946 format!("{:#}", shwpkh),
1947 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
1948 );
1949
1950 let wsh = StdDescriptor::from_str("wsh(1)").unwrap();
1951 assert_eq!(format!("{}", wsh), "wsh(1)#mrg7xj7p");
1952 assert_eq!(format!("{:#}", wsh), "wsh(1)");
1953
1954 let sh = StdDescriptor::from_str("sh(1)").unwrap();
1955 assert_eq!(format!("{}", sh), "sh(1)#l8r75ggs");
1956 assert_eq!(format!("{:#}", sh), "sh(1)");
1957
1958 let shwsh = StdDescriptor::from_str("sh(wsh(1))").unwrap();
1959 assert_eq!(format!("{}", shwsh), "sh(wsh(1))#hcyfl07f");
1960 assert_eq!(format!("{:#}", shwsh), "sh(wsh(1))");
1961
1962 let tr = StdDescriptor::from_str(
1963 "tr(020000000000000000000000000000000000000000000000000000000000000002)",
1964 )
1965 .unwrap();
1966 assert_eq!(
1967 format!("{}", tr),
1968 "tr(020000000000000000000000000000000000000000000000000000000000000002)#8hc7wq5h",
1969 );
1970 assert_eq!(
1971 format!("{:#}", tr),
1972 "tr(020000000000000000000000000000000000000000000000000000000000000002)",
1973 );
1974 }
1975
1976 #[test]
1977 fn multipath_descriptors() {
1978 let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))").unwrap();
1980 assert!(desc.is_multipath());
1981 assert_eq!(desc.into_single_descriptors().unwrap(), vec![
1982 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))").unwrap(),
1983 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))").unwrap(),
1984 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/20/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/987/*)))").unwrap()
1985 ]);
1986
1987 let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
1989 assert!(desc.is_multipath());
1990 assert_eq!(desc.into_single_descriptors().unwrap(), vec![
1991 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
1992 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
1993 ]);
1994
1995 let notmulti_desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
1997 assert!(!notmulti_desc.is_multipath());
1998 assert_eq!(notmulti_desc.clone().into_single_descriptors().unwrap(), vec![notmulti_desc]);
1999
2000 Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))").unwrap_err();
2002 Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))").unwrap_err();
2003 }
2004
2005 #[test]
2006 fn test_context_pks() {
2007 let comp_key = bitcoin::PublicKey::from_str(
2008 "02015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2009 )
2010 .unwrap();
2011 let x_only_key = bitcoin::key::XOnlyPublicKey::from_str(
2012 "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2013 )
2014 .unwrap();
2015 let uncomp_key = bitcoin::PublicKey::from_str("04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4").unwrap();
2016
2017 type Desc = Descriptor<DescriptorPublicKey>;
2018
2019 Desc::from_str(&format!("sh(pk({}))", comp_key)).unwrap();
2021 Desc::from_str(&format!("sh(pk({}))", uncomp_key)).unwrap();
2022 Desc::from_str(&format!("sh(pk({}))", x_only_key)).unwrap_err();
2023
2024 Desc::from_str(&format!("pk({})", comp_key)).unwrap();
2026 Desc::from_str(&format!("pk({})", uncomp_key)).unwrap();
2027 Desc::from_str(&format!("pk({})", x_only_key)).unwrap_err();
2028
2029 Desc::from_str(&format!("pkh({})", comp_key)).unwrap();
2031 Desc::from_str(&format!("pkh({})", uncomp_key)).unwrap();
2032 Desc::from_str(&format!("pkh({})", x_only_key)).unwrap_err();
2033
2034 Desc::from_str(&format!("wpkh({})", comp_key)).unwrap();
2036 Desc::from_str(&format!("wpkh({})", uncomp_key)).unwrap_err();
2037 Desc::from_str(&format!("wpkh({})", x_only_key)).unwrap_err();
2038
2039 Desc::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
2041 Desc::from_str(&format!("wsh(pk({}))", uncomp_key)).unwrap_err();
2042 Desc::from_str(&format!("wsh(pk({}))", x_only_key)).unwrap_err();
2043
2044 Desc::from_str(&format!("tr({})", comp_key)).unwrap();
2046 Desc::from_str(&format!("tr({})", uncomp_key)).unwrap_err();
2047 Desc::from_str(&format!("tr({})", x_only_key)).unwrap();
2048
2049 Desc::from_str(&format!("tr({},pk({}))", x_only_key, comp_key)).unwrap();
2051 Desc::from_str(&format!("tr({},pk({}))", x_only_key, uncomp_key)).unwrap_err();
2052 Desc::from_str(&format!("tr({},pk({}))", x_only_key, x_only_key)).unwrap();
2053 }
2054
2055 #[test]
2056 fn regression_806() {
2057 let secp = secp256k1::Secp256k1::signing_only();
2058 type Desc = Descriptor<DescriptorPublicKey>;
2059 Desc::from_str("pkh(111111111111111111111111111111110000008375319363688624584A111111)")
2061 .unwrap_err();
2062 Desc::parse_descriptor(
2064 &secp,
2065 "pkh(111111111111111111111111111111110000008375319363688624584A111111)",
2066 )
2067 .unwrap_err();
2068 }
2069
2070 #[test]
2071 fn convert_public_key_descriptor_to_definite_key() {
2072 let descriptor_str = "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))";
2073 let full_pk_descriptor: Descriptor<PublicKey> =
2074 Descriptor::from_str(descriptor_str).unwrap();
2075
2076 struct TranslateFullPk;
2077
2078 impl Translator<bitcoin::PublicKey, DefiniteDescriptorKey, ()> for TranslateFullPk {
2079 fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result<DefiniteDescriptorKey, ()> {
2080 Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2081 .expect("DescriptorPublicKey from PublicKey has no wildcards"))
2082 }
2083
2084 translate_hash_clone!(bitcoin::PublicKey, DefiniteDescriptorKey, ());
2085 }
2086
2087 let converted_descriptor = full_pk_descriptor
2088 .translate_pk(&mut TranslateFullPk)
2089 .expect("infallible");
2090
2091 assert_eq!(full_pk_descriptor.to_string(), converted_descriptor.to_string());
2092
2093 let xonly_descriptor_str = "tr(1d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,pk(02c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))";
2094 let xonly_pk_descriptor: Descriptor<XOnlyPublicKey> =
2095 Descriptor::from_str(xonly_descriptor_str).unwrap();
2096
2097 struct TranslateXOnlyPk;
2098
2099 impl Translator<XOnlyPublicKey, DefiniteDescriptorKey, ()> for TranslateXOnlyPk {
2100 fn pk(&mut self, pk: &XOnlyPublicKey) -> Result<DefiniteDescriptorKey, ()> {
2101 Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2102 .expect("DescriptorPublicKey from XOnlyPublicKey has no wildcards"))
2103 }
2104
2105 translate_hash_clone!(XOnlyPublicKey, DefiniteDescriptorKey, ());
2106 }
2107
2108 let xonly_converted_descriptor = xonly_pk_descriptor
2109 .translate_pk(&mut TranslateXOnlyPk)
2110 .expect("infallible");
2111
2112 assert_eq!(xonly_pk_descriptor.to_string(), xonly_converted_descriptor.to_string());
2113 }
2114}