chainstream-sdk 2.0.11

SDK for interacting with the ChainStream API
Documentation
//! WebSocket Stream API Test
//!
//! Run with: cargo test --test ws_test -- --nocapture --ignored
//! Set CHAINSTREAM_ACCESS_TOKEN environment variable for testing

use chainstream_sdk::{
    stream::{Resolution, TokenCandle},
    ChainStreamClient,
};
use std::env;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use tokio::signal;

const TEST_ACCESS_TOKEN: &str = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtleXN0b3JlLUNIQU5HRS1NRSJ9.eyJqdGkiOiJJQWxZMGdNRGJ0ZW5jNnNhT1dheDEiLCJzdWIiOiJIR2hWbmpiSWlheDFIcDNUakdUd083WU9FUkJURXRwaSIsImlhdCI6MTc3MDAxMzc0MywiZXhwIjoxNzcwMTAwMTQzLCJjbGllbnRfaWQiOiJIR2hWbmpiSWlheDFIcDNUakdUd083WU9FUkJURXRwaSIsImlzcyI6Imh0dHBzOi8vZGV4LmFzaWEuYXV0aC5jaGFpbnN0cmVhbS5pby8iLCJhdWQiOiJodHRwczovL2FwaS5kZXguY2hhaW5zdHJlYW0uaW8ifQ.TVY_FN1MdMogamLvXnYlVoLSXTZpX1b1c3xtUJNB5peUrZCTY_nLB8oOJ-ysBz3qsZhnUpUnX4LKSfuyGXDlfyasJG5c7yrj5zEYUZfkFKxG7PTtNLzXTF-4z0J7VnkbA-VUz1c1z3gaGDf3TFpo_Mfl6Zqf0v_CgDugciJ0ZbJS68gy_EaMXSBHwU7mm_vC2FUFkUfa8qwL3xvEEbOYxIQXJyHmqddnJew6nSyifHEqC_tSYj-o8GDP6PTbfOwqiyB_-T8valMwygFXYMgGstOUnITgNvJE4ciya3yalLuWONoA3LtoDzAq3wABr-0cyIbHVvQJkDT0VjqvJOv89Q";

fn get_access_token() -> String {
    env::var("CHAINSTREAM_ACCESS_TOKEN").unwrap_or_else(|_| TEST_ACCESS_TOKEN.to_string())
}

#[tokio::test]
#[ignore] // Run with: cargo test --test ws_test -- --nocapture --ignored
async fn test_subscribe_token_candles() {
    let access_token = get_access_token();
    let client = ChainStreamClient::new(&access_token, None);

    let chain = "sol";
    let token_address = "So11111111111111111111111111111111111111112"; // SOL
    let resolution = Resolution::X1s;

    println!("===========================================");
    println!("Subscribing to token candles");
    println!("Chain: {}", chain);
    println!("Token: {}", token_address);
    println!("Resolution: {}", resolution);
    println!("Press Ctrl+C to exit...");
    println!("===========================================\n");

    let message_count = Arc::new(AtomicUsize::new(0));
    let message_count_clone = message_count.clone();

    let result = client
        .stream
        .subscribe_token_candles(
            chain,
            token_address,
            resolution,
            move |candle: TokenCandle| {
                let count = message_count_clone.fetch_add(1, Ordering::SeqCst) + 1;
                println!(
                    "[{}] open={}, close={}, high={}, low={}, volume={}, time={}",
                    count,
                    candle.open,
                    candle.close,
                    candle.high,
                    candle.low,
                    candle.volume,
                    candle.time
                );
            },
            None,
            None, // price_type: default to USD
        )
        .await;

    if let Err(e) = result {
        eprintln!("Failed to subscribe: {:?}", e);
        return;
    }

    let _unsub = result.unwrap();

    // Wait for Ctrl+C
    signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");

    println!("\n===========================================");
    println!(
        "Received {} messages total",
        message_count.load(Ordering::SeqCst)
    );
    println!("Closing connection...");
    println!("===========================================");

    client.close().await;
}