Skip to content

Commit abb138f

Browse files
authored
Merge pull request #98 from Foundation-Devices/refine-multisig-keymaps
cleaned up multisig keymap generation
2 parents f2de24b + 64369d4 commit abb138f

File tree

1 file changed

+36
-93
lines changed

1 file changed

+36
-93
lines changed

src/config.rs

Lines changed: 36 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ use crate::utils::get_address_type;
1616
use bdk_wallet::KeychainKind;
1717
use bdk_wallet::WalletPersister;
1818
use bdk_wallet::bitcoin::bip32::{self, ChildNumber, DerivationPath, Fingerprint, Xpriv, Xpub};
19-
use bdk_wallet::bitcoin::secp256k1::Secp256k1;
19+
use bdk_wallet::bitcoin::secp256k1::{Secp256k1, Signing};
2020
use bdk_wallet::bitcoin::{self, Network};
2121
use bdk_wallet::descriptor::Descriptor as BdkDescriptor;
2222
use bdk_wallet::miniscript::{
2323
ForEachKey,
2424
descriptor::{
25-
DerivPaths, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
26-
ShInner, SortedMultiVec, Wildcard, WshInner,
25+
DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, ShInner, SortedMultiVec,
26+
Wildcard, WshInner,
2727
},
2828
};
2929
use regex::Regex;
@@ -435,29 +435,6 @@ impl MultiSigDetails {
435435
}
436436
}
437437

438-
fn signer_to_multi_xpub(&self, signer: &MultiSigSigner) -> Option<DescriptorPublicKey> {
439-
let (fingerprint, derivation_path, pubkey) = match (
440-
signer.get_fingerprint(),
441-
signer.get_derivation(),
442-
signer.get_pubkey(),
443-
) {
444-
(f, Ok(d), Ok(p)) => (f, d, p),
445-
_ => return None,
446-
};
447-
let master_path = DerivationPath::master();
448-
let derivation_paths = DerivPaths::new(vec![
449-
master_path.child(ChildNumber::Normal { index: 0 }),
450-
master_path.child(ChildNumber::Normal { index: 1 }),
451-
])?;
452-
let descriptor_x_key: DescriptorMultiXKey<Xpub> = DescriptorMultiXKey {
453-
origin: Some((fingerprint, derivation_path)),
454-
xkey: pubkey,
455-
derivation_paths,
456-
wildcard: Wildcard::Unhardened,
457-
};
458-
Some(DescriptorPublicKey::MultiXPub(descriptor_x_key))
459-
}
460-
461438
fn signer_to_xpub(
462439
&self,
463440
signer: &MultiSigSigner,
@@ -483,9 +460,10 @@ impl MultiSigDetails {
483460
Some(DescriptorPublicKey::XPub(descriptor_x_key))
484461
}
485462

486-
pub fn to_descriptor(
463+
pub fn to_descriptor<C: Signing>(
487464
&self,
488-
keychain: Option<KeychainKind>,
465+
keychain: KeychainKind,
466+
secp: &Secp256k1<C>,
489467
master_key: Option<&MasterKey>,
490468
) -> Result<
491469
(
@@ -497,10 +475,7 @@ impl MultiSigDetails {
497475
let signers = self
498476
.signers
499477
.iter()
500-
.filter_map(|s| match keychain {
501-
Some(k) => self.signer_to_xpub(s, k),
502-
None => self.signer_to_multi_xpub(s),
503-
})
478+
.filter_map(|s| self.signer_to_xpub(s, keychain))
504479
.collect::<Vec<DescriptorPublicKey>>();
505480

506481
let descriptor = match self.format {
@@ -521,58 +496,31 @@ impl MultiSigDetails {
521496
let mut keymap = BTreeMap::<DescriptorPublicKey, DescriptorSecretKey>::new();
522497

523498
if let Some(master) = master_key {
524-
let secp = Secp256k1::new();
525499
let fp = master.fingerprint;
526500
let master_xprv = Xpriv::new_master(self.network_kind, &master.key.0)?;
527501

528502
descriptor.for_each_key(|pubkey| {
529-
match pubkey {
530-
DescriptorPublicKey::XPub(xkey) => {
531-
if let Some(origin) = &xkey.origin && origin.0 == fp && let Ok(derived_xprv) = master_xprv.derive_priv(&secp, &origin.1)
532-
{
533-
let derived_xpub = Xpub::from_priv(&secp, &derived_xprv);
534-
let desc_xkey = DescriptorXKey {
535-
origin: Some(origin.clone()),
536-
xkey: derived_xprv,
537-
derivation_path: xkey.derivation_path.clone(),
538-
wildcard: xkey.wildcard,
539-
};
540-
keymap.insert(
541-
DescriptorPublicKey::XPub(DescriptorXKey {
542-
origin: Some(origin.clone()),
543-
xkey: derived_xpub,
544-
derivation_path: xkey.derivation_path.clone(),
545-
wildcard: xkey.wildcard,
546-
}),
547-
DescriptorSecretKey::XPrv(desc_xkey),
548-
);
549-
}
550-
}
551-
DescriptorPublicKey::MultiXPub(xkey) => {
552-
if let Some(origin) = &xkey.origin && origin.0 == fp && let Ok(derived_xprv) = master_xprv.derive_priv(&secp, &origin.1)
553-
{
554-
let derived_xpub = Xpub::from_priv(&secp, &derived_xprv);
555-
// For MultiXPub, we need to create individual XPub entries for each derivation path
556-
for derivation_path in xkey.derivation_paths.paths() {
557-
let desc_xkey = DescriptorXKey {
558-
origin: Some(origin.clone()),
559-
xkey: derived_xprv,
560-
derivation_path: derivation_path.clone(),
561-
wildcard: xkey.wildcard,
562-
};
563-
keymap.insert(
564-
DescriptorPublicKey::XPub(DescriptorXKey {
565-
origin: Some(origin.clone()),
566-
xkey: derived_xpub,
567-
derivation_path: derivation_path.clone(),
568-
wildcard: xkey.wildcard,
569-
}),
570-
DescriptorSecretKey::XPrv(desc_xkey),
571-
);
572-
}
573-
}
574-
}
575-
_ => {}
503+
if let DescriptorPublicKey::XPub(xkey) = pubkey
504+
&& let Some(origin) = &xkey.origin
505+
&& origin.0 == fp
506+
&& let Ok(derived_xprv) = master_xprv.derive_priv(secp, &origin.1)
507+
{
508+
let derived_xpub = Xpub::from_priv(secp, &derived_xprv);
509+
let desc_xkey = DescriptorXKey {
510+
origin: Some(origin.clone()),
511+
xkey: derived_xprv,
512+
derivation_path: xkey.derivation_path.clone(),
513+
wildcard: xkey.wildcard,
514+
};
515+
keymap.insert(
516+
DescriptorPublicKey::XPub(DescriptorXKey {
517+
origin: Some(origin.clone()),
518+
xkey: derived_xpub,
519+
derivation_path: xkey.derivation_path.clone(),
520+
wildcard: xkey.wildcard,
521+
}),
522+
DescriptorSecretKey::XPrv(desc_xkey),
523+
);
576524
}
577525
true
578526
});
@@ -591,14 +539,15 @@ impl MultiSigDetails {
591539
})
592540
}
593541

594-
pub fn get_descriptors(
542+
pub fn get_descriptors<C: Signing>(
595543
&self,
544+
secp: &Secp256k1<C>,
596545
master_key: Option<&MasterKey>,
597546
) -> anyhow::Result<Vec<Descriptors>> {
598547
let (external_desc, external_keymap) =
599-
self.to_descriptor(Some(KeychainKind::External), master_key)?;
548+
self.to_descriptor(KeychainKind::External, secp, master_key)?;
600549
let (internal_desc, internal_keymap) =
601-
self.to_descriptor(Some(KeychainKind::Internal), master_key)?;
550+
self.to_descriptor(KeychainKind::Internal, secp, master_key)?;
602551
let descriptor_type = external_desc.desc_type();
603552

604553
Ok(vec![Descriptors {
@@ -1064,15 +1013,9 @@ AB88DE89: tpubDFUc8ddWCzA8kC195Zn6UitBcBGXbPbtjktU2dk2Deprnf6sR15GAyHLQKUjAPa3gq
10641013
assert_eq!(expected, multisig);
10651014
assert_eq!(String::from("Multisig 2-of-2 Test"), name);
10661015

1067-
let descriptor = multisig.to_descriptor(None, None).unwrap().0;
1068-
let expected_descriptor = String::from(
1069-
"wsh(sortedmulti(2,[ab88de89/48'/1'/0'/2']tpubDFUc8ddWCzA8kC195Zn6UitBcBGXbPbtjktU2dk2Deprnf6sR15GAyHLQKUjAPa3gqD74g7Eea3NSqkb9FfYRZzEm2MTbCtTDZAKSHezJwb/<0;1>/*,[662a42e4/48'/1'/0'/2']tpubDFGqX4Ge633XixPNo4uF5h6sPkv32bwJrknDmmPGMq8Tn3Pu9QgWfk5hUiDe7gvv2eaFeaHXgjiZwKvnP3AhusoaWBK3qTv8cznyHxxGoSF/<0;1>/*))#wn2wpcz6",
1070-
);
1071-
1072-
assert_eq!(descriptor.to_string(), expected_descriptor);
1073-
1016+
let secp = Secp256k1::new();
10741017
let receive_descriptor = multisig
1075-
.to_descriptor(Some(KeychainKind::External), None)
1018+
.to_descriptor(KeychainKind::External, &secp, None)
10761019
.unwrap()
10771020
.0;
10781021
let expected_receive_descriptor = String::from(
@@ -1082,7 +1025,7 @@ AB88DE89: tpubDFUc8ddWCzA8kC195Zn6UitBcBGXbPbtjktU2dk2Deprnf6sR15GAyHLQKUjAPa3gq
10821025
assert_eq!(receive_descriptor.to_string(), expected_receive_descriptor);
10831026

10841027
let change_descriptor = multisig
1085-
.to_descriptor(Some(KeychainKind::Internal), None)
1028+
.to_descriptor(KeychainKind::Internal, &secp, None)
10861029
.unwrap()
10871030
.0;
10881031
let expected_change_descriptor = String::from(
@@ -1091,7 +1034,7 @@ AB88DE89: tpubDFUc8ddWCzA8kC195Zn6UitBcBGXbPbtjktU2dk2Deprnf6sR15GAyHLQKUjAPa3gq
10911034

10921035
assert_eq!(change_descriptor.to_string(), expected_change_descriptor);
10931036

1094-
let descriptors = multisig.get_descriptors(None).unwrap();
1037+
let descriptors = multisig.get_descriptors(&secp, None).unwrap();
10951038

10961039
let descriptor = &descriptors[0];
10971040
assert_eq!(String::from("48_2"), descriptor.bip);

0 commit comments

Comments
 (0)