polynode
Rust SDK for the PolyNode real-time Polymarket API.
Stream settlements, trades, positions, deposits, oracle events, orderbook updates, and more through a single WebSocket connection. All events enriched with full market metadata.
New in v0.13.10: Published docs now include explicit Rust examples for both supported V2 wallet identities: existing Safe users (POLY_GNOSIS_SAFE) and new deposit-wallet users (POLY_1271).
New in v0.13.9: Rust V2 trading keeps Safe and deposit-wallet identities separate: pass an explicit signature_type plus funder_address to route existing Safe users through POLY_GNOSIS_SAFE, while new deposit-wallet users continue through POLY_1271. Safe V2 onboarding can now relay pUSD/CTF approvals, and stored credentials are reused without silently flipping wallet type.
New in v0.13.8: Rust deposit-wallet V2 trading now self-heals deployed-wallet onboarding, includes USDC.e collateral-onramp approval, uses the deposit wallet as both order maker and signer for POLY_1271, wraps available USDC.e into pUSD before buy orders, and matches Polymarket's current V2 POLY_1271 order body and wrapped signature format.
New in v0.12: V2 order flow — place orders on the Polymarket V2 CLOB with pUSD collateral and builder attribution. See src/trading/V2_ORDER_FLOW.md for the full reference.
In v0.5: Local Cache — SQLite-backed local storage. Backfill wallet history in seconds, query trades and positions instantly with zero API calls.
Install
[]
= "0.13.10"
= { = "1", = ["rt", "macros"] }
# For local cache (optional):
# polynode = { version = "0.13.10", features = ["cache"] }
Quick Start
use PolyNodeClient;
async
Rust V2 Trading Wallet Modes
Polymarket V2 supports two smart-wallet identities. They are not interchangeable:
- Existing Safe users:
SignatureType::PolyGnosisSafe, with the Safe address asfunder_address. - New deposit-wallet users:
SignatureType::Poly1271, with the deposit wallet address asfunder_address.
Pass both values explicitly whenever you know the user's Polymarket wallet type. This prevents the SDK from deriving a different wallet and sending orders with a maker address that the CLOB does not allow.
Existing Safe user:
use ;
let signer = from_hex?;
let mut trader = new?;
trader.ensure_ready.await?;
Deposit-wallet user:
use ;
let signer = from_hex?;
let deposit_wallet = format!;
let mut trader = new?;
trader.ensure_ready.await?;
Both paths use pUSD on V2. The SDK can wrap available USDC.e into pUSD before BUY orders when the configured wallet has the required onramp approval and builder credentials are available for smart-wallet execution.
REST API
// System
client.healthz.await?;
client.status.await?;
client.create_key.await?;
// Markets
client.markets.await?;
client.market.await?;
client.market_by_slug.await?;
client.market_by_condition.await?;
client.list_markets.await?;
client.search.await?;
// Pricing
client.candles.await?;
client.stats.await?;
// Settlements
client.recent_settlements.await?;
client.token_settlements.await?;
client.wallet_settlements.await?;
// Wallets
client.wallet.await?;
// RPC (rpc.polynode.dev)
client.rpc_call.await?;
WebSocket Streaming
use ;
use WsMessage;
let mut stream = client.stream.await?;
stream.subscribe.await?;
while let Some = stream.next.await
Subscription Types
Settlements // pending + confirmed settlements
Trades // all trade activity
Prices // price-moving events
Blocks // new Polygon blocks
Wallets // all wallet activity
Markets // all market activity
LargeTrades // $1K+ trades
Oracle // UMA resolution events
Chainlink // real-time price feeds
Subscription Filters
new
.wallets
.tokens
.slugs
.condition_ids
.side
.status
.min_size
.max_size
.event_types
.snapshot_count
.feeds
Orderbook Streaming
use ;
let mut stream = client.orderbook_stream.await?;
stream.subscribe.await?;
let mut book = new;
while let Some = stream.next.await
// Query local state
let best_bid = book.best_bid;
let best_ask = book.best_ask;
let spread = book.spread;
OrderbookEngine
Higher-level orderbook client. One connection, shared state, filtered views for different parts of your app.
use ;
let engine = connect.await?;
// Subscribe with token IDs, slugs, or condition IDs
engine.subscribe.await?;
// Query computed values from local state
engine.midpoint.await; // Some(0.465)
engine.spread.await; // Some(0.01)
engine.best_bid.await; // Some(OrderbookLevel { price: "0.46", size: "226.29" })
engine.book.await; // Some((bids, asks))
// Create filtered views for different components
let mut view = engine.view;
view.midpoint.await; // reads from shared state
// Receive only this view's updates
while let Some = view.next.await
engine.close.await?;
Zlib compression is enabled by default (~50% bandwidth savings). All connections auto-reconnect with exponential backoff.
Local Cache
Store trades and positions in a local SQLite database. Backfills recent history on startup, streams live updates, and serves all queries locally with zero API calls.
Enable the cache feature in your Cargo.toml:
= { = "0.13.10", = ["cache"] }
use ;
use Arc;
let client = new;
let mut cache = builder
.db_path
.watchlist_path
.on_backfill_progress
.build?;
cache.start.await?;
// Query locally — instant, no API calls
let trades = cache.wallet_trades?;
let positions = cache.wallet_positions?;
let stats = cache.stats?;
// Add wallets at runtime
use EntityType;
cache.add_to_watchlist?;
cache.stop.await?;
Watchlist (polynode.watch.json):
Backfill timing: 1 request per wallet at 1 req/s. 10 wallets = 10 seconds. See full documentation.
Configuration
let client = builder
.base_url
.ws_url
.ob_url
.rpc_url
.timeout
.build?;
Error Handling
use Error;
match client.market.await
Links
License
MIT