Skip to content

Commit 904b8e9

Browse files
authored
Merge pull request #118 from iamnivekx/feat/websocket-devnet-support
feat: add enhanced websocket support for devnet cluster
2 parents e43dffe + 6a12662 commit 904b8e9

3 files changed

Lines changed: 60 additions & 7 deletions

File tree

src/client.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::config::Config;
44
use crate::error::{HeliusError, Result};
55
use crate::rpc_client::RpcClient;
66
use crate::types::Cluster;
7-
use crate::websocket::{EnhancedWebsocket, ENHANCED_WEBSOCKET_URL};
7+
use crate::websocket::EnhancedWebsocket;
88

99
use reqwest::Client;
1010
use solana_client::nonblocking::rpc_client::RpcClient as AsyncSolanaRpcClient;
@@ -106,10 +106,11 @@ impl Helius {
106106
ping_interval_secs: Option<u64>,
107107
pong_timeout_secs: Option<u64>,
108108
) -> Result<Self> {
109-
let config: Arc<Config> = Arc::new(Config::new(api_key, cluster)?);
109+
let config: Arc<Config> = Arc::new(Config::new(api_key, cluster.clone())?);
110110
let client: Client = Client::builder().build().map_err(HeliusError::ReqwestError)?;
111111
let rpc_client: Arc<RpcClient> = Arc::new(RpcClient::new(Arc::new(client.clone()), config.clone())?);
112-
let wss: String = format!("{}{}", ENHANCED_WEBSOCKET_URL, api_key);
112+
113+
let wss: String = EnhancedWebsocket::get_url(&cluster, api_key)?;
113114
let ws_client: Arc<EnhancedWebsocket> =
114115
Arc::new(EnhancedWebsocket::new(&wss, ping_interval_secs, pong_timeout_secs).await?);
115116

src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::error::{HeliusError, Result};
22
use crate::rpc_client::RpcClient;
33
use crate::types::{Cluster, HeliusEndpoints, MintApiAuthority};
4-
use crate::websocket::{EnhancedWebsocket, ENHANCED_WEBSOCKET_URL};
4+
use crate::websocket::EnhancedWebsocket;
55
use crate::Helius;
66
use reqwest::Client;
77
use solana_client::nonblocking::rpc_client::RpcClient as AsyncSolanaRpcClient;
@@ -108,7 +108,7 @@ impl Config {
108108
let client: Client = Client::builder().build().map_err(HeliusError::ReqwestError)?;
109109
let rpc_client: Arc<RpcClient> = Arc::new(self.rpc_client_with_reqwest_client(client.clone())?);
110110

111-
let wss: String = format!("{}{}", ENHANCED_WEBSOCKET_URL, self.api_key);
111+
let wss: String = EnhancedWebsocket::get_url(&self.cluster, &self.api_key)?;
112112
let ws_client: Arc<EnhancedWebsocket> =
113113
Arc::new(EnhancedWebsocket::new(&wss, ping_interval_secs, pong_timeout_secs).await?);
114114

@@ -144,7 +144,7 @@ impl Config {
144144
let async_solana_client = Arc::new(AsyncSolanaRpcClient::new(rpc_url.to_string()));
145145

146146
// Setup websocket
147-
let wss: String = format!("{}{}", ENHANCED_WEBSOCKET_URL, self.api_key);
147+
let wss: String = EnhancedWebsocket::get_url(&self.cluster, &self.api_key)?;
148148
let ws_client: Arc<EnhancedWebsocket> =
149149
Arc::new(EnhancedWebsocket::new(&wss, ping_interval_secs, pong_timeout_secs).await?);
150150

src/websocket.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::error::{HeliusError, Result};
2+
use crate::types::Cluster;
23
use crate::types::{RpcTransactionsConfig, TransactionNotification};
34
use futures_util::{
45
future::{ready, BoxFuture, FutureExt},
@@ -29,7 +30,9 @@ use tokio_tungstenite::{
2930
MaybeTlsStream, WebSocketStream,
3031
};
3132

32-
pub const ENHANCED_WEBSOCKET_URL: &str = "wss://atlas-mainnet.helius-rpc.com/?api-key=";
33+
pub const ENHANCED_WEBSOCKET_URL_MAINNET: &str = "wss://atlas-mainnet.helius-rpc.com/?api-key=";
34+
pub const ENHANCED_WEBSOCKET_URL_DEVNET: &str = "wss://atlas-devnet.helius-rpc.com/?api-key=";
35+
3336
pub const DEFAULT_PING_DURATION_SECONDS: u64 = 10;
3437
pub const DEFAULT_MAX_FAILED_PINGS: usize = 3;
3538

@@ -52,6 +55,55 @@ pub struct EnhancedWebsocket {
5255
}
5356

5457
impl EnhancedWebsocket {
58+
/// Constructs the complete websocket URL for connecting to Helius's enhanced websocket endpoints.
59+
///
60+
/// # Arguments
61+
///
62+
/// * `cluster` - The Solana cluster to connect to (MainnetBeta or Devnet)
63+
/// * `api_key` - Your Helius API key
64+
///
65+
/// # Returns
66+
///
67+
/// Returns a Result containing the formatted websocket URL or an error if an unsupported cluster is specified.
68+
///
69+
/// # Errors
70+
///
71+
/// Returns `HeliusError::EnhancedWebsocket` if the specified cluster is not MainnetBeta or Devnet.
72+
/// Note: StakedMainnetBeta is not supported for websocket connections.
73+
///
74+
/// # Examples
75+
///
76+
/// ```rust
77+
/// use helius::websocket::EnhancedWebsocket;
78+
/// use helius::types::Cluster;
79+
///
80+
/// let api_key = "your_api_key";
81+
///
82+
/// // For Mainnet
83+
/// let mainnet_url = EnhancedWebsocket::get_url(&Cluster::MainnetBeta, api_key).expect("Failed to get URL");
84+
/// println!("Mainnet URL: {}", mainnet_url);
85+
/// assert!(mainnet_url.eq("wss://atlas-mainnet.helius-rpc.com/?api-key=your_api_key"));
86+
///
87+
/// // For Devnet
88+
/// let devnet_url = EnhancedWebsocket::get_url(&Cluster::Devnet, api_key).expect("Failed to get URL");
89+
/// println!("Devnet URL: {}", devnet_url);
90+
/// assert!(devnet_url.eq("wss://atlas-devnet.helius-rpc.com/?api-key=your_api_key"));
91+
///
92+
/// // For Staked Mainnet (will error)
93+
/// let staked_result = EnhancedWebsocket::get_url(&Cluster::StakedMainnetBeta, api_key);
94+
/// assert!(staked_result.is_err());
95+
/// ```
96+
pub fn get_url(cluster: &Cluster, api_key: &str) -> Result<String> {
97+
match cluster {
98+
Cluster::MainnetBeta => Ok(format!("{}{}", ENHANCED_WEBSOCKET_URL_MAINNET, api_key)),
99+
Cluster::Devnet => Ok(format!("{}{}", ENHANCED_WEBSOCKET_URL_DEVNET, api_key)),
100+
Cluster::StakedMainnetBeta => Err(HeliusError::EnhancedWebsocket {
101+
reason: "Unsupported cluster".into(),
102+
message: "only mainnet and devnet are supported".into(),
103+
}),
104+
}
105+
}
106+
55107
/// Expects enhanced websocket endpoint: wss://atlas-mainnet.helius-rpc.com?api-key=<API_KEY>
56108
pub async fn new(url: &str, ping_interval_secs: Option<u64>, pong_timeout_secs: Option<u64>) -> Result<Self> {
57109
let (ws, _response) = connect_async(url).await.map_err(HeliusError::Tungstenite)?;

0 commit comments

Comments
 (0)