Maintain exact Rust orderbooks with PN1 sequence and checksum verification.
use polynode::{EngineOptions, OrderbookEngine};#[tokio::main]async fn main() -> polynode::Result<()> { let api_key = std::env::var("POLYNODE_API_KEY") .expect("Set POLYNODE_API_KEY"); let token_id = std::env::var("POLYMARKET_TOKEN_ID") .expect("Set POLYMARKET_TOKEN_ID"); let engine = OrderbookEngine::connect(&api_key, EngineOptions { integrity: true, allow_stale_reads: false, ..Default::default() }).await?; let mut integrity_errors = engine.integrity_errors(); tokio::spawn(async move { while let Ok(error) = integrity_errors.recv().await { eprintln!("{:?} {} {}", error.code, error.token, error.message); } }); engine.subscribe(vec![token_id.clone()]).await?; while engine.book(&token_id).await.is_none() { tokio::time::sleep(std::time::Duration::from_millis(10)).await; } println!("best bid: {:?}", engine.best_bid(&token_id).await); println!("best ask: {:?}", engine.best_ask(&token_id).await); println!("midpoint: {:?}", engine.midpoint(&token_id).await); println!("spread: {:?}", engine.spread(&token_id).await); engine.close().await?; Ok(())}
PN1 keeps price and size values as exact decimal strings. It validates the full-snapshot anchor, then validates sequence continuity and a deterministic checksum on each applicable update.Managed state moves through Initializing, Ready, Stale, Resyncing, and Failed. With stale reads disabled, queries are unavailable until a verified anchor is ready and become unavailable after a disconnect or integrity failure. The engine requests a fresh anchor before returning to ready.
Wildcard "*" subscriptions are unavailable in integrity mode. Use explicit token IDs, slugs, or condition IDs.
Use client.orderbook_stream(ObStreamOptions { integrity: true, ..Default::default() }) when you want raw ObMessage values instead of managed state.See the shared orderbook guide and PN1 protocol reference.