@@ -23,7 +23,7 @@ use sync::Arc;
2323
2424use self :: checksum:: verify_checksum;
2525use crate :: miniscript:: { satisfy, Legacy , Miniscript , Segwitv0 } ;
26- use crate :: plan:: { AssetProvider , Plan } ;
26+ use crate :: plan:: { AssetProvider , Plan , Assets } ;
2727use crate :: prelude:: * ;
2828use crate :: {
2929 expression, hash256, miniscript, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier ,
@@ -566,6 +566,101 @@ impl Descriptor<DefiniteDescriptorKey> {
566566 }
567567}
568568
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+
569664impl < P , Q > TranslatePk < P , Q > for Descriptor < P >
570665where
571666 P : MiniscriptKey ,
@@ -2092,4 +2187,85 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
20922187 Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, uncomp_key) ) . unwrap_err ( ) ;
20932188 Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
20942189 }
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+ }
20952271}
0 commit comments