Skip to main content

sol_parser_sdk/grpc/
geyser_connect.rs

1//! Yellowstone Geyser gRPC 客户端连接(与 [`super::client::YellowstoneGrpc`] 共用 tonic / TLS 约定)。
2
3use std::time::Duration;
4
5use yellowstone_grpc_client::{GeyserGrpcClient, Interceptor, ClientTlsConfig};
6
7/// 连接 Geyser 的常用选项(与业务无关)。
8#[derive(Debug, Clone)]
9pub struct GeyserConnectConfig {
10    pub connect_timeout: Duration,
11    pub max_decoding_message_size: usize,
12    pub x_token: Option<String>,
13}
14
15impl Default for GeyserConnectConfig {
16    fn default() -> Self {
17        Self {
18            connect_timeout: Duration::from_secs(8),
19            max_decoding_message_size: 1024 * 1024 * 1024,
20            x_token: None,
21        }
22    }
23}
24
25/// 建立一条 Geyser gRPC 连接(安装 rustls ring provider、`https` 时启用系统根 TLS)。
26pub async fn connect_yellowstone_geyser(
27    endpoint: &str,
28    config: GeyserConnectConfig,
29) -> Result<GeyserGrpcClient<impl Interceptor>, String> {
30    let _ = rustls::crypto::ring::default_provider().install_default();
31
32    let mut builder = GeyserGrpcClient::build_from_shared(endpoint.to_string())
33        .map_err(|e| e.to_string())?
34        .connect_timeout(config.connect_timeout)
35        .max_decoding_message_size(config.max_decoding_message_size);
36
37    if let Some(ref t) = config.x_token {
38        builder = builder
39            .x_token(Some(t.as_str()))
40            .map_err(|e| e.to_string())?;
41    }
42
43    if endpoint.starts_with("https://") {
44        builder = builder
45            .tls_config(ClientTlsConfig::new().with_native_roots())
46            .map_err(|e| e.to_string())?;
47    }
48
49    builder.connect().await.map_err(|e| e.to_string())
50}