openzeppelin_relayer/models/network/solana/
network.rs

1use crate::models::{NetworkConfigData, NetworkRepoModel, RepositoryError};
2use core::time::Duration;
3
4#[derive(Clone, PartialEq, Eq, Hash)]
5pub struct SolanaNetwork {
6    /// Unique network identifier (e.g., "mainnet", "sepolia", "custom-devnet").
7    pub network: String,
8    /// List of RPC endpoint URLs for connecting to the network.
9    pub rpc_urls: Vec<String>,
10    /// List of Explorer endpoint URLs for connecting to the network.
11    pub explorer_urls: Option<Vec<String>>,
12    /// Estimated average time between blocks in milliseconds.
13    pub average_blocktime_ms: u64,
14    /// Flag indicating if the network is a testnet.
15    pub is_testnet: bool,
16    /// List of arbitrary tags for categorizing or filtering networks.
17    pub tags: Vec<String>,
18}
19
20impl TryFrom<NetworkRepoModel> for SolanaNetwork {
21    type Error = RepositoryError;
22
23    /// Converts a NetworkRepoModel to a SolanaNetwork.
24    ///
25    /// # Arguments
26    /// * `network_repo` - The repository model to convert
27    ///
28    /// # Returns
29    /// Result containing the SolanaNetwork if successful, or a RepositoryError
30    fn try_from(network_repo: NetworkRepoModel) -> Result<Self, Self::Error> {
31        match &network_repo.config {
32            NetworkConfigData::Solana(solana_config) => {
33                let common = &solana_config.common;
34
35                let rpc_urls = common.rpc_urls.clone().ok_or_else(|| {
36                    RepositoryError::InvalidData(format!(
37                        "Solana network '{}' has no rpc_urls",
38                        network_repo.name
39                    ))
40                })?;
41
42                let average_blocktime_ms = common.average_blocktime_ms.ok_or_else(|| {
43                    RepositoryError::InvalidData(format!(
44                        "Solana network '{}' has no average_blocktime_ms",
45                        network_repo.name
46                    ))
47                })?;
48
49                Ok(SolanaNetwork {
50                    network: common.network.clone(),
51                    rpc_urls,
52                    explorer_urls: common.explorer_urls.clone(),
53                    average_blocktime_ms,
54                    is_testnet: common.is_testnet.unwrap_or(false),
55                    tags: common.tags.clone().unwrap_or_default(),
56                })
57            }
58            _ => Err(RepositoryError::InvalidData(format!(
59                "Network '{}' is not a Solana network",
60                network_repo.name
61            ))),
62        }
63    }
64}
65
66impl SolanaNetwork {
67    pub fn average_blocktime(&self) -> Option<Duration> {
68        Some(Duration::from_millis(self.average_blocktime_ms))
69    }
70
71    pub fn public_rpc_urls(&self) -> Option<&[String]> {
72        if self.rpc_urls.is_empty() {
73            None
74        } else {
75            Some(&self.rpc_urls)
76        }
77    }
78
79    pub fn explorer_urls(&self) -> Option<&[String]> {
80        self.explorer_urls.as_deref()
81    }
82
83    pub fn is_testnet(&self) -> bool {
84        self.is_testnet
85    }
86}