layer_climb_config/
config.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use std::{fmt::Display, str::FromStr};
4
5#[derive(Serialize, Deserialize, Debug, Clone)]
6pub struct ChainConfig {
7    pub chain_id: ChainId,
8    pub rpc_endpoint: Option<String>,
9    pub grpc_endpoint: Option<String>,
10    // if not specified, will fallback to `grpc_endpoint`
11    pub grpc_web_endpoint: Option<String>,
12    // not micro-units, e.g. 0.025 would be a typical value
13    pub gas_price: f32,
14    pub gas_denom: String,
15    pub address_kind: AddrKind,
16}
17
18#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
19#[serde(rename_all = "snake_case")]
20pub enum AddrKind {
21    Cosmos { prefix: String },
22    Eth,
23}
24
25impl std::hash::Hash for AddrKind {
26    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
27        match self {
28            AddrKind::Cosmos { prefix } => {
29                1u32.hash(state);
30                prefix.hash(state);
31            }
32            AddrKind::Eth => {
33                2u32.hash(state);
34            }
35        }
36    }
37}
38
39impl ChainConfig {
40    pub fn ibc_client_revision(&self) -> Result<u64> {
41        // > Tendermint chains wishing to use revisions to maintain persistent IBC connections even across height-resetting upgrades
42        // > must format their chainIDs in the following manner: {chainID}-{revision_number}
43        // - https://github.com/cosmos/ibc-go/blob/main/docs/docs/01-ibc/01-overview.md#ibc-client-heights
44        Ok(self
45            .chain_id
46            .as_str()
47            .split("-")
48            .last()
49            .and_then(|s| s.parse::<u64>().ok())
50            .unwrap_or_default())
51    }
52}
53
54#[derive(Deserialize, Serialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
55#[serde(transparent)]
56pub struct ChainId(String);
57impl ChainId {
58    pub fn new(id: impl ToString) -> Self {
59        Self(id.to_string())
60    }
61    pub fn as_str(&self) -> &str {
62        &self.0
63    }
64}
65
66impl FromStr for ChainId {
67    type Err = anyhow::Error;
68
69    fn from_str(s: &str) -> Result<Self, Self::Err> {
70        Ok(Self::new(s))
71    }
72}
73
74impl Display for ChainId {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        write!(f, "{}", self.0)
77    }
78}