Skip to content

Commit 95edba5

Browse files
Add full_derivation_paths on DescriptorPublicKey
1 parent a238673 commit 95edba5

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/descriptor/key.rs

+41
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,33 @@ impl DescriptorPublicKey {
592592
}
593593
}
594594

595+
/// Returns a vector containing the full derivation paths from the master key.
596+
/// The vector will contain just one element for single keys, and multiple elements
597+
/// for multipath extended keys.
598+
///
599+
/// For wildcard keys this will return the path up to the wildcard, so you
600+
/// can get full paths by appending one additional derivation step, according
601+
/// to the wildcard type (hardened or normal).
602+
pub fn full_derivation_paths(&self) -> Vec<bip32::DerivationPath> {
603+
match self {
604+
DescriptorPublicKey::MultiXPub(xpub) => {
605+
let origin_path = if let Some((_, ref path)) = xpub.origin {
606+
path.clone()
607+
} else {
608+
bip32::DerivationPath::from(vec![])
609+
};
610+
xpub.derivation_paths
611+
.paths()
612+
.into_iter()
613+
.map(|p| origin_path.extend(p))
614+
.collect()
615+
}
616+
_ => vec![self
617+
.full_derivation_path()
618+
.expect("Must be Some for non-multipath keys")],
619+
}
620+
}
621+
595622
/// Whether or not the key has a wildcard
596623
#[deprecated(note = "use has_wildcard instead")]
597624
pub fn is_deriveable(&self) -> bool {
@@ -1075,6 +1102,12 @@ impl DefiniteDescriptorKey {
10751102
self.0.full_derivation_path()
10761103
}
10771104

1105+
/// Full paths from the master key. The vector will contain just one path for single
1106+
/// keys, and multiple ones for multipath extended keys
1107+
pub fn full_derivation_paths(&self) -> Vec<bip32::DerivationPath> {
1108+
self.0.full_derivation_paths()
1109+
}
1110+
10781111
/// Reference to the underlying `DescriptorPublicKey`
10791112
pub fn as_descriptor_public_key(&self) -> &DescriptorPublicKey {
10801113
&self.0
@@ -1476,6 +1509,14 @@ mod test {
14761509
let desc_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/9478'/<0';1>/8h/*'").unwrap();
14771510
assert!(desc_key.full_derivation_path().is_none());
14781511
assert!(desc_key.is_multipath());
1512+
// But you can get all the derivation paths
1513+
assert_eq!(
1514+
desc_key.full_derivation_paths(),
1515+
vec![
1516+
bip32::DerivationPath::from_str("m/0'/1'/9478'/0'/8'").unwrap(),
1517+
bip32::DerivationPath::from_str("m/0'/1'/9478'/1/8'").unwrap(),
1518+
],
1519+
);
14791520
assert_eq!(desc_key.into_single_keys(), vec![DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/9478'/0'/8h/*'").unwrap(), DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/9478'/1/8h/*'").unwrap()]);
14801521

14811522
// All the same but with extended private keys instead of xpubs.

0 commit comments

Comments
 (0)