From cd7590ff52c2f8dd6d00aac4b883ec9731e5cd0c Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Fri, 8 Dec 2023 15:34:37 +0500 Subject: [PATCH 1/7] fromStr for private and public keys --- src/model/account/private_key.rs | 21 +++++++++++++++++++++ src/model/account/public_key.rs | 19 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/model/account/private_key.rs b/src/model/account/private_key.rs index 126f92a..97746bc 100644 --- a/src/model/account/private_key.rs +++ b/src/model/account/private_key.rs @@ -12,6 +12,16 @@ pub struct PrivateKey { public_key: PublicKey, } +impl std::str::FromStr for PrivateKey { + type Err = Error; + + fn from_str(base58string: &str) -> Result { + let bytes = Base58::decode(base58string)?; + let bytes_array: [u8; 32] = bytes.try_into()?; + PrivateKey::from_bytes(bytes_array) + } +} + impl PrivateKey { pub fn from_seed(seed_phrase: &str, nonce: u8) -> Result { let hash_seed = Crypto::get_account_seed(seed_phrase.as_bytes(), nonce)?; @@ -79,6 +89,8 @@ impl PrivateKey { #[cfg(test)] mod tests { + use std::str::FromStr; + use crate::error::Error::InvalidBytesLength; use crate::error::Result; use crate::model::account::PrivateKey; @@ -149,4 +161,13 @@ mod tests { assert_eq!(private_key.bytes(), [0_u8; 32]); Ok(()) } + + #[test] + fn test_private_key_std_from_str() -> Result<()> { + let seed_phrase = "blame vacant regret company chase trip grant funny brisk innocent"; + let private_key_from_seed = PrivateKey::from_seed(seed_phrase, 0)?; + let private_key_from_str = PrivateKey::from_str(&private_key_from_seed.encoded())?; + assert_eq!(private_key_from_seed.bytes(), private_key_from_str.bytes()); + Ok(()) + } } diff --git a/src/model/account/public_key.rs b/src/model/account/public_key.rs index 899bd74..a4ba707 100644 --- a/src/model/account/public_key.rs +++ b/src/model/account/public_key.rs @@ -16,6 +16,15 @@ impl fmt::Debug for PublicKey { } } +impl std::str::FromStr for PublicKey { + type Err = Error; + + fn from_str(base58string: &str) -> Result { + let bytes = Base58::decode(base58string)?; + Ok(PublicKey { bytes }) + } +} + impl PublicKey { pub fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() != 32 { @@ -71,6 +80,8 @@ impl TryFrom for PublicKey { #[cfg(test)] mod tests { + use std::str::FromStr; + use crate::error::Error::InvalidBytesLength; use crate::error::Result; use crate::model::account::{PrivateKey, PublicKey}; @@ -136,6 +147,14 @@ mod tests { Ok(()) } + #[test] + fn test_public_key_std_from_str() -> Result<()> { + let expected_string = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB".to_owned(); + let public_key = PublicKey::from_str(&expected_string)?; + assert_eq!(expected_string, public_key.encoded()); + Ok(()) + } + #[test] fn test_byte_string_for_public_key() -> Result<()> { let public_key: PublicKey = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB".try_into()?; From eafacc9b2fc584f863b07c5b9fa8d197b4f6def6 Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Fri, 8 Dec 2023 15:51:01 +0500 Subject: [PATCH 2/7] fix private key from str --- src/error.rs | 2 ++ src/model/account/private_key.rs | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index d8ac455..2fa5201 100644 --- a/src/error.rs +++ b/src/error.rs @@ -43,6 +43,8 @@ pub enum Error { HexError(#[from] FromHexError), #[error("unsupported operation: {0}")] UnsupportedOperation(String), + #[error("failed to convert vector to array")] + PrivateKeyConversionError, #[error("alias must be {min_length:?} to {max_length:?} length of {alphabet:?} and may have a prefix \"{max_length:?}{chain_id:?}:\"")] InvalidAliasName { min_length: u8, diff --git a/src/model/account/private_key.rs b/src/model/account/private_key.rs index 97746bc..33fca18 100644 --- a/src/model/account/private_key.rs +++ b/src/model/account/private_key.rs @@ -17,7 +17,10 @@ impl std::str::FromStr for PrivateKey { fn from_str(base58string: &str) -> Result { let bytes = Base58::decode(base58string)?; - let bytes_array: [u8; 32] = bytes.try_into()?; + let bytes_array: [u8; 32] = match bytes.try_into() { + Ok(v) => v, + Err(_) => return Err(Error::PrivateKeyConversionError), + }; PrivateKey::from_bytes(bytes_array) } } From d969d25e4583fb56d554ffbd4eccd4b480affccf Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Fri, 8 Dec 2023 18:18:23 +0500 Subject: [PATCH 3/7] from_str for address --- src/model/account/address.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/model/account/address.rs b/src/model/account/address.rs index e284ef3..39f4e94 100644 --- a/src/model/account/address.rs +++ b/src/model/account/address.rs @@ -17,6 +17,16 @@ impl fmt::Debug for Address { } } +impl std::str::FromStr for Address { + type Err = Error; + + fn from_str(base58string: &str) -> Result
{ + Ok(Address { + bytes: Base58::decode(base58string)?, + }) + } +} + impl Address { pub fn from_public_key(chain_id: u8, public_key: &PublicKey) -> Result
{ Ok(Address { @@ -72,6 +82,7 @@ mod tests { use crate::model::{ByteString, ChainId}; use serde_json::Value; use std::borrow::Borrow; + use std::str::FromStr; #[test] fn test_address_from_public_key() { @@ -97,6 +108,13 @@ mod tests { assert_eq!(expected_address, address.encoded()) } + #[test] + fn test_address_std_from_str() { + let expected_address = "3MtQQX9NwYH5URGGcS2e6ptEgV7wTFesaRW"; + let address = Address::from_str(expected_address).expect("failed to get address from string"); + assert_eq!(expected_address, address.encoded()) + } + #[test] fn test_address_from_json() -> Result<()> { let expected_address = "3MtQQX9NwYH5URGGcS2e6ptEgV7wTFesaRW"; From 5abb9db690e825748e2dc2f3262372064d8fdf9b Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Mon, 11 Dec 2023 17:16:07 +0500 Subject: [PATCH 4/7] fmt --- src/model/account/address.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/model/account/address.rs b/src/model/account/address.rs index 39f4e94..ca19579 100644 --- a/src/model/account/address.rs +++ b/src/model/account/address.rs @@ -111,7 +111,8 @@ mod tests { #[test] fn test_address_std_from_str() { let expected_address = "3MtQQX9NwYH5URGGcS2e6ptEgV7wTFesaRW"; - let address = Address::from_str(expected_address).expect("failed to get address from string"); + let address = + Address::from_str(expected_address).expect("failed to get address from string"); assert_eq!(expected_address, address.encoded()) } From 87cea8bcf7fe63ef01f56d29c4b1bf91d1eb2074 Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Mon, 11 Dec 2023 17:45:35 +0500 Subject: [PATCH 5/7] VectorToArrayConversionError --- src/error.rs | 4 ++-- src/model/account/private_key.rs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/error.rs b/src/error.rs index 2fa5201..0db954b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -43,8 +43,8 @@ pub enum Error { HexError(#[from] FromHexError), #[error("unsupported operation: {0}")] UnsupportedOperation(String), - #[error("failed to convert vector to array")] - PrivateKeyConversionError, + #[error("failed to convert vector {0:?} to array")] + VectorToArrayConversionError(Vec), #[error("alias must be {min_length:?} to {max_length:?} length of {alphabet:?} and may have a prefix \"{max_length:?}{chain_id:?}:\"")] InvalidAliasName { min_length: u8, diff --git a/src/model/account/private_key.rs b/src/model/account/private_key.rs index 33fca18..da2a6d7 100644 --- a/src/model/account/private_key.rs +++ b/src/model/account/private_key.rs @@ -17,10 +17,7 @@ impl std::str::FromStr for PrivateKey { fn from_str(base58string: &str) -> Result { let bytes = Base58::decode(base58string)?; - let bytes_array: [u8; 32] = match bytes.try_into() { - Ok(v) => v, - Err(_) => return Err(Error::PrivateKeyConversionError), - }; + let bytes_array: [u8; 32] = bytes.try_into().map_err(|e| Error::VectorToArrayConversionError(e))?; PrivateKey::from_bytes(bytes_array) } } From befcf9f44661ffdd4950da6b5ea00734acd8c698 Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Mon, 11 Dec 2023 17:47:31 +0500 Subject: [PATCH 6/7] fmt --- src/model/account/private_key.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/model/account/private_key.rs b/src/model/account/private_key.rs index da2a6d7..707cebd 100644 --- a/src/model/account/private_key.rs +++ b/src/model/account/private_key.rs @@ -17,7 +17,9 @@ impl std::str::FromStr for PrivateKey { fn from_str(base58string: &str) -> Result { let bytes = Base58::decode(base58string)?; - let bytes_array: [u8; 32] = bytes.try_into().map_err(|e| Error::VectorToArrayConversionError(e))?; + let bytes_array: [u8; 32] = bytes + .try_into() + .map_err(|e| Error::VectorToArrayConversionError(e))?; PrivateKey::from_bytes(bytes_array) } } From b06d42c283267df0349623ac98a2875c86732675 Mon Sep 17 00:00:00 2001 From: Artem Badrtdinov Date: Mon, 11 Dec 2023 18:03:41 +0500 Subject: [PATCH 7/7] fix PrivateKey from_str --- src/model/account/private_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/account/private_key.rs b/src/model/account/private_key.rs index 707cebd..ea3cd72 100644 --- a/src/model/account/private_key.rs +++ b/src/model/account/private_key.rs @@ -19,7 +19,7 @@ impl std::str::FromStr for PrivateKey { let bytes = Base58::decode(base58string)?; let bytes_array: [u8; 32] = bytes .try_into() - .map_err(|e| Error::VectorToArrayConversionError(e))?; + .map_err(Error::VectorToArrayConversionError)?; PrivateKey::from_bytes(bytes_array) } }