@@ -23,7 +23,7 @@ use sync::Arc;
23
23
24
24
use self :: checksum:: verify_checksum;
25
25
use crate :: miniscript:: { satisfy, Legacy , Miniscript , Segwitv0 } ;
26
- use crate :: plan:: { AssetProvider , Plan } ;
26
+ use crate :: plan:: { AssetProvider , Plan , Assets } ;
27
27
use crate :: prelude:: * ;
28
28
use crate :: {
29
29
expression, hash256, miniscript, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier ,
@@ -566,6 +566,101 @@ impl Descriptor<DefiniteDescriptorKey> {
566
566
}
567
567
}
568
568
569
+ impl Descriptor < DescriptorPublicKey > {
570
+ /// Get all possible assets for a given descriptor
571
+ pub fn get_all_assets ( & self ) -> Result < Vec < Assets > , Error > {
572
+
573
+ match self {
574
+ Descriptor :: Bare ( k) => Ok ( k. as_inner ( ) . get_all_assets ( ) ) ,
575
+ Descriptor :: Pkh ( k) => {
576
+ let mut asset = Assets :: new ( ) ;
577
+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
578
+ Ok ( vec ! [ asset] )
579
+ }
580
+ Descriptor :: Wpkh ( k) => {
581
+ let mut asset = Assets :: new ( ) ;
582
+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
583
+ Ok ( vec ! [ asset] )
584
+ }
585
+ Descriptor :: Sh ( k) => match k. as_inner ( ) {
586
+ ShInner :: Wsh ( k) => match k. as_inner ( ) {
587
+ WshInner :: SortedMulti ( k) => {
588
+ let dpk_v = k. clone ( ) . pks ;
589
+ let k = k. clone ( ) . k ;
590
+ Ok ( Self :: get_asset_combination ( k, & dpk_v) )
591
+ }
592
+ WshInner :: Ms ( k) => Ok ( k. get_all_assets ( ) ) ,
593
+ } ,
594
+ ShInner :: Wpkh ( k) => {
595
+ let mut asset = Assets :: new ( ) ;
596
+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
597
+ Ok ( vec ! [ asset] )
598
+ }
599
+ ShInner :: SortedMulti ( k) => {
600
+ let dpk_v = k. clone ( ) . pks ;
601
+ let k = k. clone ( ) . k ;
602
+ Ok ( Self :: get_asset_combination ( k, & dpk_v) )
603
+ }
604
+ ShInner :: Ms ( k) => Ok ( k. get_all_assets ( ) ) ,
605
+ } ,
606
+ Descriptor :: Wsh ( k) => match k. as_inner ( ) {
607
+ WshInner :: SortedMulti ( k) => {
608
+ let dpk_v = k. clone ( ) . pks ;
609
+ let k = k. clone ( ) . k ;
610
+ Ok ( Self :: get_asset_combination ( k, & dpk_v) )
611
+ }
612
+ WshInner :: Ms ( k) => {
613
+ println ! ( "{}" , k) ;
614
+ let a = k. get_all_assets ( ) ;
615
+ println ! ( "{:#?}" , a) ;
616
+ Ok ( a)
617
+ } ,
618
+ } ,
619
+ Descriptor :: Tr ( k) => {
620
+ let s = k. taptree ( ) . clone ( ) . unwrap ( ) ;
621
+ match s {
622
+ TapTree :: Tree ( ref left, ref right) => {
623
+ let mut a = left. get_all_assets ( ) ;
624
+ let b = right. get_all_assets ( ) ;
625
+ a. extend ( b) ;
626
+ Ok ( a)
627
+ }
628
+ TapTree :: Leaf ( k) => Ok ( k. get_all_assets ( ) ) ,
629
+ }
630
+ }
631
+ }
632
+ }
633
+
634
+ fn get_asset_combination ( k : usize , dpk_v : & Vec < DescriptorPublicKey > ) -> Vec < Assets > {
635
+ let mut all_assets: Vec < Assets > = Vec :: new ( ) ;
636
+ let current_assets = Assets :: new ( ) ;
637
+ Self :: combine_assets ( k, dpk_v, 0 , current_assets, & mut all_assets) ;
638
+ all_assets
639
+ }
640
+
641
+ fn combine_assets (
642
+ k : usize ,
643
+ dpk_v : & [ DescriptorPublicKey ] ,
644
+ index : usize ,
645
+ current_assets : Assets ,
646
+ all_assets : & mut Vec < Assets > ,
647
+ ) {
648
+ if k == 0 {
649
+ all_assets. push ( current_assets) ;
650
+ return ;
651
+ }
652
+ if index >= dpk_v. len ( ) {
653
+ return ;
654
+ }
655
+ Self :: combine_assets ( k, dpk_v, index + 1 , current_assets. clone ( ) , all_assets) ;
656
+ let mut new_asset = current_assets;
657
+ new_asset = new_asset. add ( dpk_v[ index] . clone ( ) ) ;
658
+ println ! ( "{:#?}" , new_asset) ;
659
+ Self :: combine_assets ( k - 1 , dpk_v, index + 1 , new_asset, all_assets)
660
+ }
661
+
662
+ }
663
+
569
664
impl < P , Q > TranslatePk < P , Q > for Descriptor < P >
570
665
where
571
666
P : MiniscriptKey ,
@@ -2092,4 +2187,85 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2092
2187
Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, uncomp_key) ) . unwrap_err ( ) ;
2093
2188
Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
2094
2189
}
2190
+
2191
+ #[ test]
2192
+ fn test_get_all_assets_bare ( ) {
2193
+ let descriptor = Descriptor :: < DescriptorPublicKey > :: from_str (
2194
+ "pk(0237b1c59ab055a8d3de40eaeb215c7b1922664b5ac049d849fb3346f81431e77f)" ,
2195
+ )
2196
+ . unwrap ( ) ;
2197
+
2198
+ // Getting the assets from the get_all_assets method
2199
+ let assets = descriptor. get_all_assets ( ) . unwrap ( ) ;
2200
+
2201
+ let mut expected_asset = Assets :: new ( ) ;
2202
+ expected_asset = expected_asset. add (
2203
+ DescriptorPublicKey :: from_str (
2204
+ "0237b1c59ab055a8d3de40eaeb215c7b1922664b5ac049d849fb3346f81431e77f" ,
2205
+ )
2206
+ . unwrap ( ) ,
2207
+ ) ;
2208
+ assert_eq ! ( assets, vec![ expected_asset] ) ;
2209
+ }
2210
+
2211
+ #[ test]
2212
+ fn test_get_all_assets_sh_sortedmulti ( ) {
2213
+ let keys = vec ! [
2214
+ "0360eabc52e04f70c89e944f379895cdff28fed60849afe7736815c091765afb3c" ,
2215
+ "03a80a24196e66ccf6bca6e6f96633bb629ec702acd76b074de10922b0cf41cc81" ,
2216
+ ] ;
2217
+
2218
+ let descriptor = Descriptor :: < DescriptorPublicKey > :: from_str ( & format ! (
2219
+ "sh(sortedmulti(1,{},{}))" ,
2220
+ keys[ 0 ] , keys[ 1 ]
2221
+ ) )
2222
+ . unwrap ( ) ;
2223
+
2224
+ let assets = descriptor. get_all_assets ( ) . unwrap ( ) ;
2225
+
2226
+ let mut expected_assets: Vec < Assets > = Vec :: new ( ) ;
2227
+
2228
+ let mut asset1 = Assets :: new ( ) ;
2229
+ asset1 = asset1. add (
2230
+ DescriptorPublicKey :: from_str (
2231
+ keys[ 0 ]
2232
+ )
2233
+ . unwrap ( ) ,
2234
+ ) ;
2235
+ expected_assets. push ( asset1) ;
2236
+
2237
+ let mut asset2 = Assets :: new ( ) ;
2238
+ asset2 = asset2. add (
2239
+ DescriptorPublicKey :: from_str (
2240
+ keys[ 1 ]
2241
+ )
2242
+ . unwrap ( ) ,
2243
+ ) ;
2244
+ expected_assets. push ( asset2) ;
2245
+
2246
+ for expected_asset in & expected_assets {
2247
+ assert ! ( assets. contains( expected_asset) ) ;
2248
+ }
2249
+ }
2250
+
2251
+ #[ test]
2252
+ fn test_get_all_assets_taproot ( ) {
2253
+ let x_only_key = bitcoin:: key:: XOnlyPublicKey :: from_str (
2254
+ "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
2255
+ )
2256
+ . unwrap ( ) ;
2257
+ let descriptor =
2258
+ Descriptor :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
2259
+ let assets = descriptor. get_all_assets ( ) . unwrap ( ) ;
2260
+ let mut expected_assets: Vec < Assets > = Vec :: new ( ) ;
2261
+ let mut asset_1 = Assets :: new ( ) ;
2262
+ asset_1 = asset_1. add (
2263
+ DescriptorPublicKey :: from_str (
2264
+ "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
2265
+ )
2266
+ . unwrap ( ) ,
2267
+ ) ;
2268
+ expected_assets. push ( asset_1) ;
2269
+ assert_eq ! ( assets, expected_assets) ;
2270
+ }
2095
2271
}
0 commit comments