@@ -73,6 +73,38 @@ macro_rules! impl_top_level_pk {
73
73
} } ;
74
74
}
75
75
76
+ #[ doc( hidden) ]
77
+ #[ macro_export]
78
+ macro_rules! impl_top_level_tr {
79
+ ( $internal_key: expr, $tap_tree: expr ) => { {
80
+ use $crate:: miniscript:: descriptor:: { Descriptor , DescriptorPublicKey , Tr } ;
81
+ use $crate:: miniscript:: Tap ;
82
+
83
+ #[ allow( unused_imports) ]
84
+ use $crate:: keys:: { DescriptorKey , IntoDescriptorKey } ;
85
+ let secp = $crate:: bitcoin:: secp256k1:: Secp256k1 :: new( ) ;
86
+
87
+ $internal_key
88
+ . into_descriptor_key( )
89
+ . and_then( |key: DescriptorKey <Tap >| key. extract( & secp) )
90
+ . map_err( $crate:: descriptor:: DescriptorError :: Key )
91
+ . and_then( |( pk, mut key_map, mut valid_networks) | {
92
+ let tap_tree = $tap_tree. map( |( tap_tree, tree_keymap, tree_networks) | {
93
+ key_map. extend( tree_keymap. into_iter( ) ) ;
94
+ valid_networks = $crate:: keys:: merge_networks( & valid_networks, & tree_networks) ;
95
+
96
+ tap_tree
97
+ } ) ;
98
+
99
+ Ok ( (
100
+ Descriptor :: <DescriptorPublicKey >:: Tr ( Tr :: new( pk, tap_tree) ?) ,
101
+ key_map,
102
+ valid_networks,
103
+ ) )
104
+ } )
105
+ } } ;
106
+ }
107
+
76
108
#[ doc( hidden) ]
77
109
#[ macro_export]
78
110
macro_rules! impl_leaf_opcode {
@@ -228,6 +260,62 @@ macro_rules! impl_sortedmulti {
228
260
229
261
}
230
262
263
+ #[ doc( hidden) ]
264
+ #[ macro_export]
265
+ macro_rules! parse_tap_tree {
266
+ ( @merge $tree_a: expr, $tree_b: expr) => { {
267
+ use std:: sync:: Arc ;
268
+ use $crate:: miniscript:: descriptor:: TapTree ;
269
+
270
+ $tree_a
271
+ . and_then( |tree_a| Ok ( ( tree_a, $tree_b?) ) )
272
+ . and_then( |( ( a_tree, mut a_keymap, a_networks) , ( b_tree, b_keymap, b_networks) ) | {
273
+ a_keymap. extend( b_keymap. into_iter( ) ) ;
274
+ Ok ( ( TapTree :: Tree ( Arc :: new( a_tree) , Arc :: new( b_tree) ) , a_keymap, $crate:: keys:: merge_networks( & a_networks, & b_networks) ) )
275
+ } )
276
+
277
+ } } ;
278
+
279
+ // Two sub-trees
280
+ ( { { $( $tree_a: tt ) * } , { $( $tree_b: tt ) * } } ) => { {
281
+ let tree_a = $crate:: parse_tap_tree!( { $( $tree_a ) * } ) ;
282
+ let tree_b = $crate:: parse_tap_tree!( { $( $tree_b ) * } ) ;
283
+
284
+ $crate:: parse_tap_tree!( @merge tree_a, tree_b)
285
+ } } ;
286
+
287
+ // One leaf and a sub-tree
288
+ ( { $op_a: ident ( $( $minisc_a: tt ) * ) , { $( $tree_b: tt ) * } } ) => { {
289
+ let tree_a = $crate:: parse_tap_tree!( $op_a ( $( $minisc_a ) * ) ) ;
290
+ let tree_b = $crate:: parse_tap_tree!( { $( $tree_b ) * } ) ;
291
+
292
+ $crate:: parse_tap_tree!( @merge tree_a, tree_b)
293
+ } } ;
294
+ ( { { $( $tree_a: tt ) * } , $op_b: ident ( $( $minisc_b: tt ) * ) } ) => { {
295
+ let tree_a = $crate:: parse_tap_tree!( { $( $tree_a ) * } ) ;
296
+ let tree_b = $crate:: parse_tap_tree!( $op_b ( $( $minisc_b ) * ) ) ;
297
+
298
+ $crate:: parse_tap_tree!( @merge tree_a, tree_b)
299
+ } } ;
300
+
301
+ // Two leaves
302
+ ( { $op_a: ident ( $( $minisc_a: tt ) * ) , $op_b: ident ( $( $minisc_b: tt ) * ) } ) => { {
303
+ let tree_a = $crate:: parse_tap_tree!( $op_a ( $( $minisc_a ) * ) ) ;
304
+ let tree_b = $crate:: parse_tap_tree!( $op_b ( $( $minisc_b ) * ) ) ;
305
+
306
+ $crate:: parse_tap_tree!( @merge tree_a, tree_b)
307
+ } } ;
308
+
309
+ // Single leaf
310
+ ( $op: ident ( $( $minisc: tt ) * ) ) => { {
311
+ use std:: sync:: Arc ;
312
+ use $crate:: miniscript:: descriptor:: TapTree ;
313
+
314
+ $crate:: fragment!( $op ( $( $minisc ) * ) )
315
+ . map( |( a_minisc, a_keymap, a_networks) | ( TapTree :: Leaf ( Arc :: new( a_minisc) ) , a_keymap, a_networks) )
316
+ } } ;
317
+ }
318
+
231
319
#[ doc( hidden) ]
232
320
#[ macro_export]
233
321
macro_rules! apply_modifier {
@@ -441,6 +529,15 @@ macro_rules! descriptor {
441
529
( wsh ( $( $minisc: tt ) * ) ) => ( {
442
530
$crate:: impl_top_level_sh!( Wsh , new, new_sortedmulti, Segwitv0 , $( $minisc ) * )
443
531
} ) ;
532
+
533
+ ( tr ( $internal_key: expr ) ) => ( {
534
+ $crate:: impl_top_level_tr!( $internal_key, None )
535
+ } ) ;
536
+ ( tr ( $internal_key: expr, $( $taptree: tt ) * ) ) => ( {
537
+ let tap_tree = $crate:: parse_tap_tree!( $( $taptree ) * ) ;
538
+ tap_tree
539
+ . and_then( |tap_tree| $crate:: impl_top_level_tr!( $internal_key, Some ( tap_tree) ) )
540
+ } ) ;
444
541
}
445
542
446
543
#[ doc( hidden) ]
0 commit comments