diff --git a/src/config/blockchain.rs b/src/config/blockchain.rs index bb55bab..25637e2 100644 --- a/src/config/blockchain.rs +++ b/src/config/blockchain.rs @@ -2,8 +2,7 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; -use crate::ethereum::utils::{parse_caip2_chain_id, ChainIdError}; -use crate::utils::caip2::ChainId; +use crate::utils::caip2::{ChainId, ChainIdError}; fn default_chain_sync_step() -> u64 { 1000 } @@ -42,7 +41,7 @@ pub struct EthereumConfig { impl EthereumConfig { pub fn try_ethereum_chain_id(&self) -> Result { - parse_caip2_chain_id(&self.chain_id) + self.chain_id.ethereum_chain_id() } pub fn ethereum_chain_id(&self) -> u32 { diff --git a/src/ethereum/utils.rs b/src/ethereum/utils.rs index 478b73d..233713a 100644 --- a/src/ethereum/utils.rs +++ b/src/ethereum/utils.rs @@ -6,26 +6,6 @@ use web3::{ types::Address, }; -use crate::utils::caip2::ChainId; - -#[derive(thiserror::Error, Debug)] -pub enum ChainIdError { - #[error("unsupported chain")] - UnsupportedChain, - - #[error("invalid EIP155 chain ID")] - InvalidEip155ChainId(#[from] std::num::ParseIntError), -} - -/// Parses CAIP-2 chain ID -pub fn parse_caip2_chain_id(chain_id: &ChainId) -> Result { - if !chain_id.is_ethereum() { - return Err(ChainIdError::UnsupportedChain); - }; - let eth_chain_id: u32 = chain_id.reference.parse()?; - Ok(eth_chain_id) -} - pub fn key_to_ethereum_address(private_key: &SecretKey) -> Address { private_key.address() } @@ -42,22 +22,3 @@ pub fn parse_address(address: &str) -> Result { pub fn address_to_string(address: Address) -> String { format!("{:#x}", address) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_parse_caip2_chain_id() { - let chain_id: ChainId = "eip155:1".parse().unwrap(); - let result = parse_caip2_chain_id(&chain_id).unwrap(); - assert_eq!(result, 1); - } - - #[test] - fn test_parse_caip2_chain_id_unsupported() { - let chain_id: ChainId = "bip122:000000000019d6689c085ae165831e93".parse().unwrap(); - let error = parse_caip2_chain_id(&chain_id).err().unwrap(); - assert!(matches!(error, ChainIdError::UnsupportedChain)); - } -} diff --git a/src/utils/caip2.rs b/src/utils/caip2.rs index ee40fdb..348b863 100644 --- a/src/utils/caip2.rs +++ b/src/utils/caip2.rs @@ -45,18 +45,28 @@ impl ChainId { pub fn is_monero(&self) -> bool { self.namespace == CAIP2_MONERO_NAMESPACE } + + pub fn ethereum_chain_id(&self) -> Result { + if !self.is_ethereum() { + return Err(ChainIdError("namespace is not eip155")); + }; + let chain_id: u32 = self.reference.parse() + .map_err(|_| ChainIdError("invalid EIP-155 chain ID"))?; + Ok(chain_id) + } } #[derive(thiserror::Error, Debug)] -#[error("Chain ID parse error")] -pub struct ChainIdError; +#[error("{0}")] +pub struct ChainIdError(&'static str); impl FromStr for ChainId { type Err = ChainIdError; fn from_str(value: &str) -> Result { let caip2_re = Regex::new(CAIP2_RE).unwrap(); - let caps = caip2_re.captures(value).ok_or(ChainIdError)?; + let caps = caip2_re.captures(value) + .ok_or(ChainIdError("invalid chain ID"))?; let chain_id = Self { namespace: caps["namespace"].to_string(), reference: caps["reference"].to_string(), @@ -157,4 +167,18 @@ mod tests { let value = "eip155/1/abcde"; assert!(value.parse::().is_err()); } + + #[test] + fn test_ethereum_chain_id() { + let chain_id: ChainId = "eip155:1".parse().unwrap(); + let result = chain_id.ethereum_chain_id().unwrap(); + assert_eq!(result, 1); + } + + #[test] + fn test_ethereum_chain_id_not_ethereum() { + let chain_id: ChainId = "bip122:000000000019d6689c085ae165831e93".parse().unwrap(); + let error = chain_id.ethereum_chain_id().err().unwrap(); + assert!(matches!(error, ChainIdError("namespace is not eip155"))); + } }