chainlist_rs/
eip.rs

1//! EIP-compatible structures and conversions.
2
3use crate::schema::{ChainRecord, NativeCurrency};
4use crate::Chain;
5use serde::{Deserialize, Serialize};
6
7/// EIP-3085 wallet addChain parameters.
8#[derive(Clone, Debug, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Eip3085Params {
11    /// Hex string chain ID, e.g. "0x1".
12    pub chain_id: String,
13    pub chain_name: String,
14    pub native_currency: NativeCurrency,
15    pub rpc_urls: Vec<String>,
16    #[serde(default, skip_serializing_if = "Vec::is_empty")]
17    pub block_explorer_urls: Vec<String>,
18    #[serde(default, skip_serializing_if = "Vec::is_empty")]
19    pub icon_urls: Vec<String>,
20}
21
22impl Eip3085Params {
23    fn from_parts(
24        chain_id: u64,
25        chain_name: &str,
26        native_currency: &NativeCurrency,
27        rpc_urls: &[impl AsRef<str>],
28        explorer_urls: &[String],
29        icon_urls: &[String],
30    ) -> Self {
31        Self {
32            chain_id: format!("0x{:x}", chain_id),
33            chain_name: chain_name.to_string(),
34            native_currency: native_currency.clone(),
35            rpc_urls: rpc_urls.iter().map(|s| s.as_ref().to_string()).collect(),
36            block_explorer_urls: explorer_urls.to_vec(),
37            icon_urls: icon_urls.to_vec(),
38        }
39    }
40}
41
42impl Chain {
43    /// Hex chain ID string (usable for EIP-3085/3326).
44    pub fn chain_id_hex(&self) -> String {
45        format!("0x{:x}", self.id())
46    }
47
48    /// Convert to EIP-3085 wallet parameters.
49    pub fn to_eip3085(&self) -> Eip3085Params {
50        let info = self.info();
51        let explorer_urls: Vec<String> = info
52            .explorers
53            .iter()
54            .filter(|e| e.standard == "EIP3091" || e.standard.is_empty())
55            .map(|e| e.url.clone())
56            .collect();
57        let icon_urls = info.icon.iter().cloned().collect::<Vec<_>>();
58        Eip3085Params::from_parts(
59            info.id,
60            info.name,
61            &info.native_currency,
62            &info.rpc_urls,
63            &explorer_urls,
64            &icon_urls,
65        )
66    }
67}
68
69impl ChainRecord {
70    /// Hex chain ID string (usable for EIP-3085/3326).
71    pub fn chain_id_hex(&self) -> String {
72        format!("0x{:x}", self.chain_id)
73    }
74
75    /// Convert schema record to EIP-3085 wallet parameters.
76    pub fn to_eip3085(&self) -> Eip3085Params {
77        let explorer_urls: Vec<String> = self
78            .explorers
79            .iter()
80            .filter(|e| e.standard == "EIP3091" || e.standard.is_empty())
81            .map(|e| e.url.clone())
82            .collect();
83        let icon_urls = self.icon.iter().cloned().collect::<Vec<_>>();
84        Eip3085Params::from_parts(
85            self.chain_id,
86            &self.name,
87            &self.native_currency,
88            &self.rpc,
89            &explorer_urls,
90            &icon_urls,
91        )
92    }
93}