bitget_rs 0.1.0

Bitget V2 futures SDK
Documentation
use bitget_rs::api::websocket::{
    BitgetWebsocketChannel, BitgetWebsocketEvent, BitgetWebsocketManager, ReconnectConfig,
};
use bitget_rs::config::{Config, Credentials};
use std::env;
use std::time::Duration;
use tokio::time::timeout;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::from_env();
    let credentials = Credentials::from_env()?;
    let product_type =
        env::var("BITGET_WS_SMOKE_PRODUCT_TYPE").unwrap_or_else(|_| "USDT-FUTURES".to_string());
    let wait_seconds = env::var("BITGET_WS_SMOKE_WAIT_SECONDS")
        .ok()
        .and_then(|value| value.parse::<u64>().ok())
        .unwrap_or(30);

    let mut manager = BitgetWebsocketManager::new(
        config.ws_private_url,
        ReconnectConfig::default().with_message_timeout(Duration::from_secs(wait_seconds + 10)),
    )
    .with_login_credentials(credentials);
    if let Some(proxy_url) = config.proxy_url {
        manager = manager.with_proxy_url(proxy_url);
    }

    manager.add_subscription(
        BitgetWebsocketChannel::new(&product_type, "account").with_coin("default"),
    );
    manager.add_subscription(
        BitgetWebsocketChannel::new(&product_type, "orders").with_inst_id("default"),
    );

    let mut events = manager.start().await?;
    wait_for_private_login_and_subscriptions(&mut events, Duration::from_secs(wait_seconds))
        .await?;

    println!(
        "bitget private websocket smoke ok: state={:?} active_subscriptions={}",
        manager.connection_state(),
        manager.active_subscriptions_count()
    );

    manager.stop().await;
    Ok(())
}

async fn wait_for_private_login_and_subscriptions(
    events: &mut tokio::sync::mpsc::Receiver<BitgetWebsocketEvent>,
    wait: Duration,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut logged_in = false;
    let mut subscribed = 0_usize;

    loop {
        let event = timeout(wait, events.recv())
            .await
            .map_err(|_| "timed out waiting for Bitget private WebSocket event")?
            .ok_or("Bitget private WebSocket event stream closed")?;

        match event {
            BitgetWebsocketEvent::Login { code, msg, .. } => {
                let success = matches!(code.as_deref(), Some("0") | Some("00000"));
                if !success {
                    return Err(format!(
                        "Bitget private WebSocket login failed: code={:?} msg={:?}",
                        code, msg
                    )
                    .into());
                }
                logged_in = true;
            }
            BitgetWebsocketEvent::Subscribed { .. } => {
                subscribed += 1;
            }
            BitgetWebsocketEvent::Account { .. } | BitgetWebsocketEvent::Orders { .. } => {
                subscribed += 1;
            }
            BitgetWebsocketEvent::Error { code, msg, .. } => {
                return Err(format!(
                    "Bitget private WebSocket error: code={:?} msg={:?}",
                    code, msg
                )
                .into());
            }
            _ => {}
        }

        if logged_in && subscribed >= 2 {
            return Ok(());
        }
    }
}