@@ -534,8 +534,12 @@ impl TaprootAvailableLeaves {
534
534
/// The Assets we can use to satisfy a particular spending path
535
535
#[ derive( Debug , Default ) ]
536
536
pub struct Assets {
537
- /// Keys the user can sign for, and how
538
- pub keys : HashSet < ( DescriptorPublicKey , CanSign ) > ,
537
+ /// Keys the user can sign for, and how. A pair `(fingerprint, derivation_path)` is
538
+ /// provided, meaning that the user can sign using the key with `fingerprint`,
539
+ /// derived with either `derivation_path` or a derivation path that extends `derivation_path`
540
+ /// by exactly one child number. For example, if the derivation path `m/0/1` is provided, the
541
+ /// user can sign with either `m/0/1` or `m/0/1/*`.
542
+ pub keys : HashSet < ( bip32:: KeySource , CanSign ) > ,
539
543
/// Set of available sha256 preimages
540
544
pub sha256_preimages : HashSet < sha256:: Hash > ,
541
545
/// Set of available hash256 preimages
@@ -550,16 +554,44 @@ pub struct Assets {
550
554
pub relative_timelock : Option < Sequence > ,
551
555
}
552
556
557
+ // Checks if the `pk` is a "direct child" of the `derivation_path` provided.
558
+ // Direct child means that the key derivation path is either the same as the
559
+ // `derivation_path`, or the same extened by exactly one child number.
560
+ // For example, `pk/0/1/2` is a direct child of `m/0/1` and of `m/0/1/2`,
561
+ // but not of `m/0`.
562
+ fn is_key_direct_child_of (
563
+ pk : & DefiniteDescriptorKey ,
564
+ derivation_path : & bip32:: DerivationPath ,
565
+ ) -> bool {
566
+ for pk_derivation_path in pk. full_derivation_paths ( ) {
567
+ if & pk_derivation_path == derivation_path {
568
+ return true ;
569
+ }
570
+
571
+ let definite_path_len = pk_derivation_path. len ( ) ;
572
+ if derivation_path. as_ref ( ) == & pk_derivation_path[ ..( definite_path_len - 1 ) ] {
573
+ return true ;
574
+ }
575
+ }
576
+
577
+ return false ;
578
+ }
579
+
553
580
impl Assets {
554
581
pub ( crate ) fn has_ecdsa_key ( & self , pk : & DefiniteDescriptorKey ) -> bool {
555
- self . keys
556
- . iter ( )
557
- . any ( |( key, can_sign) | can_sign. ecdsa && key. is_parent ( pk) . is_some ( ) )
582
+ self . keys . iter ( ) . any ( |( keysource, can_sign) | {
583
+ can_sign. ecdsa
584
+ && pk. master_fingerprint ( ) == keysource. 0
585
+ && is_key_direct_child_of ( pk, & keysource. 1 )
586
+ } )
558
587
}
559
588
560
589
pub ( crate ) fn has_taproot_internal_key ( & self , pk : & DefiniteDescriptorKey ) -> Option < usize > {
561
- self . keys . iter ( ) . find_map ( |( key, can_sign) | {
562
- if !can_sign. taproot . key_spend || !key. is_parent ( pk) . is_some ( ) {
590
+ self . keys . iter ( ) . find_map ( |( keysource, can_sign) | {
591
+ if !can_sign. taproot . key_spend
592
+ || pk. master_fingerprint ( ) != keysource. 0
593
+ || !is_key_direct_child_of ( pk, & keysource. 1 )
594
+ {
563
595
None
564
596
} else {
565
597
Some ( can_sign. taproot . sig_len ( ) )
@@ -572,9 +604,10 @@ impl Assets {
572
604
pk : & DefiniteDescriptorKey ,
573
605
tap_leaf_hash : & TapLeafHash ,
574
606
) -> Option < usize > {
575
- self . keys . iter ( ) . find_map ( |( key , can_sign) | {
607
+ self . keys . iter ( ) . find_map ( |( keysource , can_sign) | {
576
608
if !can_sign. taproot . script_spend . is_available ( tap_leaf_hash)
577
- || !key. is_parent ( pk) . is_some ( )
609
+ || pk. master_fingerprint ( ) != keysource. 0
610
+ || !is_key_direct_child_of ( pk, & keysource. 1 )
578
611
{
579
612
None
580
613
} else {
@@ -639,11 +672,14 @@ impl AssetProvider<DefiniteDescriptorKey> for Assets {
639
672
640
673
impl FromIterator < DescriptorPublicKey > for Assets {
641
674
fn from_iter < I : IntoIterator < Item = DescriptorPublicKey > > ( iter : I ) -> Self {
675
+ let mut keys = HashSet :: new ( ) ;
676
+ for pk in iter {
677
+ for deriv_path in pk. full_derivation_paths ( ) {
678
+ keys. insert ( ( ( pk. master_fingerprint ( ) , deriv_path) , CanSign :: default ( ) ) ) ;
679
+ }
680
+ }
642
681
Assets {
643
- keys : iter
644
- . into_iter ( )
645
- . map ( |pk| ( pk, CanSign :: default ( ) ) )
646
- . collect ( ) ,
682
+ keys,
647
683
..Default :: default ( )
648
684
}
649
685
}
0 commit comments