polynode 0.7.0

Rust SDK for the PolyNode API — real-time Polymarket data
Documentation
use serde::{Deserialize, Serialize};

/// A single price level in the orderbook.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrderbookLevel {
    pub price: String,
    pub size: String,
}

/// Full orderbook snapshot for an asset.
#[derive(Debug, Clone, Deserialize)]
pub struct BookSnapshot {
    pub asset_id: String,
    pub market: String,
    #[serde(default)]
    pub event_title: Option<String>,
    #[serde(default)]
    pub question: Option<String>,
    #[serde(default)]
    pub outcome: Option<String>,
    #[serde(default)]
    pub slug: Option<String>,
    pub bids: Vec<OrderbookLevel>,
    pub asks: Vec<OrderbookLevel>,
}

/// Incremental orderbook delta. A level with size "0" means removal.
#[derive(Debug, Clone, Deserialize)]
pub struct BookUpdate {
    pub asset_id: String,
    pub market: String,
    #[serde(default)]
    pub event_title: Option<String>,
    #[serde(default)]
    pub question: Option<String>,
    #[serde(default)]
    pub outcome: Option<String>,
    #[serde(default)]
    pub slug: Option<String>,
    pub bids: Vec<OrderbookLevel>,
    pub asks: Vec<OrderbookLevel>,
}

/// A single asset's price in a price change event.
#[derive(Debug, Clone, Deserialize)]
pub struct PriceChangeAsset {
    pub asset_id: String,
    pub price: String,
    pub outcome: String,
}

/// Summary of price movement across assets in a market.
#[derive(Debug, Clone, Deserialize)]
pub struct PriceChange {
    pub market: String,
    #[serde(default)]
    pub event_title: Option<String>,
    #[serde(default)]
    pub question: Option<String>,
    #[serde(default)]
    pub slug: Option<String>,
    pub assets: Vec<PriceChangeAsset>,
}

/// Individual orderbook update, discriminated by `type` field.
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type")]
pub enum OrderbookUpdate {
    #[serde(rename = "book_snapshot")]
    Snapshot(BookSnapshot),
    #[serde(rename = "book_update")]
    Update(BookUpdate),
    #[serde(rename = "price_change")]
    PriceChange(PriceChange),
}

/// Messages yielded to the user from the orderbook stream.
#[derive(Debug)]
pub enum ObMessage {
    /// An individual orderbook update (snapshot, delta, or price change).
    Update(OrderbookUpdate),
    /// All initial snapshots have been delivered.
    SnapshotsDone { total: u64 },
    /// Subscription acknowledged.
    Subscribed { markets: u64 },
    /// Unsubscribed.
    Unsubscribed,
    /// Error from the server.
    Error { error: String, message: String },
}

// ── Wire message types for deserialization ──

#[derive(Debug, Deserialize)]
pub(crate) struct RawObMessage {
    #[serde(rename = "type", default)]
    pub msg_type: Option<String>,
    #[serde(default)]
    pub error: Option<String>,
    #[serde(default)]
    pub message: Option<String>,
    #[serde(default)]
    pub markets: Option<u64>,
    #[serde(default)]
    pub total: Option<u64>,
    #[serde(default)]
    pub snapshots: Option<Vec<serde_json::Value>>,
    #[serde(default)]
    pub updates: Option<Vec<serde_json::Value>>,
}