Skip to main content

reth_node_ethstats/
credentials.rs

1use crate::error::EthStatsError;
2use std::str::FromStr;
3
4/// Credentials for connecting to an `EthStats` server
5///
6/// Contains the node identifier, authentication secret, and server host
7/// information needed to establish a connection with the `EthStats` service.
8#[derive(Debug, Clone)]
9pub(crate) struct EthstatsCredentials {
10    /// Unique identifier for this node in the `EthStats` network
11    pub node_id: String,
12    /// Authentication secret for the `EthStats` server
13    pub secret: String,
14    /// Host address of the `EthStats` server
15    pub host: String,
16    /// Whether to use secure `WebSocket` (`WSS`) connection
17    pub use_tls: bool,
18}
19
20impl FromStr for EthstatsCredentials {
21    type Err = EthStatsError;
22
23    /// Parse credentials from a string in the format "`node_id:secret@host`" or
24    /// "`node_id:secret@wss://host`"
25    ///
26    /// Supports the following formats:
27    /// - `node_id:secret@host` - Uses plain `WebSocket` (`ws://`)
28    /// - `node_id:secret@ws://host` - Explicitly use plain `WebSocket`
29    /// - `node_id:secret@wss://host` - Use secure `WebSocket` (`WSS`)
30    ///
31    /// # Arguments
32    /// * `s` - String containing credentials
33    ///
34    /// # Returns
35    /// * `Ok(EthstatsCredentials)` - Successfully parsed credentials
36    /// * `Err(EthStatsError::InvalidUrl)` - Invalid format or missing separators
37    fn from_str(s: &str) -> Result<Self, Self::Err> {
38        let parts: Vec<&str> = s.split('@').collect();
39        if parts.len() != 2 {
40            return Err(EthStatsError::InvalidUrl("Missing '@' separator".to_string()));
41        }
42        let creds = parts[0];
43        let mut host = parts[1].to_string();
44        let creds_parts: Vec<&str> = creds.split(':').collect();
45        if creds_parts.len() != 2 {
46            return Err(EthStatsError::InvalidUrl(
47                "Missing ':' separator in credentials".to_string(),
48            ));
49        }
50        let node_id = creds_parts[0].to_string();
51        let secret = creds_parts[1].to_string();
52
53        // Detect and strip protocol prefix if present
54        let mut use_tls = false;
55        if let Some(stripped) = host.strip_prefix("wss://") {
56            use_tls = true;
57            host = stripped.to_string();
58        } else if let Some(stripped) = host.strip_prefix("ws://") {
59            use_tls = false;
60            host = stripped.to_string();
61        }
62
63        Ok(Self { node_id, secret, host, use_tls })
64    }
65}