pragma_common/web3/
chain.rs

1use std::str::FromStr;
2
3#[derive(Debug, Copy, Hash, Eq, Clone, PartialEq)]
4#[cfg_attr(
5    feature = "serde",
6    derive(serde::Serialize, serde::Deserialize),
7    serde(rename_all = "lowercase")
8)]
9#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
10pub enum Chain {
11    Starknet,
12    Solana,
13    Sui,
14    Aptos,
15    // Evm chains
16    Ethereum,
17    Base,
18    Arbitrum,
19    Optimism,
20    ZkSync,
21    Polygon,
22    Bnb,
23    Avalanche,
24    Gnosis,
25    Worldchain,
26}
27
28impl Chain {
29    #[must_use]
30    pub const fn id(&self) -> Option<u64> {
31        let chain_id = match self {
32            Self::Ethereum => 1,
33            Self::Optimism => 10,
34            Self::Polygon => 137,
35            Self::ZkSync => 324,
36            Self::Base => 8453,
37            Self::Arbitrum => 42161,
38            Self::Bnb => 56,
39            Self::Avalanche => 43114,
40            Self::Gnosis => 100,
41            Self::Worldchain => 480,
42            _ => {
43                return None;
44            }
45        };
46
47        Some(chain_id)
48    }
49
50    pub const fn is_evm(&self) -> bool {
51        matches!(
52            self,
53            Self::Ethereum
54                | Self::Optimism
55                | Self::Polygon
56                | Self::ZkSync
57                | Self::Base
58                | Self::Arbitrum
59                | Self::Bnb
60                | Self::Avalanche
61                | Self::Gnosis
62                | Self::Worldchain
63        )
64    }
65
66    pub fn from_id(id: u64) -> Result<Self, ChainError> {
67        match id {
68            1 => Ok(Self::Ethereum),
69            10 => Ok(Self::Optimism),
70            137 => Ok(Self::Polygon),
71            324 => Ok(Self::ZkSync),
72            8453 => Ok(Self::Base),
73            42161 => Ok(Self::Arbitrum),
74            56 => Ok(Self::Bnb),
75            43114 => Ok(Self::Avalanche),
76            100 => Ok(Self::Gnosis),
77            480 => Ok(Self::Worldchain),
78            _ => Err(ChainError::UnknownChainId(id.to_string())),
79        }
80    }
81}
82
83impl std::fmt::Display for Chain {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        write!(f, "{self:?}")
86    }
87}
88
89impl FromStr for Chain {
90    type Err = ChainError;
91
92    fn from_str(s: &str) -> Result<Self, Self::Err> {
93        match s.to_lowercase().as_str() {
94            "starknet" => Ok(Self::Starknet),
95            "solana" => Ok(Self::Solana),
96            "sui" => Ok(Self::Sui),
97            "aptos" => Ok(Self::Aptos),
98            "ethereum" => Ok(Self::Ethereum),
99            "base" => Ok(Self::Base),
100            "arbitrum" => Ok(Self::Arbitrum),
101            "optimism" => Ok(Self::Optimism),
102            "zksync" => Ok(Self::ZkSync),
103            "polygon" => Ok(Self::Polygon),
104            "bnb" => Ok(Self::Bnb),
105            "avalanche" => Ok(Self::Avalanche),
106            "gnosis" => Ok(Self::Gnosis),
107            "worldchain" => Ok(Self::Worldchain),
108            _ => Err(ChainError::UnknownChainId(s.to_string())),
109        }
110    }
111}
112
113#[derive(Debug, thiserror::Error)]
114pub enum ChainError {
115    #[error("Unknown chain id: {0}")]
116    UnknownChainId(String),
117}