//! Core types for the Polymarket client //! //! This module defines all the stable public types used throughout the client. //! These types are optimized for latency-sensitive trading environments. use alloy_primitives::{Address, U256}; use chrono::{DateTime, Utc}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use uuid::Uuid; /// Trading side for orders #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Side { BUY = 0, SELL = 1, } impl Side { pub fn as_str(&self) -> &'static str { match self { Side::BUY => "BUY", Side::SELL => "SELL", } } pub fn opposite(&self) -> Self { match self { Side::BUY => Side::SELL, Side::SELL => Side::BUY, } } } /// Order type specifications #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum OrderType { GTC, FOK, GTD, } impl OrderType { pub fn as_str(&self) -> &'static str { match self { OrderType::GTC => "GTC", OrderType::FOK => "FOK", OrderType::GTD => "GTD", } } } /// Order status in the system #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum OrderStatus { #[serde(rename = "LIVE")] Live, #[serde(rename = "CANCELLED")] Cancelled, #[serde(rename = "FILLED")] Filled, #[serde(rename = "PARTIAL")] Partial, #[serde(rename = "EXPIRED")] Expired, } /// Market snapshot representing current state #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MarketSnapshot { pub token_id: String, pub market_id: String, pub timestamp: DateTime, pub bid: Option, pub ask: Option, pub mid: Option, pub spread: Option, pub last_price: Option, pub volume_24h: Option, } /// Order book level (price/size pair) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BookLevel { #[serde(with = "rust_decimal::serde::str")] pub price: Decimal, #[serde(with = "rust_decimal::serde::str")] pub size: Decimal, } /// Full order book state #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OrderBook { /// Token ID pub token_id: String, /// Timestamp pub timestamp: DateTime, /// Bid orders pub bids: Vec, /// Ask orders pub asks: Vec, /// Sequence number pub sequence: u64, } /// Order book delta for streaming updates #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OrderDelta { pub token_id: String, pub timestamp: DateTime, pub side: Side, pub price: Decimal, pub size: Decimal, // 0 means remove level pub sequence: u64, } /// Trade execution event #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FillEvent { pub id: String, pub order_id: String, pub token_id: String, pub side: Side, pub price: Decimal, pub size: Decimal, pub timestamp: DateTime, pub maker_address: Address, pub taker_address: Address, pub fee: Decimal, } /// Order creation parameters #[derive(Debug, Clone)] pub struct OrderRequest { pub token_id: String, pub side: Side, pub price: Decimal, pub size: Decimal, pub order_type: OrderType, pub expiration: Option>, pub client_id: Option, } /// Market order parameters #[derive(Debug, Clone)] pub struct MarketOrderRequest { pub token_id: String, pub side: Side, pub amount: Decimal, // USD amount for buys, token amount for sells pub slippage_tolerance: Option, pub client_id: Option, } /// Order state in the system #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Order { pub id: String, pub token_id: String, pub side: Side, pub price: Decimal, pub original_size: Decimal, pub filled_size: Decimal, pub remaining_size: Decimal, pub status: OrderStatus, pub order_type: OrderType, pub created_at: DateTime, pub updated_at: DateTime, pub expiration: Option>, pub client_id: Option, } /// API credentials for authentication #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApiCredentials { pub api_key: String, pub secret: String, pub passphrase: String, } /// Configuration for order creation #[derive(Debug, Clone)] pub struct OrderOptions { pub tick_size: Option, pub neg_risk: Option, pub fee_rate_bps: Option, } /// Market information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Market { pub condition_id: String, pub tokens: [Token; 2], pub active: bool, pub closed: bool, pub question: String, pub description: String, pub category: Option, pub end_date_iso: Option, pub minimum_order_size: Decimal, pub minimum_tick_size: Decimal, } /// Token information within a market #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Token { pub token_id: String, pub outcome: String, } /// Client configuration for PolyfillClient #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientConfig { /// Base URL for the API pub base_url: String, /// Chain ID for the network pub chain_id: u64, /// Private key for signing (optional) pub private_key: Option, /// API credentials (optional) pub api_credentials: Option, /// Maximum slippage tolerance pub max_slippage: Option, /// Fee rate in basis points pub fee_rate: Option, /// Request timeout pub timeout: Option, /// Maximum number of connections pub max_connections: Option, } impl Default for ClientConfig { fn default() -> Self { Self { base_url: "https://clob.polymarket.com".to_string(), chain_id: 137, // Polygon mainnet private_key: None, api_credentials: None, timeout: Some(std::time::Duration::from_secs(30)), max_connections: Some(100), max_slippage: None, fee_rate: None, } } } /// WebSocket authentication for Polymarket API #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WssAuth { /// User's Ethereum address pub address: String, /// EIP-712 signature pub signature: String, /// Unix timestamp pub timestamp: u64, /// Nonce for replay protection pub nonce: String, } /// WebSocket subscription request #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WssSubscription { /// Authentication information pub auth: WssAuth, /// Array of markets (condition IDs) for USER channel pub markets: Option>, /// Array of asset IDs (token IDs) for MARKET channel pub asset_ids: Option>, /// Channel type: "USER" or "MARKET" #[serde(rename = "type")] pub channel_type: String, } /// WebSocket message types for streaming #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type")] pub enum StreamMessage { #[serde(rename = "book_update")] BookUpdate { data: OrderDelta, }, #[serde(rename = "trade")] Trade { data: FillEvent, }, #[serde(rename = "order_update")] OrderUpdate { data: Order, }, #[serde(rename = "heartbeat")] Heartbeat { timestamp: DateTime, }, /// User channel events #[serde(rename = "user_order_update")] UserOrderUpdate { data: Order, }, #[serde(rename = "user_trade")] UserTrade { data: FillEvent, }, /// Market channel events #[serde(rename = "market_book_update")] MarketBookUpdate { data: OrderDelta, }, #[serde(rename = "market_trade")] MarketTrade { data: FillEvent, }, } /// Subscription parameters for streaming #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Subscription { pub token_ids: Vec, pub channels: Vec, } /// WebSocket channel types #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum WssChannelType { #[serde(rename = "USER")] User, #[serde(rename = "MARKET")] Market, } impl WssChannelType { pub fn as_str(&self) -> &'static str { match self { WssChannelType::User => "USER", WssChannelType::Market => "MARKET", } } } /// Price quote response #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Quote { pub token_id: String, pub side: Side, #[serde(with = "rust_decimal::serde::str")] pub price: Decimal, pub timestamp: DateTime, } /// Balance information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Balance { pub token_id: String, pub available: Decimal, pub locked: Decimal, pub total: Decimal, } /// Performance metrics for monitoring #[derive(Debug, Clone)] pub struct Metrics { pub orders_per_second: f64, pub avg_latency_ms: f64, pub error_rate: f64, pub uptime_pct: f64, } // Type aliases for common patterns pub type TokenId = String; pub type OrderId = String; pub type MarketId = String; pub type ClientId = String; /// Result type used throughout the client pub type Result = std::result::Result;