@@ -35,6 +35,7 @@ use sync::Arc;
3535
3636use self :: checksum:: verify_checksum;
3737use crate :: miniscript:: { Legacy , Miniscript , Segwitv0 } ;
38+ use crate :: plan:: { AssetProvider , Assets , IntoAssets , Plan } ;
3839use crate :: prelude:: * ;
3940use crate :: {
4041 expression, hash256, miniscript, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier ,
@@ -435,7 +436,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
435436 Descriptor :: Wpkh ( ref wpkh) => wpkh. get_satisfaction ( satisfier) ,
436437 Descriptor :: Wsh ( ref wsh) => wsh. get_satisfaction ( satisfier) ,
437438 Descriptor :: Sh ( ref sh) => sh. get_satisfaction ( satisfier) ,
438- Descriptor :: Tr ( ref tr) => tr. get_satisfaction ( satisfier) ,
439+ Descriptor :: Tr ( ref tr) => tr. get_satisfaction ( & satisfier) ,
439440 }
440441 }
441442
@@ -452,7 +453,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
452453 Descriptor :: Wpkh ( ref wpkh) => wpkh. get_satisfaction_mall ( satisfier) ,
453454 Descriptor :: Wsh ( ref wsh) => wsh. get_satisfaction_mall ( satisfier) ,
454455 Descriptor :: Sh ( ref sh) => sh. get_satisfaction_mall ( satisfier) ,
455- Descriptor :: Tr ( ref tr) => tr. get_satisfaction_mall ( satisfier) ,
456+ Descriptor :: Tr ( ref tr) => tr. get_satisfaction_mall ( & satisfier) ,
456457 }
457458 }
458459
@@ -470,6 +471,38 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
470471 }
471472}
472473
474+ impl Descriptor < DefiniteDescriptorKey > {
475+ /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
476+ pub fn get_plan < P > ( & self , provider : & P ) -> Option < Plan >
477+ where
478+ P : AssetProvider < DefiniteDescriptorKey > ,
479+ {
480+ match * self {
481+ Descriptor :: Bare ( ref bare) => bare. get_plan ( provider) ,
482+ Descriptor :: Pkh ( ref pkh) => pkh. get_plan ( provider) ,
483+ Descriptor :: Wpkh ( ref wpkh) => wpkh. get_plan ( provider) ,
484+ Descriptor :: Wsh ( ref wsh) => wsh. get_plan ( provider) ,
485+ Descriptor :: Sh ( ref sh) => sh. get_plan ( provider) ,
486+ Descriptor :: Tr ( ref tr) => tr. get_plan ( provider) ,
487+ }
488+ }
489+
490+ /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
491+ pub fn get_plan_mall < P > ( & self , provider : & P ) -> Option < Plan >
492+ where
493+ P : AssetProvider < DefiniteDescriptorKey > ,
494+ {
495+ match * self {
496+ Descriptor :: Bare ( ref bare) => bare. get_plan_mall ( provider) ,
497+ Descriptor :: Pkh ( ref pkh) => pkh. get_plan_mall ( provider) ,
498+ Descriptor :: Wpkh ( ref wpkh) => wpkh. get_plan_mall ( provider) ,
499+ Descriptor :: Wsh ( ref wsh) => wsh. get_plan_mall ( provider) ,
500+ Descriptor :: Sh ( ref sh) => sh. get_plan_mall ( provider) ,
501+ Descriptor :: Tr ( ref tr) => tr. get_plan_mall ( provider) ,
502+ }
503+ }
504+ }
505+
473506impl < P , Q > TranslatePk < P , Q > for Descriptor < P >
474507where
475508 P : MiniscriptKey ,
@@ -771,6 +804,46 @@ impl Descriptor<DefiniteDescriptorKey> {
771804 let derived = self . translate_pk ( & mut Derivator ( secp) ) ?;
772805 Ok ( derived)
773806 }
807+
808+ /// Returns the set of keys which are available in the [`KeyMap`] in form of [`Assets`]
809+ pub fn available_keys ( & self , key_map : & KeyMap ) -> Assets {
810+ let mut available_keys = vec ! [ ] ;
811+
812+ self . for_each_key ( |pk| {
813+ let found = match & pk. 0 {
814+ s @ DescriptorPublicKey :: Single ( _) => key_map. contains_key ( & s) ,
815+ DescriptorPublicKey :: XPub ( xkey) => {
816+ if key_map. contains_key ( & DescriptorPublicKey :: XPub ( xkey. clone ( ) ) ) {
817+ true
818+ } else if xkey. derivation_path . len ( ) > 0 {
819+ let unwind_wildcard = DescriptorXKey {
820+ origin : xkey. origin . clone ( ) ,
821+ xkey : xkey. xkey ,
822+ wildcard : Wildcard :: Unhardened ,
823+ derivation_path : xkey
824+ . derivation_path
825+ . into_iter ( )
826+ . take ( xkey. derivation_path . len ( ) - 1 )
827+ . cloned ( )
828+ . collect :: < Vec < _ > > ( )
829+ . into ( ) ,
830+ } ;
831+ key_map. contains_key ( & DescriptorPublicKey :: XPub ( unwind_wildcard) )
832+ } else {
833+ false
834+ }
835+ }
836+ } ;
837+
838+ if found {
839+ available_keys. push ( pk. clone ( ) ) ;
840+ }
841+
842+ true
843+ } ) ;
844+
845+ available_keys. into_assets ( )
846+ }
774847}
775848
776849impl_from_tree ! (
0 commit comments