1use 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
24pub 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
34pub(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 fn assert_eq_template<T: EncodeTemplate>(t: T, expected: Vec<u8>) {
480 assert_eq!(template_of(t), expected);
481 }
482
483 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 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 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 let dp_empty = DerivationPath::master();
534 let mut expected = varint::encode(0);
535 assert_eq_template(dp_empty, expected);
536
537 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 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 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 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 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 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 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 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 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 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 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 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 let (_, dpk) = create_dpk_single_full(true, None, 1);
668 let mut km = KeyMap::new();
669
670 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}