Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #13 from Sajjon/keys
Browse files Browse the repository at this point in the history
Keys, FactorSources, FactorInstances
  • Loading branch information
Sajjon authored Dec 3, 2023
2 parents 903741b + 519d4bf commit e0da263
Show file tree
Hide file tree
Showing 88 changed files with 5,168 additions and 389 deletions.
7 changes: 1 addition & 6 deletions hierarchical_deterministic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ name = "hierarchical_deterministic"
version = "0.1.0"
edition = "2021"

[lib]
doctest = false

[dependencies]
serde = { version = "1.0.192", features = ["derive"] }
serde_json = { version = "1.0.108", features = ["preserve_order"] }
Expand All @@ -21,8 +18,6 @@ memoize = "0.4.1"
radix-engine-common = { git = "https://github.com/radixdlt/radixdlt-scrypto", rev = "038ddee8b0f57aa90e36375c69946c4eb634efeb", features = [
"serde",
] }
transaction = { git = "https://github.com/radixdlt/radixdlt-scrypto", rev = "038ddee8b0f57aa90e36375c69946c4eb634efeb", features = [
"serde",
] }
bip32 = "0.5.1" # slip10 crate does not support `secp256k1`.
hex = "0.4.3"
enum-as-inner = "0.6.0"
26 changes: 18 additions & 8 deletions hierarchical_deterministic/src/bip32/hd_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::str::FromStr;
use itertools::Itertools;
use serde::{de, Deserializer, Serialize, Serializer};
use slip10::path::BIP32Path;

use crate::hdpath_error::HDPathError;
use wallet_kit_common::error::hdpath_error::HDPathError;

use super::hd_path_component::{HDPathComponent, HDPathValue};

Expand Down Expand Up @@ -79,12 +78,11 @@ impl HDPath {
Ok(got)
}

pub(crate) fn try_parse_base(
s: &str,
pub(crate) fn try_parse_base_hdpath(
path: &HDPath,
depth_error: HDPathError,
) -> Result<(HDPath, Vec<HDPathComponent>), HDPathError> {
use HDPathError::*;
let path = HDPath::from_str(s).map_err(|_| HDPathError::InvalidBIP32Path(s.to_string()))?;
if path.depth() < 2 {
return Err(depth_error);
}
Expand All @@ -105,6 +103,14 @@ impl HDPath {
)?;
return Ok((path.clone(), components.clone()));
}

pub(crate) fn try_parse_base(
s: &str,
depth_error: HDPathError,
) -> Result<(HDPath, Vec<HDPathComponent>), HDPathError> {
let path = HDPath::from_str(s).map_err(|_| HDPathError::InvalidBIP32Path(s.to_string()))?;
return Self::try_parse_base_hdpath(&path, depth_error);
}
}

impl ToString for HDPath {
Expand All @@ -119,7 +125,8 @@ impl ToString for HDPath {
}

impl Serialize for HDPath {
/// Serializes this `AccountAddress` into its bech32 address string as JSON.
/// Serializes this `HDPath` into its bech32 address string as JSON.
#[cfg(not(tarpaulin_include))] // false negative
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
Expand All @@ -129,7 +136,8 @@ impl Serialize for HDPath {
}

impl<'de> serde::Deserialize<'de> for HDPath {
/// Tries to deserializes a JSON string as a bech32 address into an `AccountAddress`.
/// Tries to deserializes a JSON string as a bech32 address into an `HDPath`.
#[cfg(not(tarpaulin_include))] // false negative
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<HDPath, D::Error> {
let s = String::deserialize(d)?;
HDPath::from_str(&s).map_err(de::Error::custom)
Expand All @@ -140,7 +148,8 @@ impl<'de> serde::Deserialize<'de> for HDPath {
mod tests {
use serde_json::json;
use wallet_kit_common::json::{
assert_json_value_eq_after_roundtrip, assert_json_value_ne_after_roundtrip,
assert_json_value_eq_after_roundtrip, assert_json_value_fails,
assert_json_value_ne_after_roundtrip,
};

use super::HDPath;
Expand All @@ -151,5 +160,6 @@ mod tests {
let parsed = HDPath::from_str(str).unwrap();
assert_json_value_eq_after_roundtrip(&parsed, json!(str));
assert_json_value_ne_after_roundtrip(&parsed, json!("m/44H/33H"));
assert_json_value_fails::<HDPath>(json!("super invalid path"));
}
}
7 changes: 3 additions & 4 deletions hierarchical_deterministic/src/bip39/bip39_word/bip39_word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::cmp::Ordering;

use bip39::Language;
use memoize::memoize;
use wallet_kit_common::error::Error;
use wallet_kit_common::error::hdpath_error::HDPathError as Error;

use super::u11::U11;

Expand Down Expand Up @@ -53,10 +53,9 @@ fn index_of_word_in_bip39_wordlist_of_language(

#[cfg(test)]
mod tests {
use bip39::Language;
use wallet_kit_common::error::Error;

use super::BIP39Word;
use bip39::Language;
use wallet_kit_common::error::hdpath_error::HDPathError as Error;

#[test]
fn equality() {
Expand Down
2 changes: 1 addition & 1 deletion hierarchical_deterministic/src/bip39/bip39_word_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Display;

use serde_repr::{Deserialize_repr, Serialize_repr};
use strum::FromRepr;
use wallet_kit_common::error::Error;
use wallet_kit_common::error::hdpath_error::HDPathError as Error;

/// The number of words in the mnemonic of a DeviceFactorSource, according to the BIP39
/// standard, a multiple of 3, from 12 to 24 words. All "Babylon" `DeviceFactorSource`s
Expand Down
21 changes: 13 additions & 8 deletions hierarchical_deterministic/src/bip39/mnemonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::str::FromStr;
use bip39::Language;
use itertools::Itertools;
use serde::{de, Deserializer, Serialize, Serializer};
use wallet_kit_common::error::Error;
use wallet_kit_common::error::hdpath_error::HDPathError as Error;

use super::{bip39_word::bip39_word::BIP39Word, bip39_word_count::BIP39WordCount};

Expand Down Expand Up @@ -48,7 +48,7 @@ impl Mnemonic {
pub type Seed = [u8; 64];

impl Serialize for Mnemonic {
/// Serializes this `AccountAddress` into its bech32 address string as JSON.
/// Serializes this `Mnemonic` into a phrase, all words separated by a space.
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
Expand All @@ -58,22 +58,30 @@ impl Serialize for Mnemonic {
}

impl<'de> serde::Deserialize<'de> for Mnemonic {
/// Tries to deserializes a JSON string as a bech32 address into an `AccountAddress`.
/// Tries to deserializes a JSON string as a Mnemonic
#[cfg(not(tarpaulin_include))] // false negative
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let s = String::deserialize(d)?;
Mnemonic::from_phrase(&s).map_err(de::Error::custom)
}
}

impl TryInto<Mnemonic> for &str {
type Error = wallet_kit_common::error::Error;
type Error = wallet_kit_common::error::hdpath_error::HDPathError;

/// Tries to deserializes a bech32 address into an `AccountAddress`.
fn try_into(self) -> Result<Mnemonic, Self::Error> {
Mnemonic::from_phrase(self)
}
}

impl Mnemonic {
/// A placeholder used to facilitate unit tests.
pub fn placeholder() -> Self {
Self::from_phrase("bright club bacon dinner achieve pull grid save ramp cereal blush woman humble limb repeat video sudden possible story mask neutral prize goose mandate").expect("Valid mnemonic")
}
}

#[cfg(test)]
mod tests {
use bip39::Language;
Expand Down Expand Up @@ -111,10 +119,7 @@ mod tests {

#[test]
fn words() {
let mnemonic: Mnemonic =
"bright club bacon dinner achieve pull grid save ramp cereal blush woman humble limb repeat video sudden possible story mask neutral prize goose mandate"
.try_into()
.unwrap();
let mnemonic = Mnemonic::placeholder();
assert_eq!(mnemonic.words[0].word, "bright");
assert_eq!(mnemonic.words[1].word, "club");
assert_eq!(mnemonic.words[2].word, "bacon");
Expand Down
53 changes: 43 additions & 10 deletions hierarchical_deterministic/src/bip44/bip44_like_path.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
use serde::{de, Deserializer, Serialize, Serializer};
use wallet_kit_common::error::hdpath_error::HDPathError;

use crate::{
bip32::{
hd_path::HDPath,
hd_path_component::{HDPathComponent, HDPathValue},
},
derivation::{derivation::Derivation, derivation_path_scheme::DerivationPathScheme},
hdpath_error::HDPathError,
derivation::{
derivation::Derivation, derivation_path::DerivationPath,
derivation_path_scheme::DerivationPathScheme,
},
};

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct BIP44LikePath(HDPath);

impl BIP44LikePath {
pub fn from_str(s: &str) -> Result<Self, HDPathError> {
let (path, components) = HDPath::try_parse_base(s, HDPathError::InvalidDepthOfBIP44Path)?;
impl TryFrom<&HDPath> for BIP44LikePath {
type Error = HDPathError;

fn try_from(value: &HDPath) -> Result<Self, Self::Error> {
let (path, components) =
HDPath::try_parse_base_hdpath(value, HDPathError::InvalidDepthOfBIP44Path)?;
if path.depth() != 5 {
return Err(HDPathError::InvalidDepthOfBIP44Path);
}
Expand All @@ -33,6 +39,13 @@ impl BIP44LikePath {
}
return Ok(Self(path));
}
}

impl BIP44LikePath {
pub fn from_str(s: &str) -> Result<Self, HDPathError> {
let (path, _) = HDPath::try_parse_base(s, HDPathError::InvalidDepthOfBIP44Path)?;
return Self::try_from(&path);
}

fn with_account_and_index(account: HDPathValue, index: HDPathValue) -> Self {
let c0 = HDPathComponent::bip44_purpose(); // purpose
Expand All @@ -51,6 +64,9 @@ impl BIP44LikePath {
}

impl Derivation for BIP44LikePath {
fn derivation_path(&self) -> DerivationPath {
DerivationPath::BIP44Like(self.clone())
}
fn hd_path(&self) -> &HDPath {
&self.0
}
Expand All @@ -61,7 +77,7 @@ impl Derivation for BIP44LikePath {
}

impl Serialize for BIP44LikePath {
/// Serializes this `AccountAddress` into its bech32 address string as JSON.
/// Serializes this `BIP44LikePath` into JSON as a string on: "m/44H/1022H/0H/0/0H" format
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
Expand All @@ -71,7 +87,8 @@ impl Serialize for BIP44LikePath {
}

impl<'de> serde::Deserialize<'de> for BIP44LikePath {
/// Tries to deserializes a JSON string as a bech32 address into an `AccountAddress`.
/// Tries to deserializes a JSON string as a derivation path string into a `BIP44LikePath`
#[cfg(not(tarpaulin_include))] // false negative
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<BIP44LikePath, D::Error> {
let s = String::deserialize(d)?;
BIP44LikePath::from_str(&s).map_err(de::Error::custom)
Expand All @@ -86,14 +103,22 @@ impl TryInto<BIP44LikePath> for &str {
}
}

impl BIP44LikePath {
/// A placeholder used to facilitate unit tests.
pub fn placeholder() -> Self {
Self::from_str("m/44H/1022H/0H/0/0H").expect("Valid placeholder")
}
}

#[cfg(test)]
mod tests {
use serde_json::json;
use wallet_kit_common::json::{
assert_json_value_eq_after_roundtrip, assert_json_value_ne_after_roundtrip,
use wallet_kit_common::{
error::hdpath_error::HDPathError,
json::{assert_json_value_eq_after_roundtrip, assert_json_value_ne_after_roundtrip},
};

use crate::{derivation::derivation::Derivation, hdpath_error::HDPathError};
use crate::derivation::derivation::Derivation;

use super::BIP44LikePath;

Expand All @@ -104,6 +129,14 @@ mod tests {
assert_eq!(a.to_string(), str);
}

#[test]
fn placeholder() {
assert_eq!(
BIP44LikePath::placeholder().to_string(),
"m/44H/1022H/0H/0/0H"
);
}

#[test]
fn invalid_depth_1() {
assert_eq!(
Expand Down
2 changes: 2 additions & 0 deletions hierarchical_deterministic/src/cap26/cap26_entity_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
use strum::FromRepr;

use crate::bip32::hd_path_component::HDPathValue;
use enum_as_inner::EnumAsInner;

/// Account or Identity (used by Personas) part of a CAP26 derivation
/// path.
Expand All @@ -14,6 +15,7 @@ use crate::bip32::hd_path_component::HDPathValue;
Clone,
Copy,
Debug,
EnumAsInner,
PartialEq,
Eq,
Hash,
Expand Down
2 changes: 2 additions & 0 deletions hierarchical_deterministic/src/cap26/cap26_key_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
use strum::FromRepr;

use crate::bip32::hd_path_component::HDPathValue;
use enum_as_inner::EnumAsInner;

#[derive(
Serialize_repr,
Expand All @@ -13,6 +14,7 @@ use crate::bip32::hd_path_component::HDPathValue;
Copy,
Debug,
PartialEq,
EnumAsInner,
Eq,
Hash,
PartialOrd,
Expand Down
Loading

0 comments on commit e0da263

Please sign in to comment.