Skip to main content

evm_sdk/
tool.rs

1/// address tool module
2pub mod address {
3    use ethers::types::Address;
4    use std::str::FromStr;
5
6    /// Convert string to Address
7    pub fn str_to_address(address_str: &str) -> Result<Address, String> {
8        Address::from_str(address_str.trim())
9            .map_err(|e| format!("Invalid Ethereum address: {}", e))
10    }
11
12    /// Convert Address to checksum format
13    pub fn to_checksum(address: &Address) -> String {
14        format!("{:?}", address)
15    }
16
17    /// Verify address format
18    pub fn verify_address_format(address: &str) -> bool {
19        str_to_address(address).is_ok()
20    }
21
22    /// Check if address is zero address
23    pub fn is_zero_address(address: &Address) -> bool {
24        *address == Address::zero()
25    }
26}
27
28/// number tool module
29pub mod num {
30    /// Format big numbers
31    pub fn format_big_num(value: f64) -> String {
32        if value >= 1_000_000_000.0 {
33            format!("{:.2}B", value / 1_000_000_000.0)
34        } else if value >= 1_000_000.0 {
35            format!("{:.2}M", value / 1_000_000.0)
36        } else if value >= 1_000.0 {
37            format!("{:.2}K", value / 1_000.0)
38        } else {
39            format!("{:.6}", value)
40        }
41    }
42
43    /// Convert U256 to f64 with decimals
44    pub fn u256_to_f64(value: ethers::types::U256, decimals: u8) -> f64 {
45        let divisor = ethers::types::U256::from(10).pow(ethers::types::U256::from(decimals));
46        let integer_part = value / divisor;
47        let fractional_part = value % divisor;
48
49        let integer = integer_part.as_u64() as f64;
50        let fractional = fractional_part.as_u64() as f64 / 10f64.powi(decimals as i32);
51
52        integer + fractional
53    }
54
55    /// Convert f64 to U256 with decimals
56    pub fn f64_to_u256(value: f64, decimals: u8) -> Result<ethers::types::U256, String> {
57        let scaled_value = (value * 10f64.powi(decimals as i32)).round();
58
59        if scaled_value.is_nan() || scaled_value.is_infinite() {
60            return Err("Invalid number value".to_string());
61        }
62
63        match ethers::types::U256::from_dec_str(&scaled_value.to_string()) {
64            Ok(val) => Ok(val),
65            Err(_) => Err("Number conversion failed".to_string()),
66        }
67    }
68}
69
70/// price tool module
71pub mod price {
72    use crate::EvmError;
73    use ethers::types::Address;
74    use std::collections::HashMap;
75
76    /// Price oracle trait for getting token prices
77    pub trait PriceOracle {
78        async fn get_price(&self, token_address: Address) -> Result<f64, EvmError>;
79        async fn get_prices(
80            &self,
81            token_addresses: Vec<Address>,
82        ) -> Result<HashMap<Address, f64>, EvmError>;
83    }
84
85    /// Simple price oracle implementation
86    pub struct SimplePriceOracle;
87
88    impl SimplePriceOracle {
89        pub fn new() -> Self {
90            Self
91        }
92    }
93
94    impl PriceOracle for SimplePriceOracle {
95        async fn get_price(&self, _token_address: Address) -> Result<f64, EvmError> {
96            // Implement price fetching logic here
97            // This is a placeholder implementation
98            Ok(1.0)
99        }
100
101        async fn get_prices(
102            &self,
103            token_addresses: Vec<Address>,
104        ) -> Result<HashMap<Address, f64>, EvmError> {
105            let mut prices = HashMap::new();
106            for address in token_addresses {
107                prices.insert(address, self.get_price(address).await?);
108            }
109            Ok(prices)
110        }
111    }
112}