polynode 0.8.0

Rust SDK for the PolyNode API — real-time Polymarket data
Documentation
use polynode::PolyNodeClient;

const API_KEY: &str = "pn_live_sdk_testing_enterprise_c0b4bfdff7bfd9f722bc89e1be83e965";

fn client() -> PolyNodeClient {
    PolyNodeClient::new(API_KEY).unwrap()
}

#[tokio::test]
async fn test_healthz() {
    let c = client();
    let result = c.healthz().await.unwrap();
    assert!(result.contains("ok"), "healthz should return ok, got: {}", result);
}

#[tokio::test]
async fn test_readyz() {
    let c = client();
    // readyz can return 200 or 503
    match c.readyz().await {
        Ok(v) => assert!(v.is_object() || v.is_string()),
        Err(polynode::Error::Api { status: 503, .. }) => {} // valid
        Err(e) => panic!("unexpected error: {}", e),
    }
}

#[tokio::test]
async fn test_status() {
    let c = client();
    let status = c.status().await.unwrap();
    assert!(status.uptime_seconds > 0);
    assert!(status.state.market_count > 0);
}

#[tokio::test]
async fn test_markets() {
    let c = client();
    let result = c.markets(Some(5)).await.unwrap();
    assert!(result.count > 0);
    assert!(!result.markets.is_empty());
    assert!(result.markets.len() <= 5);
    let m = &result.markets[0];
    assert!(m.token_id.is_some());
}

#[tokio::test]
async fn test_market_detail() {
    let c = client();
    let markets = c.markets(Some(1)).await.unwrap();
    let token_id = markets.markets[0].token_id.as_ref().unwrap();
    let detail = c.market(token_id).await.unwrap();
    assert!(detail.is_object());
}

#[tokio::test]
async fn test_search() {
    let c = client();
    let result = c.search("bitcoin", Some(5), None).await.unwrap();
    assert_eq!(result.query, "bitcoin");
    assert!(result.count > 0);
    assert!(!result.results.is_empty());
}

#[tokio::test]
async fn test_list_markets() {
    let c = client();
    let params = polynode::types::rest::ListMarketsParams {
        count: Some(3),
        sort: Some("volume".into()),
        ..Default::default()
    };
    let result = c.list_markets(&params).await.unwrap();
    assert!(result.markets.len() <= 3);
}

#[tokio::test]
async fn test_candles() {
    let c = client();
    let markets = c.markets(Some(1)).await.unwrap();
    let token_id = markets.markets[0].token_id.as_ref().unwrap();
    let result = c.candles(
        token_id,
        Some(polynode::CandleResolution::OneHour),
        Some(5),
    ).await.unwrap();
    assert!(!result.candles.is_empty());
    let candle = &result.candles[0];
    assert!(candle.timestamp > 0);
}

#[tokio::test]
async fn test_recent_settlements() {
    let c = client();
    let result = c.recent_settlements(Some(5)).await.unwrap();
    assert!(result.count > 0);
}

#[tokio::test]
async fn test_wallet() {
    let c = client();
    let result = c.wallet("0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e").await.unwrap();
    assert!(result.is_object());
}

#[tokio::test]
async fn test_invalid_api_key() {
    let c = PolyNodeClient::new("pn_live_invalid_key_000").unwrap();
    match c.status().await {
        Err(polynode::Error::Auth(_)) => {}
        other => panic!("expected Auth error, got: {:?}", other),
    }
}

#[tokio::test]
async fn test_not_found() {
    let c = client();
    match c.market("0000000000000000000000000000000000").await {
        Err(polynode::Error::NotFound(_)) => {}
        other => panic!("expected NotFound, got: {:?}", other),
    }
}

#[tokio::test]
async fn test_rpc() {
    let c = client();
    match c.rpc_call("eth_chainId", serde_json::json!([])).await {
        Ok(result) => {
            assert_eq!(result.as_str().unwrap(), "0x89");
        }
        Err(polynode::Error::Api { message, .. }) => {
            // Node may be unavailable (beta)
            assert!(message.contains("unavailable"), "unexpected RPC error: {}", message);
        }
        Err(e) => panic!("unexpected error: {}", e),
    }
}