orca_tx_sender/
rpc_config.rs1use 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 let hash_str = hash.to_string();
29 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#[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 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}