From f9290438cdf2fe8aa5766f8901f9bd32d3e2bf56 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 26 Sep 2020 21:03:28 +0200 Subject: [PATCH 1/2] DerivationPath improvements Adding IntoDerivationPath trait DerivationPath is_master function DerivationPath constructor for empty path + Default impl --- src/util/bip32.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/util/bip32.rs b/src/util/bip32.rs index 964e79e1..2d8db57f 100644 --- a/src/util/bip32.rs +++ b/src/util/bip32.rs @@ -210,12 +210,31 @@ impl serde::Serialize for ChildNumber { } } +/// Trait that allows possibly failable conversion from a type into a +/// derivation path +pub trait IntoDerivationPath { + /// Convers a given type into a [`DerivationPath`] with possible error + fn into_derivation_path(self) -> Result; +} + /// A BIP-32 derivation path. #[derive(Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct DerivationPath(Vec); impl_index_newtype!(DerivationPath, ChildNumber); serde_string_impl!(DerivationPath, "a BIP-32 derivation path"); +impl Default for DerivationPath { + fn default() -> DerivationPath { + DerivationPath::master() + } +} + +impl IntoDerivationPath for T where T: Into { + fn into_derivation_path(self) -> Result { + Ok(self.into()) + } +} + impl From> for DerivationPath { fn from(numbers: Vec) -> Self { DerivationPath(numbers) @@ -304,6 +323,17 @@ impl DerivationPath { self.0.len() } + /// Returns derivation path for a master key (i.e. empty derivation path) + pub fn master() -> DerivationPath { + DerivationPath(vec![]) + } + + /// Returns whether derivation path represents master key (i.e. it's length + /// is empty). True for `m` path. + pub fn is_master(&self) -> bool { + self.0.is_empty() + } + /// Create a new [DerivationPath] that is a child of this one. pub fn child(&self, cn: ChildNumber) -> DerivationPath { let mut path = self.0.clone(); @@ -763,6 +793,8 @@ mod tests { assert_eq!(DerivationPath::from_str("m/0h/0x"), Err(Error::InvalidChildNumberFormat)); assert_eq!(DerivationPath::from_str("m/2147483648"), Err(Error::InvalidChildNumber(2147483648))); + assert_eq!(DerivationPath::master(), DerivationPath::from_str("m").unwrap()); + assert_eq!(DerivationPath::master(), DerivationPath::default()); assert_eq!(DerivationPath::from_str("m"), Ok(vec![].into())); assert_eq!( DerivationPath::from_str("m/0'"), From 44ffddab8c4f873d566b35953ce6bf2dbb0e07bf Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 14 Oct 2020 16:04:18 +0200 Subject: [PATCH 2/2] Impl IntoDerivationPath for string types --- src/util/bip32.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/util/bip32.rs b/src/util/bip32.rs index 2d8db57f..c28d337a 100644 --- a/src/util/bip32.rs +++ b/src/util/bip32.rs @@ -235,6 +235,18 @@ impl IntoDerivationPath for T where T: Into { } } +impl IntoDerivationPath for String { + fn into_derivation_path(self) -> Result { + self.parse() + } +} + +impl<'a> IntoDerivationPath for &'a str { + fn into_derivation_path(self) -> Result { + self.parse() + } +} + impl From> for DerivationPath { fn from(numbers: Vec) -> Self { DerivationPath(numbers) @@ -831,6 +843,9 @@ mod tests { ChildNumber::from_normal_idx(1000000000).unwrap(), ].into()) ); + let s = "m/0'/50/3'/5/545456"; + assert_eq!(DerivationPath::from_str(s), s.into_derivation_path()); + assert_eq!(DerivationPath::from_str(s), s.to_string().into_derivation_path()); } #[test]