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