descriptor_codec/
encoder.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Descriptor Encode
4
5use super::tag::Tag;
6use super::varint;
7
8use bitcoin::{
9    bip32::{ChildNumber, DerivationPath, Xpriv, Xpub},
10    hashes::Hash,
11};
12use miniscript::{
13    Miniscript, ScriptContext, Threshold,
14    descriptor::{
15        Bare, DerivPaths, Descriptor, DescriptorMultiXKey, DescriptorPublicKey,
16        DescriptorSecretKey, DescriptorXKey, KeyMap, Pkh, Sh, ShInner, SinglePubKey,
17        SortedMultiVec, TapTree, Tr, Wildcard, Wpkh, Wsh, WshInner,
18    },
19    miniscript::decode::Terminal,
20};
21use std::fmt::Debug;
22use std::sync::Arc;
23
24/// Encodes a descriptor as a template with a separate payload, containing the keys,
25/// fingerprints, hashes, and timelocks.
26pub fn encode(descriptor: Descriptor<DescriptorPublicKey>, key_map: &KeyMap) -> (Vec<u8>, Vec<u8>) {
27    let mut template = Vec::new();
28    let mut payload = Vec::new();
29    descriptor.encode_template(&mut template, &mut payload, key_map);
30
31    (template, payload)
32}
33
34/// A trait to create an encoded template
35pub(crate) trait EncodeTemplate: Debug + PartialEq {
36    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap);
37}
38
39impl EncodeTemplate for Descriptor<DescriptorPublicKey> {
40    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
41        match self {
42            Descriptor::Sh(sh) => sh.encode_template(template, payload, key_map),
43            Descriptor::Wsh(wsh) => wsh.encode_template(template, payload, key_map),
44            Descriptor::Tr(tr) => tr.encode_template(template, payload, key_map),
45            Descriptor::Wpkh(wpkh) => wpkh.encode_template(template, payload, key_map),
46            Descriptor::Pkh(pk) => pk.encode_template(template, payload, key_map),
47            Descriptor::Bare(bare) => bare.encode_template(template, payload, key_map),
48        };
49    }
50}
51
52impl EncodeTemplate for Sh<DescriptorPublicKey> {
53    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
54        template.push(Tag::Sh.value());
55
56        match self.as_inner() {
57            ShInner::SortedMulti(sortedmulti) => {
58                sortedmulti.encode_template(template, payload, key_map)
59            }
60            ShInner::Wsh(wsh) => wsh.encode_template(template, payload, key_map),
61            ShInner::Wpkh(wpkh) => wpkh.encode_template(template, payload, key_map),
62            ShInner::Ms(ms) => ms.encode_template(template, payload, key_map),
63        }
64    }
65}
66
67impl EncodeTemplate for Wsh<DescriptorPublicKey> {
68    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
69        template.push(Tag::Wsh.value());
70
71        match self.as_inner() {
72            WshInner::SortedMulti(sortedmulti) => {
73                sortedmulti.encode_template(template, payload, key_map)
74            }
75            WshInner::Ms(ms) => ms.encode_template(template, payload, key_map),
76        };
77    }
78}
79
80impl EncodeTemplate for Tr<DescriptorPublicKey> {
81    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
82        template.push(Tag::Tr.value());
83
84        self.internal_key()
85            .encode_template(template, payload, key_map);
86
87        if let Some(tap_tree) = self.tap_tree() {
88            tap_tree.encode_template(template, payload, key_map);
89        }
90    }
91}
92
93impl EncodeTemplate for Wpkh<DescriptorPublicKey> {
94    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
95        template.push(Tag::Wpkh.value());
96
97        self.as_inner().encode_template(template, payload, key_map);
98    }
99}
100
101impl EncodeTemplate for Pkh<DescriptorPublicKey> {
102    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
103        template.push(Tag::Pkh.value());
104
105        self.as_inner().encode_template(template, payload, key_map);
106    }
107}
108
109impl EncodeTemplate for Bare<DescriptorPublicKey> {
110    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
111        template.push(Tag::Bare.value());
112
113        self.as_inner().encode_template(template, payload, key_map);
114    }
115}
116
117impl EncodeTemplate for TapTree<DescriptorPublicKey> {
118    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
119        template.push(Tag::TapTree.value());
120
121        match self {
122            TapTree::Tree { left, right, .. } => {
123                left.encode_template(template, payload, key_map);
124                right.encode_template(template, payload, key_map);
125            }
126            TapTree::Leaf(ms) => ms.encode_template(template, payload, key_map),
127        }
128    }
129}
130
131impl<Ctx: ScriptContext> EncodeTemplate for SortedMultiVec<DescriptorPublicKey, Ctx> {
132    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
133        template.push(Tag::SortedMulti.value());
134        template.extend(varint::encode(self.k() as u128));
135        template.extend(varint::encode(self.n() as u128));
136
137        self.pks()
138            .iter()
139            .for_each(|pk| pk.encode_template(template, payload, key_map));
140    }
141}
142
143impl<Ctx: ScriptContext> EncodeTemplate for Miniscript<DescriptorPublicKey, Ctx> {
144    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
145        self.node.encode_template(template, payload, key_map);
146    }
147}
148
149impl<Ctx: ScriptContext> EncodeTemplate for Terminal<DescriptorPublicKey, Ctx> {
150    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
151        match self {
152            Terminal::True => {
153                template.push(Tag::True.value());
154            }
155            Terminal::False => {
156                template.push(Tag::False.value());
157            }
158            Terminal::PkK(pk) => {
159                template.push(Tag::PkK.value());
160                pk.encode_template(template, payload, key_map);
161            }
162            Terminal::PkH(pk) => {
163                template.push(Tag::PkH.value());
164                pk.encode_template(template, payload, key_map);
165            }
166            Terminal::RawPkH(hash) => {
167                template.push(Tag::RawPkH.value());
168                payload.extend(hash.as_byte_array().to_vec());
169            }
170            Terminal::After(after) => {
171                template.push(Tag::After.value());
172                payload.extend(varint::encode(after.to_consensus_u32().into()));
173            }
174            Terminal::Older(older) => {
175                template.push(Tag::Older.value());
176                payload.extend(varint::encode(older.to_consensus_u32().into()));
177            }
178            Terminal::Sha256(sha256) => {
179                template.push(Tag::Sha256.value());
180                payload.extend(sha256.as_byte_array().to_vec());
181            }
182            Terminal::Hash256(hash156) => {
183                template.push(Tag::Hash256.value());
184                payload.extend(hash156.as_byte_array().to_vec());
185            }
186            Terminal::Ripemd160(ripemd160) => {
187                template.push(Tag::Ripemd160.value());
188                payload.extend(ripemd160.as_byte_array().to_vec());
189            }
190            Terminal::Hash160(hash160) => {
191                template.push(Tag::Hash160.value());
192                payload.extend(hash160.as_byte_array().to_vec());
193            }
194            Terminal::Alt(ms) => {
195                template.push(Tag::Alt.value());
196                ms.encode_template(template, payload, key_map);
197            }
198            Terminal::Swap(ms) => {
199                template.push(Tag::Swap.value());
200                ms.encode_template(template, payload, key_map);
201            }
202            Terminal::Check(ms) => {
203                template.push(Tag::Check.value());
204                ms.encode_template(template, payload, key_map);
205            }
206            Terminal::DupIf(ms) => {
207                template.push(Tag::DupIf.value());
208                ms.encode_template(template, payload, key_map);
209            }
210            Terminal::Verify(ms) => {
211                template.push(Tag::Verify.value());
212                ms.encode_template(template, payload, key_map);
213            }
214            Terminal::NonZero(ms) => {
215                template.push(Tag::NonZero.value());
216                ms.encode_template(template, payload, key_map);
217            }
218            Terminal::ZeroNotEqual(ms) => {
219                template.push(Tag::ZeroNotEqual.value());
220                ms.encode_template(template, payload, key_map);
221            }
222            Terminal::AndV(ms0, ms1) => {
223                template.push(Tag::AndV.value());
224                ms0.encode_template(template, payload, key_map);
225                ms1.encode_template(template, payload, key_map);
226            }
227            Terminal::AndB(ms0, ms1) => {
228                template.push(Tag::AndB.value());
229                ms0.encode_template(template, payload, key_map);
230                ms1.encode_template(template, payload, key_map);
231            }
232            Terminal::AndOr(ms0, ms1, ms2) => {
233                template.push(Tag::AndOr.value());
234                ms0.encode_template(template, payload, key_map);
235                ms1.encode_template(template, payload, key_map);
236                ms2.encode_template(template, payload, key_map);
237            }
238            Terminal::OrB(ms0, ms1) => {
239                template.push(Tag::OrB.value());
240                ms0.encode_template(template, payload, key_map);
241                ms1.encode_template(template, payload, key_map);
242            }
243            Terminal::OrC(ms0, ms1) => {
244                template.push(Tag::OrC.value());
245                ms0.encode_template(template, payload, key_map);
246                ms1.encode_template(template, payload, key_map);
247            }
248            Terminal::OrD(ms0, ms1) => {
249                template.push(Tag::OrD.value());
250                ms0.encode_template(template, payload, key_map);
251                ms1.encode_template(template, payload, key_map);
252            }
253            Terminal::OrI(ms0, ms1) => {
254                template.push(Tag::OrI.value());
255                ms0.encode_template(template, payload, key_map);
256                ms1.encode_template(template, payload, key_map);
257            }
258            Terminal::Thresh(thresh) => {
259                template.push(Tag::Thresh.value());
260                thresh.encode_template(template, payload, key_map);
261            }
262            Terminal::Multi(thresh) => {
263                template.push(Tag::Multi.value());
264                thresh.encode_template(template, payload, key_map);
265            }
266            Terminal::MultiA(thresh) => {
267                template.push(Tag::MultiA.value());
268                thresh.encode_template(template, payload, key_map);
269            }
270        }
271    }
272}
273
274impl<T: EncodeTemplate> EncodeTemplate for Arc<T> {
275    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
276        (**self).encode_template(template, payload, key_map);
277    }
278}
279
280impl<T: EncodeTemplate, const MAX: usize> EncodeTemplate for Threshold<T, MAX> {
281    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
282        template.extend(varint::encode(self.k() as u128));
283        template.extend(varint::encode(self.n() as u128));
284
285        self.iter()
286            .for_each(|t| t.encode_template(template, payload, key_map));
287    }
288}
289
290impl EncodeTemplate for DescriptorPublicKey {
291    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
292        if let Some(secret_key) = key_map.get(self) {
293            secret_key.encode_template(template, payload, key_map);
294            return;
295        }
296
297        let (tag, origin) = match self.clone() {
298            DescriptorPublicKey::XPub(xpub) => (Tag::XPub, xpub.origin),
299            DescriptorPublicKey::MultiXPub(xpub) => (Tag::MultiXPub, xpub.origin),
300            DescriptorPublicKey::Single(single) => {
301                let tag = match single.key {
302                    SinglePubKey::FullKey(pk) => {
303                        if pk.compressed {
304                            Tag::CompressedFullKey
305                        } else {
306                            Tag::UncompressedFullKey
307                        }
308                    }
309                    SinglePubKey::XOnly(_) => Tag::XOnly,
310                };
311                (tag, single.origin)
312            }
313        };
314
315        template.push(tag.value());
316
317        if let Some((fingerprint, derivation_path)) = origin {
318            template.push(Tag::Origin.value());
319            payload.extend(fingerprint.as_bytes().to_vec());
320
321            derivation_path.encode_template(template, payload, key_map);
322        } else {
323            template.push(Tag::NoOrigin.value());
324        }
325
326        match self {
327            DescriptorPublicKey::XPub(xpub) => xpub.encode_template(template, payload, key_map),
328            DescriptorPublicKey::MultiXPub(xpub) => {
329                xpub.encode_template(template, payload, key_map)
330            }
331            DescriptorPublicKey::Single(single) => {
332                single.key.encode_template(template, payload, key_map)
333            }
334        }
335    }
336}
337
338impl EncodeTemplate for DescriptorSecretKey {
339    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
340        let (tag, origin) = match self.clone() {
341            DescriptorSecretKey::XPrv(xprv) => (Tag::XPriv, xprv.origin),
342            DescriptorSecretKey::MultiXPrv(xprv) => (Tag::MultiXPriv, xprv.origin),
343            DescriptorSecretKey::Single(single) => {
344                let tag = if single.key.compressed {
345                    Tag::CompressedSinglePriv
346                } else {
347                    Tag::UncompressedSinglePriv
348                };
349                (tag, single.origin)
350            }
351        };
352
353        template.push(tag.value());
354
355        if let Some((fingerprint, derivation_path)) = origin {
356            template.push(Tag::Origin.value());
357            payload.extend(fingerprint.as_bytes().to_vec());
358
359            derivation_path.encode_template(template, payload, key_map);
360        } else {
361            template.push(Tag::NoOrigin.value());
362        }
363
364        match self {
365            DescriptorSecretKey::XPrv(xprv) => xprv.encode_template(template, payload, key_map),
366            DescriptorSecretKey::MultiXPrv(xprv) => {
367                xprv.encode_template(template, payload, key_map)
368            }
369            DescriptorSecretKey::Single(single) => {
370                payload.extend(single.key.to_bytes());
371            }
372        }
373    }
374}
375
376impl EncodeTemplate for DerivationPath {
377    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
378        template.extend(varint::encode(self.len() as u128));
379
380        self.into_iter()
381            .for_each(|child| child.encode_template(template, payload, key_map));
382    }
383}
384
385impl EncodeTemplate for ChildNumber {
386    fn encode_template(&self, template: &mut Vec<u8>, _payload: &mut Vec<u8>, _key_map: &KeyMap) {
387        let value = match *self {
388            ChildNumber::Normal { index } => (index as u128) << 1,
389            ChildNumber::Hardened { index } => 1 + ((index as u128) << 1),
390        };
391
392        template.extend(varint::encode(value));
393    }
394}
395
396impl EncodeTemplate for SinglePubKey {
397    fn encode_template(&self, _template: &mut Vec<u8>, payload: &mut Vec<u8>, _key_map: &KeyMap) {
398        match self {
399            SinglePubKey::FullKey(pk) => {
400                payload.extend(pk.to_bytes());
401            }
402            SinglePubKey::XOnly(x_only) => {
403                payload.extend(x_only.serialize().to_vec());
404            }
405        }
406    }
407}
408
409impl EncodeTemplate for DescriptorXKey<Xpub> {
410    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
411        self.derivation_path
412            .encode_template(template, payload, key_map);
413        self.wildcard.encode_template(template, payload, key_map);
414
415        payload.extend(self.xkey.encode().to_vec());
416    }
417}
418
419impl EncodeTemplate for DescriptorMultiXKey<Xpub> {
420    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
421        self.derivation_paths
422            .encode_template(template, payload, key_map);
423        self.wildcard.encode_template(template, payload, key_map);
424
425        payload.extend(self.xkey.encode().to_vec());
426    }
427}
428
429impl EncodeTemplate for DescriptorXKey<Xpriv> {
430    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
431        self.derivation_path
432            .encode_template(template, payload, key_map);
433        self.wildcard.encode_template(template, payload, key_map);
434
435        payload.extend(self.xkey.encode().to_vec());
436    }
437}
438
439impl EncodeTemplate for DescriptorMultiXKey<Xpriv> {
440    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
441        self.derivation_paths
442            .encode_template(template, payload, key_map);
443        self.wildcard.encode_template(template, payload, key_map);
444
445        payload.extend(self.xkey.encode().to_vec());
446    }
447}
448
449impl EncodeTemplate for DerivPaths {
450    fn encode_template(&self, template: &mut Vec<u8>, payload: &mut Vec<u8>, key_map: &KeyMap) {
451        template.extend(varint::encode(self.paths().len() as u128));
452
453        self.paths()
454            .iter()
455            .for_each(|path| path.encode_template(template, payload, key_map));
456    }
457}
458
459impl EncodeTemplate for Wildcard {
460    fn encode_template(&self, template: &mut Vec<u8>, _payload: &mut Vec<u8>, _key_map: &KeyMap) {
461        let tag = match self {
462            Wildcard::None => Tag::NoWildcard,
463            Wildcard::Unhardened => Tag::UnhardenedWildcard,
464            Wildcard::Hardened => Tag::HardenedWildcard,
465        };
466
467        template.push(tag.value());
468    }
469}
470
471#[cfg(test)]
472mod tests {
473    use super::*;
474    use crate::{dummy, test_helpers::*};
475    use bitcoin::bip32::DerivationPath;
476    use miniscript::{BareCtx, Legacy, Miniscript, Segwitv0, Tap};
477
478    /// Helper to check equality of any EncodeTemplate and template bytes
479    fn assert_eq_template<T: EncodeTemplate>(t: T, expected: Vec<u8>) {
480        assert_eq!(template_of(t), expected);
481    }
482
483    /// Helper to check equality of any EncodeTemplate and template and payload bytes
484    fn assert_eq_template_and_payload<T: EncodeTemplate>(
485        t: T,
486        expected_template: Vec<u8>,
487        expected_payload: Vec<u8>,
488    ) {
489        assert_eq_template_and_payload_with_key_map(
490            t,
491            expected_template,
492            expected_payload,
493            &KeyMap::new(),
494        )
495    }
496
497    /// Helper to check equality of any EncodeTemplate and template and payload bytes
498    fn assert_eq_template_and_payload_with_key_map<T: EncodeTemplate>(
499        t: T,
500        expected_template: Vec<u8>,
501        expected_payload: Vec<u8>,
502        key_map: &KeyMap,
503    ) {
504        let mut template = Vec::new();
505        let mut payload = Vec::new();
506        t.encode_template(&mut template, &mut payload, key_map);
507
508        assert_eq!(template, expected_template);
509        assert_eq!(payload, expected_payload);
510    }
511
512    // Generic Miniscript helpers
513    type TerminalBare = Terminal<DescriptorPublicKey, BareCtx>;
514    type TerminalLeg = Terminal<DescriptorPublicKey, Legacy>;
515    type TerminalSw0 = Terminal<DescriptorPublicKey, Segwitv0>;
516    type TerminalTap = Terminal<DescriptorPublicKey, Tap>;
517
518    type MsBare = Miniscript<DescriptorPublicKey, BareCtx>;
519    type MsLeg = Miniscript<DescriptorPublicKey, Legacy>;
520    type MsSw0 = Miniscript<DescriptorPublicKey, Segwitv0>;
521    type MsTap = Miniscript<DescriptorPublicKey, Tap>;
522
523    #[test]
524    fn test_wildcard() {
525        assert_eq_template(Wildcard::None, vec![Tag::NoWildcard.value()]);
526        assert_eq_template(Wildcard::Unhardened, vec![Tag::UnhardenedWildcard.value()]);
527        assert_eq_template(Wildcard::Hardened, vec![Tag::HardenedWildcard.value()]);
528    }
529
530    #[test]
531    fn test_derivation_path() {
532        // Empty path: "m"
533        let dp_empty = DerivationPath::master();
534        let mut expected = varint::encode(0);
535        assert_eq_template(dp_empty, expected);
536
537        // Path: "m/0"
538        let dp_0 = dp_from_str("m/0");
539        expected = varint::encode(1);
540        expected.extend(varint::encode(0 << 1));
541        assert_eq_template(dp_0, expected);
542
543        // Path: "m/1'"
544        let dp_1h = dp_from_str("m/1'");
545        expected = varint::encode(1);
546        expected.extend(varint::encode(1 + (1u128 << 1)));
547        assert_eq_template(dp_1h, expected);
548
549        // Path: "m/42/23h/0/1h"
550        let dp_complex = dp_from_str("m/42/23h/0/1h");
551        expected = varint::encode(4);
552        expected.extend(varint::encode(42u128 << 1));
553        expected.extend(varint::encode(1 + (23u128 << 1)));
554        expected.extend(varint::encode(0u128 << 1));
555        expected.extend(varint::encode(1 + (1u128 << 1)));
556        assert_eq_template(dp_complex, expected);
557    }
558
559    #[test]
560    fn test_deriv_paths() {
561        // Single path
562        let dp1_str = "m/0";
563        let deriv_paths_one = DerivPaths::new(vec![dp_from_str(dp1_str)]).unwrap();
564        let mut expected = varint::encode(1);
565        expected.extend(template_of(dp_from_str(dp1_str)));
566        assert_eq_template(deriv_paths_one, expected);
567
568        // Multiple paths
569        let dp2_str = "m/1h";
570        let deriv_paths_multi =
571            DerivPaths::new(vec![dp_from_str(dp1_str), dp_from_str(dp2_str)]).unwrap();
572        expected = varint::encode(2);
573        expected.extend(template_of(dp_from_str(dp1_str)));
574        expected.extend(template_of(dp_from_str(dp2_str)));
575        assert_eq_template(deriv_paths_multi, expected);
576    }
577
578    #[test]
579    fn test_descriptor_public_key() {
580        // Single FullKey Compressed, No Origin
581        let (pk1, dpk1) = create_dpk_single_full(true, None, 1);
582        let expected_template_pk1 =
583            [vec![Tag::CompressedFullKey.value(), Tag::NoOrigin.value()]].concat();
584        assert_eq_template_and_payload(dpk1, expected_template_pk1, pk1.to_bytes());
585
586        // Single FullKey Uncompressed, No Origin
587        let (pk2, dpk2) = create_dpk_single_full(false, None, 2);
588        let expected_template_pk2 = [vec![
589            Tag::UncompressedFullKey.value(),
590            Tag::NoOrigin.value(),
591        ]]
592        .concat();
593        assert_eq_template_and_payload(dpk2, expected_template_pk2, pk2.to_bytes());
594
595        // Single XOnlyKey, No Origin
596        let (pk_xonly, dpk_xonly) = create_dpk_xonly_no_origin(1);
597        let expected_pk_xonly = [vec![Tag::XOnly.value(), Tag::NoOrigin.value()]].concat();
598        assert_eq_template_and_payload(dpk_xonly, expected_pk_xonly, pk_xonly.serialize().to_vec());
599
600        // Single FullKey Compressed, With Origin
601        let origin_fp = fp_from_str("12345678");
602        let origin_path = dp_from_str("m/84h/0h/0h");
603        let (pk3, dpk3) = create_dpk_single_full(true, Some((origin_fp, origin_path.clone())), 3);
604        let expected_template = [
605            vec![Tag::CompressedFullKey.value(), Tag::Origin.value()],
606            template_of(origin_path.clone()),
607        ]
608        .concat();
609        let expected_payload = [origin_fp.as_bytes().to_vec(), pk3.to_bytes()].concat();
610        assert_eq_template_and_payload(dpk3, expected_template, expected_payload);
611
612        // XPub, No Origin, specific derivation path, NoWildcard
613        let xpub_path_str = "m/0/0";
614        let (xpub1, dpk_xpub1) =
615            create_dpk_xpub(None, xpub_path_str, dummy::xpub(), Wildcard::None);
616        let expected_template = [
617            vec![Tag::XPub.value(), Tag::NoOrigin.value()],
618            template_of(dp_from_str(xpub_path_str)),
619            template_of(Wildcard::None),
620        ]
621        .concat();
622        assert_eq_template_and_payload(dpk_xpub1, expected_template, xpub1.encode().to_vec());
623
624        // XPub, With Origin, different derivation path, UnhardenedWildcard
625        let (xpub2, dpk_xpub2) = create_dpk_xpub(
626            Some((origin_fp, origin_path.clone())),
627            "m/1",
628            dummy::xpub(),
629            Wildcard::Unhardened,
630        );
631        let expected_template = [
632            vec![Tag::XPub.value(), Tag::Origin.value()],
633            template_of(origin_path.clone()),
634            template_of(dp_from_str("m/1")),
635            template_of(Wildcard::Unhardened),
636        ]
637        .concat();
638        let expected_payload = [origin_fp.as_bytes().to_vec(), xpub2.encode().to_vec()].concat();
639        assert_eq_template_and_payload(dpk_xpub2, expected_template, expected_payload);
640
641        // MultiXPub, No Origin, specific derivation paths, HardenedWildcard
642        let multixpub_paths_str = ["m/0/0", "m/0/1"];
643        let (xpub1, dpk_multixpub1) = create_dpk_multixpub(
644            None,
645            &multixpub_paths_str,
646            dummy::xpub(),
647            Wildcard::Hardened,
648        );
649        let paths =
650            DerivPaths::new(multixpub_paths_str.iter().map(|s| dp_from_str(s)).collect()).unwrap();
651        let expected_dpk_multixpub1 = [
652            vec![Tag::MultiXPub.value(), Tag::NoOrigin.value()],
653            template_of(paths),
654            template_of(Wildcard::Hardened),
655        ]
656        .concat();
657        assert_eq_template_and_payload(
658            dpk_multixpub1,
659            expected_dpk_multixpub1,
660            xpub1.encode().to_vec(),
661        );
662    }
663
664    #[test]
665    fn test_descriptor_secret_key() {
666        // Dummy Descriptor Public Key
667        let (_, dpk) = create_dpk_single_full(true, None, 1);
668        let mut km = KeyMap::new();
669
670        // Single Key Compressed, No Origin
671        let (sk1, dsk1) = create_dsk_single(true, None, 1);
672        km.insert(dpk.clone(), dsk1.clone());
673        let expected_template_sk1 = [vec![
674            Tag::CompressedSinglePriv.value(),
675            Tag::NoOrigin.value(),
676        ]]
677        .concat();
678        assert_eq_template_and_payload_with_key_map(
679            dpk.clone(),
680            expected_template_sk1,
681            sk1.to_bytes(),
682            &km,
683        );
684
685        // Single Key Uncompressed, No Origin
686        let (sk2, dsk2) = create_dsk_single(false, None, 2);
687        km.insert(dpk.clone(), dsk2.clone());
688        let expected_template_sk2 = [vec![
689            Tag::UncompressedSinglePriv.value(),
690            Tag::NoOrigin.value(),
691        ]]
692        .concat();
693        assert_eq_template_and_payload_with_key_map(
694            dpk.clone(),
695            expected_template_sk2,
696            sk2.to_bytes(),
697            &km,
698        );
699
700        // Single Key Compressed, With Origin
701        let origin_fp = fp_from_str("12345678");
702        let origin_path = dp_from_str("m/84h/0h/0h");
703        let (sk3, dsk3) = create_dsk_single(true, Some((origin_fp, origin_path.clone())), 3);
704        km.insert(dpk.clone(), dsk3.clone());
705        let expected_template = [
706            vec![Tag::CompressedSinglePriv.value(), Tag::Origin.value()],
707            template_of(origin_path.clone()),
708        ]
709        .concat();
710        let expected_payload = [origin_fp.as_bytes().to_vec(), sk3.to_bytes()].concat();
711        assert_eq_template_and_payload_with_key_map(
712            dpk.clone(),
713            expected_template,
714            expected_payload,
715            &km,
716        );
717
718        // XPriv, No Origin, specific derivation path, NoWildcard
719        let xpriv_path_str = "m/0/0";
720        let (xpriv1, dsk_xpriv1) =
721            create_dsk_xpriv(None, xpriv_path_str, dummy::xpriv(), Wildcard::None);
722        km.insert(dpk.clone(), dsk_xpriv1.clone());
723        let expected_template = [
724            vec![Tag::XPriv.value(), Tag::NoOrigin.value()],
725            template_of(dp_from_str(xpriv_path_str)),
726            template_of(Wildcard::None),
727        ]
728        .concat();
729        assert_eq_template_and_payload_with_key_map(
730            dpk.clone(),
731            expected_template,
732            xpriv1.encode().to_vec(),
733            &km,
734        );
735
736        // XPriv, With Origin, different derivation path, UnhardenedWildcard
737        let (xpriv2, dsk_xpriv2) = create_dsk_xpriv(
738            Some((origin_fp, origin_path.clone())),
739            "m/1",
740            dummy::xpriv(),
741            Wildcard::Unhardened,
742        );
743        km.insert(dpk.clone(), dsk_xpriv2.clone());
744        let expected_template = [
745            vec![Tag::XPriv.value(), Tag::Origin.value()],
746            template_of(origin_path.clone()),
747            template_of(dp_from_str("m/1")),
748            template_of(Wildcard::Unhardened),
749        ]
750        .concat();
751        let expected_payload = [origin_fp.as_bytes().to_vec(), xpriv2.encode().to_vec()].concat();
752        assert_eq_template_and_payload_with_key_map(
753            dpk.clone(),
754            expected_template,
755            expected_payload,
756            &km,
757        );
758
759        // MultiXPub, No Origin, specific derivation paths, HardenedWildcard
760        let multixpriv_paths_str = ["m/0/0", "m/0/1"];
761        let (xpriv1, dsk_multixpriv1) = create_dsk_multixpriv(
762            None,
763            &multixpriv_paths_str,
764            dummy::xpriv(),
765            Wildcard::Hardened,
766        );
767        km.insert(dpk.clone(), dsk_multixpriv1.clone());
768        let paths = DerivPaths::new(
769            multixpriv_paths_str
770                .iter()
771                .map(|s| dp_from_str(s))
772                .collect(),
773        )
774        .unwrap();
775        let expected_dsk_multixpriv1 = [
776            vec![Tag::MultiXPriv.value(), Tag::NoOrigin.value()],
777            template_of(paths),
778            template_of(Wildcard::Hardened),
779        ]
780        .concat();
781        assert_eq_template_and_payload_with_key_map(
782            dpk.clone(),
783            expected_dsk_multixpriv1,
784            xpriv1.encode().to_vec(),
785            &km,
786        );
787    }
788
789    #[test]
790    fn test_descriptor_xkey_multixkey() {
791        let xpub = dummy::xpub();
792
793        // DescriptorXKey
794        let xkey = DescriptorXKey {
795            origin: None,
796            xkey: xpub,
797            derivation_path: dp_from_str("m/0"),
798            wildcard: Wildcard::Unhardened,
799        };
800        let expected_xkey_template = [
801            template_of(dp_from_str("m/0")),
802            template_of(Wildcard::Unhardened),
803        ]
804        .concat();
805        assert_eq_template_and_payload(
806            xkey.clone(),
807            expected_xkey_template,
808            xpub.clone().encode().to_vec(),
809        );
810
811        // DescriptorMultiXKey
812        let multixkey_paths_str = ["m/0/0", "m/0/1"];
813        let multixkey_paths =
814            DerivPaths::new(multixkey_paths_str.iter().map(|s| dp_from_str(s)).collect()).unwrap();
815        let multixkey = DescriptorMultiXKey {
816            origin: None,
817            xkey: xpub,
818            derivation_paths: multixkey_paths.clone(),
819            wildcard: Wildcard::None,
820        };
821        let expected_multixkey =
822            [template_of(multixkey_paths), template_of(Wildcard::None)].concat();
823        assert_eq_template_and_payload(
824            multixkey,
825            expected_multixkey,
826            xpub.clone().encode().to_vec(),
827        );
828    }
829
830    #[test]
831    fn test_descriptor_xkey_multixkey_priv() {
832        let xpriv = dummy::xpriv();
833
834        // DescriptorXKey
835        let xkey = DescriptorXKey {
836            origin: None,
837            xkey: xpriv,
838            derivation_path: dp_from_str("m/0"),
839            wildcard: Wildcard::Unhardened,
840        };
841        let expected_xkey_template = [
842            template_of(dp_from_str("m/0")),
843            template_of(Wildcard::Unhardened),
844        ]
845        .concat();
846        assert_eq_template_and_payload(
847            xkey.clone(),
848            expected_xkey_template,
849            xpriv.clone().encode().to_vec(),
850        );
851
852        // DescriptorMultiXKey
853        let multixkey_paths_str = ["m/0/0", "m/0/1"];
854        let multixkey_paths =
855            DerivPaths::new(multixkey_paths_str.iter().map(|s| dp_from_str(s)).collect()).unwrap();
856        let multixkey = DescriptorMultiXKey {
857            origin: None,
858            xkey: xpriv,
859            derivation_paths: multixkey_paths.clone(),
860            wildcard: Wildcard::None,
861        };
862        let expected_multixkey =
863            [template_of(multixkey_paths), template_of(Wildcard::None)].concat();
864        assert_eq_template_and_payload(
865            multixkey,
866            expected_multixkey,
867            xpriv.clone().encode().to_vec(),
868        );
869    }
870
871    #[test]
872    fn test_miniscript_terminals() {
873        let pk = create_dpk_single_compressed_no_origin(1);
874
875        assert_eq_template(TerminalSw0::True, vec![Tag::True.value()]);
876        assert_eq_template(TerminalSw0::False, vec![Tag::False.value()]);
877
878        let expected_pk_k = [vec![Tag::PkK.value()], template_of(pk.clone())].concat();
879        assert_eq_template(TerminalSw0::PkK(pk.clone()), expected_pk_k);
880
881        let expected_pk_h = [vec![Tag::PkH.value()], template_of(pk.clone())].concat();
882        assert_eq_template(TerminalSw0::PkH(pk.clone()), expected_pk_h);
883
884        // Terminals with ignored values
885        let hash160 = dummy::hash160();
886        assert_eq_template_and_payload(
887            TerminalSw0::RawPkH(hash160),
888            vec![Tag::RawPkH.value()],
889            hash160.as_byte_array().to_vec(),
890        );
891        assert_eq_template_and_payload(
892            TerminalSw0::Hash160(hash160),
893            vec![Tag::Hash160.value()],
894            hash160.as_byte_array().to_vec(),
895        );
896
897        let after = dummy::after();
898        assert_eq_template_and_payload(
899            TerminalSw0::After(after),
900            vec![Tag::After.value()],
901            varint::encode(after.to_consensus_u32().into()),
902        );
903
904        let older = dummy::older();
905        assert_eq_template_and_payload(
906            TerminalSw0::Older(older),
907            vec![Tag::Older.value()],
908            varint::encode(after.to_consensus_u32().into()),
909        );
910
911        let sha256 = dummy::sha256();
912        assert_eq_template_and_payload(
913            TerminalSw0::Sha256(sha256),
914            vec![Tag::Sha256.value()],
915            sha256.as_byte_array().to_vec(),
916        );
917
918        let hash256 = dummy::hash256();
919        assert_eq_template_and_payload(
920            TerminalSw0::Hash256(hash256),
921            vec![Tag::Hash256.value()],
922            hash256.as_byte_array().to_vec(),
923        );
924
925        let ripemd160 = dummy::ripemd160();
926        assert_eq_template_and_payload(
927            TerminalSw0::Ripemd160(ripemd160),
928            vec![Tag::Ripemd160.value()],
929            ripemd160.as_byte_array().to_vec(),
930        );
931    }
932
933    #[test]
934    fn test_miniscript_ops() {
935        let pk = create_dpk_single_compressed_no_origin(1);
936        let ms_true = Arc::new(MsSw0::TRUE);
937        let ms_false = Arc::new(MsSw0::FALSE);
938        let ms_pk_k = Arc::new(MsSw0::from_ast(TerminalSw0::PkK(pk)).unwrap());
939
940        // Unary
941        assert_eq_template(
942            TerminalSw0::Alt(ms_true.clone()),
943            [vec![Tag::Alt.value()], template_of(ms_true.clone())].concat(),
944        );
945        assert_eq_template(
946            TerminalSw0::Swap(ms_true.clone()),
947            [vec![Tag::Swap.value()], template_of(ms_true.clone())].concat(),
948        );
949        assert_eq_template(
950            TerminalSw0::Check(ms_true.clone()),
951            [vec![Tag::Check.value()], template_of(ms_true.clone())].concat(),
952        );
953        assert_eq_template(
954            TerminalSw0::DupIf(ms_true.clone()),
955            [vec![Tag::DupIf.value()], template_of(ms_true.clone())].concat(),
956        );
957        assert_eq_template(
958            TerminalSw0::Verify(ms_true.clone()),
959            [vec![Tag::Verify.value()], template_of(ms_true.clone())].concat(),
960        );
961        assert_eq_template(
962            TerminalSw0::NonZero(ms_true.clone()),
963            [vec![Tag::NonZero.value()], template_of(ms_true.clone())].concat(),
964        );
965        assert_eq_template(
966            TerminalSw0::ZeroNotEqual(ms_true.clone()),
967            [
968                vec![Tag::ZeroNotEqual.value()],
969                template_of(ms_true.clone()),
970            ]
971            .concat(),
972        );
973
974        // Binary
975        assert_eq_template(
976            TerminalSw0::AndV(ms_true.clone(), ms_false.clone()),
977            [
978                vec![Tag::AndV.value()],
979                template_of(ms_true.clone()),
980                template_of(ms_false.clone()),
981            ]
982            .concat(),
983        );
984        assert_eq_template(
985            TerminalSw0::AndB(ms_true.clone(), ms_false.clone()),
986            [
987                vec![Tag::AndB.value()],
988                template_of(ms_true.clone()),
989                template_of(ms_false.clone()),
990            ]
991            .concat(),
992        );
993        assert_eq_template(
994            TerminalSw0::OrB(ms_true.clone(), ms_false.clone()),
995            [
996                vec![Tag::OrB.value()],
997                template_of(ms_true.clone()),
998                template_of(ms_false.clone()),
999            ]
1000            .concat(),
1001        );
1002        assert_eq_template(
1003            TerminalSw0::OrC(ms_true.clone(), ms_false.clone()),
1004            [
1005                vec![Tag::OrC.value()],
1006                template_of(ms_true.clone()),
1007                template_of(ms_false.clone()),
1008            ]
1009            .concat(),
1010        );
1011        assert_eq_template(
1012            TerminalSw0::OrD(ms_true.clone(), ms_false.clone()),
1013            [
1014                vec![Tag::OrD.value()],
1015                template_of(ms_true.clone()),
1016                template_of(ms_false.clone()),
1017            ]
1018            .concat(),
1019        );
1020        assert_eq_template(
1021            TerminalSw0::OrI(ms_true.clone(), ms_false.clone()),
1022            [
1023                vec![Tag::OrI.value()],
1024                template_of(ms_true.clone()),
1025                template_of(ms_false.clone()),
1026            ]
1027            .concat(),
1028        );
1029
1030        // Ternary
1031        assert_eq_template(
1032            TerminalSw0::AndOr(ms_true.clone(), ms_false.clone(), ms_pk_k.clone()),
1033            [
1034                vec![Tag::AndOr.value()],
1035                template_of(ms_true.clone()),
1036                template_of(ms_false.clone()),
1037                template_of(ms_pk_k),
1038            ]
1039            .concat(),
1040        );
1041    }
1042
1043    #[test]
1044    fn test_threshold_miniscript() {
1045        let pk1 = create_dpk_single_compressed_no_origin(1);
1046        let pk2 = create_dpk_single_compressed_no_origin(2);
1047        let ms1 = Arc::new(MsSw0::from_ast(TerminalSw0::PkK(pk1.clone())).unwrap());
1048        let ms2 = Arc::new(MsSw0::from_ast(TerminalSw0::PkK(pk2.clone())).unwrap());
1049
1050        let k = 1;
1051        let n = 2;
1052
1053        // Thresh
1054        let subs = vec![ms1.clone(), ms2.clone()];
1055        let thresh = Threshold::<Arc<MsSw0>, 0>::new(k, subs.clone()).unwrap();
1056        let mut expected_thresh_inner = varint::encode(k as u128);
1057        expected_thresh_inner.extend(varint::encode(n as u128));
1058        for sub in subs {
1059            expected_thresh_inner.extend(template_of(sub));
1060        }
1061        let expected_template = [vec![Tag::Thresh.value()], expected_thresh_inner].concat();
1062        assert_eq_template(TerminalSw0::Thresh(thresh), expected_template);
1063
1064        // Multi
1065        let pks = vec![pk1.clone(), pk2.clone()];
1066        let multi = Threshold::<DescriptorPublicKey, 20>::new(k, pks.clone()).unwrap();
1067        let mut expected_thresh_inner = varint::encode(k as u128);
1068        expected_thresh_inner.extend(varint::encode(n as u128));
1069        for pk in pks {
1070            expected_thresh_inner.extend(template_of(pk.clone()));
1071        }
1072        let expected_template = [vec![Tag::Multi.value()], expected_thresh_inner].concat();
1073        assert_eq_template(TerminalSw0::Multi(multi), expected_template);
1074
1075        // MultiA
1076        let pks = vec![pk1.clone(), pk2.clone()];
1077        let multi_a = Threshold::<DescriptorPublicKey, 125000>::new(k, pks.clone()).unwrap();
1078        let mut expected_thresh_inner = varint::encode(k as u128);
1079        expected_thresh_inner.extend(varint::encode(n as u128));
1080        for pk in pks {
1081            expected_thresh_inner.extend(template_of(pk.clone()));
1082        }
1083        let expected_template = [vec![Tag::MultiA.value()], expected_thresh_inner].concat();
1084        assert_eq_template(TerminalSw0::MultiA(multi_a), expected_template);
1085    }
1086
1087    #[test]
1088    fn test_sorted_multi() {
1089        let pk1 = create_dpk_single_compressed_no_origin(1);
1090        let pk2 = create_dpk_single_compressed_no_origin(2);
1091        let pk3 = create_dpk_single_compressed_no_origin(3);
1092
1093        let k = 2;
1094        let n = 3;
1095
1096        let pks = vec![pk1.clone(), pk2.clone(), pk3.clone()];
1097        let sorted_multi =
1098            SortedMultiVec::<DescriptorPublicKey, Segwitv0>::new(k, pks.clone()).unwrap();
1099        let mut expected_inner = varint::encode(k as u128);
1100        expected_inner.extend(varint::encode(n as u128));
1101        for pk_in_vec in pks {
1102            expected_inner.extend(template_of(pk_in_vec));
1103        }
1104        let expected_template = [vec![Tag::SortedMulti.value()], expected_inner].concat();
1105        assert_eq_template(sorted_multi, expected_template);
1106    }
1107
1108    #[test]
1109    fn test_taptree() {
1110        let (_, pk1) = create_dpk_xonly_no_origin(1);
1111        let ms_leaf1 = Arc::new(MsTap::from_ast(TerminalTap::PkK(pk1.clone())).unwrap());
1112
1113        // Leaf
1114        let tap_leaf = TapTree::Leaf(ms_leaf1.clone());
1115        let expected_leaf = [vec![Tag::TapTree.value()], template_of(ms_leaf1.clone())].concat();
1116        assert_eq_template(tap_leaf.clone(), expected_leaf);
1117
1118        // Tree
1119        let (_, pk2) = create_dpk_xonly_no_origin(2);
1120        let ms_leaf2 = Arc::new(MsTap::from_ast(TerminalTap::PkK(pk2.clone())).unwrap());
1121        let tap_leaf2 = TapTree::Leaf(ms_leaf2.clone());
1122
1123        let tap_tree = TapTree::Tree {
1124            left: Arc::new(tap_leaf.clone()),
1125            right: Arc::new(tap_leaf2.clone()),
1126            height: 1,
1127        };
1128        let expected_tree = [
1129            vec![Tag::TapTree.value()],
1130            template_of(tap_leaf),
1131            template_of(tap_leaf2),
1132        ]
1133        .concat();
1134        assert_eq_template(tap_tree, expected_tree);
1135    }
1136
1137    #[test]
1138    fn test_bare_pkh_wpkh() {
1139        let pk_full = create_dpk_single_compressed_no_origin(1);
1140        let ms_bare_pkk = MsBare::from_ast(TerminalBare::PkK(pk_full.clone())).unwrap();
1141        let ms_bare_check_pkk = MsBare::from_ast(TerminalBare::Check(ms_bare_pkk.into())).unwrap();
1142
1143        // Bare
1144        let bare_desc = Bare::new(ms_bare_check_pkk.clone()).unwrap();
1145        let expected_bare = [
1146            vec![Tag::Bare.value()],
1147            template_of(ms_bare_check_pkk.clone()),
1148        ]
1149        .concat();
1150        assert_eq_template(bare_desc, expected_bare);
1151
1152        // Pkh
1153        let pkh_desc = Pkh::new(pk_full.clone()).unwrap();
1154        let expected_pkh = [vec![Tag::Pkh.value()], template_of(pk_full.clone())].concat();
1155        assert_eq_template(pkh_desc, expected_pkh);
1156
1157        // Wpkh
1158        let wpkh_desc = Wpkh::new(pk_full.clone()).unwrap();
1159        let expected_wpkh = [vec![Tag::Wpkh.value()], template_of(pk_full.clone())].concat();
1160        assert_eq_template(wpkh_desc, expected_wpkh);
1161    }
1162
1163    #[test]
1164    fn test_sh() {
1165        let pk1 = create_dpk_single_compressed_no_origin(1);
1166        let pk2 = create_dpk_single_compressed_no_origin(2);
1167
1168        // Sh(Wpkh)
1169        let wpkh_inner = Wpkh::new(pk1.clone()).unwrap();
1170        let sh_wpkh = Sh::new_with_wpkh(wpkh_inner.clone());
1171        let expected_sh_wpkh = [vec![Tag::Sh.value()], template_of(wpkh_inner)].concat();
1172        assert_eq_template(sh_wpkh, expected_sh_wpkh);
1173
1174        // Sh(Wsh)
1175        let ms_wsh = MsSw0::from_ast(TerminalSw0::True).unwrap();
1176        let wsh = Wsh::new(ms_wsh).unwrap();
1177        let sh_wsh = Sh::new_with_wsh(wsh.clone());
1178        let expected_sh_wsh = [vec![Tag::Sh.value()], template_of(wsh)].concat();
1179        assert_eq_template(sh_wsh, expected_sh_wsh);
1180
1181        // Sh(SortedMulti)
1182        let pks = vec![pk1.clone(), pk2.clone()];
1183        let sorted_multi = SortedMultiVec::<_, Legacy>::new(1, pks.clone()).unwrap();
1184        let sh_sortedmulti = Sh::new_sortedmulti(1, pks).unwrap();
1185        let expected_sh_sortedmulti = [vec![Tag::Sh.value()], template_of(sorted_multi)].concat();
1186        assert_eq_template(sh_sortedmulti, expected_sh_sortedmulti);
1187
1188        // Sh(Miniscript)
1189        let ms_sh = MsLeg::from_ast(TerminalLeg::True).unwrap();
1190        let sh_ms = Sh::new(ms_sh.clone()).unwrap();
1191        let expected_sh_ms = [vec![Tag::Sh.value()], template_of(ms_sh)].concat();
1192        assert_eq_template(sh_ms, expected_sh_ms);
1193    }
1194
1195    #[test]
1196    fn test_wsh() {
1197        let pk1 = create_dpk_single_compressed_no_origin(1);
1198        let pk2 = create_dpk_single_compressed_no_origin(2);
1199
1200        // Wsh(SortedMulti)
1201        let pks = vec![pk1.clone(), pk2.clone()];
1202        let sorted_multi = SortedMultiVec::<_, Segwitv0>::new(1, pks.clone()).unwrap();
1203        let wsh_sortedmulti = Wsh::new_sortedmulti(1, pks).unwrap();
1204        let expected_wsh_sortedmulti = [vec![Tag::Wsh.value()], template_of(sorted_multi)].concat();
1205        assert_eq_template(wsh_sortedmulti, expected_wsh_sortedmulti);
1206
1207        // Wsh(Miniscript)
1208        let ms_wsh = MsSw0::from_ast(TerminalSw0::True).unwrap();
1209        let wsh_ms = Wsh::new(ms_wsh.clone()).unwrap();
1210        let expected_wsh_ms = [vec![Tag::Wsh.value()], template_of(ms_wsh)].concat();
1211        assert_eq_template(wsh_ms, expected_wsh_ms);
1212    }
1213
1214    #[test]
1215    fn test_tr() {
1216        let (_, internal_key) = create_dpk_xonly_no_origin(1);
1217
1218        // Tr with no TapTree
1219        let tr_no_tree = Tr::new(internal_key.clone(), None).unwrap();
1220        let expected_tr_no_tree =
1221            [vec![Tag::Tr.value()], template_of(internal_key.clone())].concat();
1222        assert_eq_template(tr_no_tree, expected_tr_no_tree);
1223
1224        // Tr with TapTree
1225        let leaf_ms = MsTap::from_ast(TerminalTap::True).unwrap();
1226        let tap_tree = TapTree::Leaf(leaf_ms.into());
1227        let tr_with_tree = Tr::new(internal_key.clone(), Some(tap_tree.clone())).unwrap();
1228        let expected_tr_with_tree = [
1229            vec![Tag::Tr.value()],
1230            template_of(internal_key),
1231            template_of(tap_tree),
1232        ]
1233        .concat();
1234        assert_eq_template(tr_with_tree, expected_tr_with_tree);
1235    }
1236
1237    #[test]
1238    fn test_descriptor() {
1239        let pk = create_dpk_single_compressed_no_origin(1);
1240
1241        let ms_bare_pkk = MsBare::from_ast(TerminalBare::PkK(pk.clone())).unwrap();
1242        let ms_bare_check_pkk = MsBare::from_ast(TerminalBare::Check(ms_bare_pkk.into())).unwrap();
1243        let bare = Bare::new(ms_bare_check_pkk.clone()).unwrap();
1244        let descriptor = Descriptor::Bare(bare.clone());
1245        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1246        assert_eq!(template, template_of(bare.clone()));
1247        assert_eq!(payload, payload_of(bare.clone()));
1248
1249        let pkh = Pkh::new(pk.clone()).unwrap();
1250        let descriptor = Descriptor::Pkh(pkh.clone());
1251        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1252        assert_eq!(template, template_of(pkh.clone()));
1253        assert_eq!(payload, payload_of(pkh));
1254
1255        let ms_sh = MsLeg::from_ast(TerminalLeg::True).unwrap();
1256        let sh_ms = Sh::new(ms_sh.clone()).unwrap();
1257        let descriptor = Descriptor::Sh(sh_ms.clone());
1258        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1259        assert_eq!(template, template_of(sh_ms.clone()));
1260        assert_eq!(payload, payload_of(sh_ms.clone()));
1261
1262        let wpkh = Wpkh::new(pk.clone()).unwrap();
1263        let descriptor = Descriptor::Wpkh(wpkh.clone());
1264        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1265        assert_eq!(template, template_of(wpkh.clone()));
1266        assert_eq!(payload, payload_of(wpkh.clone()));
1267
1268        let ms_wsh = MsSw0::from_ast(TerminalSw0::True).unwrap();
1269        let wsh_ms = Wsh::new(ms_wsh.clone()).unwrap();
1270        let descriptor = Descriptor::Wsh(wsh_ms.clone());
1271        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1272        assert_eq!(template, template_of(wsh_ms.clone()));
1273        assert_eq!(payload, payload_of(wsh_ms.clone()));
1274
1275        let tr = Tr::new(pk.clone(), None).unwrap();
1276        let descriptor = Descriptor::Tr(tr.clone());
1277        let (template, payload) = encode(descriptor.clone(), &KeyMap::new());
1278        assert_eq!(template, template_of(tr.clone()));
1279        assert_eq!(payload, payload_of(tr.clone()));
1280    }
1281}