basic_get_account/
basic_get_account.rs

1//! Basic example demonstrating hedged RPC requests.
2//!
3//! This example shows how to use the hedged RPC client to fetch a blockhash
4//! and account data, with the client automatically racing multiple providers.
5
6use std::{
7    env,
8    time::{Duration, Instant},
9};
10
11use hedged_rpc_client::{HedgeConfig, HedgedRpcClient, ProviderConfig, ProviderId};
12use solana_commitment_config::CommitmentConfig;
13use solana_sdk::pubkey::Pubkey;
14
15fn provider_from_env(env_key: &str, id: &'static str) -> Option<ProviderConfig> {
16    env::var(env_key).ok().map(|url| ProviderConfig {
17        id: ProviderId(id),
18        url,
19    })
20}
21
22#[tokio::main]
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24    let mut providers = Vec::new();
25
26    if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
27        providers.push(p);
28    }
29    if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
30        providers.push(p);
31    }
32    if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
33        providers.push(p);
34    }
35
36    if providers.is_empty() {
37        eprintln!("No providers configured.");
38        eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
39        return Ok(());
40    }
41
42    eprintln!(
43        "Using providers:\n{}",
44        providers
45            .iter()
46            .map(|p| format!("- {}: {}", (p.id).0, p.url))
47            .collect::<Vec<_>>()
48            .join("\n")
49    );
50
51    let cfg = HedgeConfig {
52        initial_providers: 1,
53        hedge_after: Duration::from_millis(80),
54        max_providers: providers.len(),
55        min_slot: None,
56        overall_timeout: Duration::from_secs(2),
57    };
58
59    let client = HedgedRpcClient::new(providers, cfg);
60
61    let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
62    let commitment = CommitmentConfig::processed();
63
64    let t0 = Instant::now();
65    let (bh_provider, blockhash) = client.get_latest_blockhash().await?;
66    let dt_bh = t0.elapsed();
67
68    println!(
69        "[blockhash] provider={} latency={:?} hash={}",
70        bh_provider.0, dt_bh, blockhash,
71    );
72
73    let t1 = Instant::now();
74    let (acc_provider, resp) = client.get_account(&addr, commitment).await?;
75    let dt_acc = t1.elapsed();
76
77    println!(
78        "[account]   provider={} latency={:?} slot={}",
79        acc_provider.0, dt_acc, resp.context.slot,
80    );
81
82    match resp.value {
83        Some(account) => {
84            println!("lamports={}", account.lamports);
85            println!("data_len={}", account.data.len());
86            println!("owner={}", account.owner);
87        }
88        None => println!("account not found"),
89    }
90
91    Ok(())
92}