orca_tx_sender/
rpc_config.rs

1use solana_client::nonblocking::rpc_client::RpcClient;
2use solana_program::hash::Hash;
3use std::time::Duration;
4
5const MAINNET_HASH: &str = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
6const DEVNET_HASH: &str = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG";
7const ECLIPSE_HASH: &str = "EAQLJCV2mh23BsK2P9oYpV5CHVLDNHTxYss3URrNmg3s";
8const ECLIPSE_TESTNET_HASH: &str = "CX4huckiV9QNAkKNVKi5Tj8nxzBive5kQimd94viMKsU";
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ChainId {
12    Mainnet,
13    Devnet,
14    Eclipse,
15    EclipseTestnet,
16    Unknown(Hash),
17}
18
19impl ChainId {
20    pub fn is_mainnet(&self) -> bool {
21        matches!(self, Self::Mainnet)
22    }
23}
24
25impl From<Hash> for ChainId {
26    fn from(hash: Hash) -> Self {
27        // Convert hash to string once for comparison
28        let hash_str = hash.to_string();
29        // Compare with string constants directly
30        if hash_str == MAINNET_HASH {
31            return Self::Mainnet;
32        } else if hash_str == DEVNET_HASH {
33            return Self::Devnet;
34        } else if hash_str == ECLIPSE_HASH {
35            return Self::Eclipse;
36        } else if hash_str == ECLIPSE_TESTNET_HASH {
37            return Self::EclipseTestnet;
38        }
39        Self::Unknown(hash)
40    }
41}
42
43/// RPC configuration for connecting to Solana nodes
44#[derive(Debug, Default, Clone, PartialEq)]
45pub struct RpcConfig {
46    pub url: String,
47    pub supports_priority_fee_percentile: bool,
48    pub chain_id: Option<ChainId>,
49}
50
51impl RpcConfig {
52    pub async fn new(url: impl Into<String>) -> Result<Self, String> {
53        let url = url.into();
54        let client = RpcClient::new(url.clone());
55        let genesis_hash = client
56            .get_genesis_hash()
57            .await
58            .map_err(|e| format!("Chain Detection Error: Failed to get genesis hash: {e}"))?;
59
60        Ok(Self {
61            url,
62            supports_priority_fee_percentile: false,
63            chain_id: Some(ChainId::from(genesis_hash)),
64        })
65    }
66
67    pub fn client(&self) -> RpcClient {
68        RpcClient::new_with_timeout(self.url.clone(), Duration::from_millis(90_000))
69    }
70
71    /// Check if the RPC is connected to Solana mainnet
72    pub fn is_mainnet(&self) -> bool {
73        self.chain_id
74            .as_ref()
75            .is_some_and(|chain_id| chain_id.is_mainnet())
76    }
77}