Skip to main content

polyfill_rs/
lib.rs

1//! Polyfill-rs: High-performance Rust client for Polymarket
2//!
3//! # Features
4//!
5//! - **High-performance order book management** with optimized data structures
6//! - **Real-time market data streaming** with WebSocket support
7//! - **Trade execution simulation** with slippage protection
8//! - **Detailed error handling** with specific error types
9//! - **Rate limiting and retry logic** for robust API interactions
10//! - **Ethereum integration** with EIP-712 signing support
11//! - **Benchmarking tools** for performance analysis
12//!
13//! # Quick Start
14//!
15//! ```rust,no_run
16//! use polyfill_rs::{ClobClient, OrderArgs, Side};
17//! use rust_decimal::Decimal;
18//! use std::str::FromStr;
19//!
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     // Create client (compatible with polymarket-rs-client)
23//!     let mut client = ClobClient::with_l1_headers(
24//!         "https://clob.polymarket.com",
25//!         "your_private_key",
26//!         137,
27//!     );
28//!
29//!     // Get API credentials
30//!     let api_creds = client.create_or_derive_api_key(None).await.unwrap();
31//!     client.set_api_creds(api_creds);
32//!
33//!     // Create and post order
34//!     let order_args = OrderArgs::new(
35//!         "token_id",
36//!         Decimal::from_str("0.75").unwrap(),
37//!         Decimal::from_str("100.0").unwrap(),
38//!         Side::BUY,
39//!     );
40//!
41//!     let result = client.create_and_post_order(&order_args).await.unwrap();
42//!     println!("Order posted: {:?}", result);
43//!
44//!     Ok(())
45//! }
46//! ```
47//!
48//! # Advanced Usage
49//!
50//! ```rust,no_run
51//! use polyfill_rs::{ClobClient, OrderBookImpl};
52//! use rust_decimal::Decimal;
53//!
54//! #[tokio::main]
55//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
56//!     // Create a basic client
57//!     let client = ClobClient::new("https://clob.polymarket.com");
58//!
59//!     // Get market data
60//!     let markets = client.get_sampling_markets(None).await.unwrap();
61//!     println!("Found {} markets", markets.data.len());
62//!
63//!     // Create an order book for high-performance operations
64//!     let mut book = OrderBookImpl::new("token_id".to_string(), 100); // 100 levels depth
65//!     println!("Order book created for token: {}", book.token_id);
66//!
67//!     Ok(())
68//! }
69//! ```
70
71use tracing::info;
72
73// Global constants
74pub const DEFAULT_CHAIN_ID: u64 = 137; // Polygon
75pub const DEFAULT_BASE_URL: &str = "https://clob.polymarket.com";
76pub const DEFAULT_TIMEOUT_SECS: u64 = 30;
77pub const DEFAULT_MAX_RETRIES: u32 = 3;
78pub const DEFAULT_RATE_LIMIT_RPS: u32 = 100;
79
80// Initialize logging
81pub fn init() {
82    tracing_subscriber::fmt::init();
83    info!("Polyfill-rs initialized");
84}
85
86// Re-export main types
87pub use crate::types::{
88    ApiCredentials,
89    // Additional compatibility types
90    ApiKeysResponse,
91    AssetType,
92    Balance,
93    BalanceAllowance,
94    BalanceAllowanceParams,
95    BatchMidpointRequest,
96    BatchMidpointResponse,
97    BatchPriceRequest,
98    BatchPriceResponse,
99    BookParams,
100    ClientConfig,
101    ClientResult,
102    FillEvent,
103    Market,
104    MarketSnapshot,
105    MarketsResponse,
106    MidpointResponse,
107    NegRiskResponse,
108    NotificationParams,
109    OpenOrder,
110    OpenOrderParams,
111    Order,
112    OrderBook,
113    OrderBookSummary,
114    OrderDelta,
115    OrderRequest,
116    OrderStatus,
117    OrderSummary,
118    OrderType,
119    PriceResponse,
120    PricesHistoryInterval,
121    PricesHistoryResponse,
122    Rewards,
123    Side,
124    SimplifiedMarket,
125    SimplifiedMarketsResponse,
126    SpreadResponse,
127    StreamMessage,
128    TickSizeResponse,
129    Token,
130    TokenPrice,
131    TradeParams,
132    WssAuth,
133    WssChannelType,
134    WssSubscription,
135};
136
137// Re-export client
138pub use crate::client::{ClobClient, PolyfillClient};
139
140// Re-export compatibility types (for easy migration from polymarket-rs-client)
141pub use crate::client::OrderArgs;
142
143// Re-export error types
144pub use crate::errors::{PolyfillError, Result};
145
146// Re-export advanced components
147pub use crate::book::{OrderBook as OrderBookImpl, OrderBookManager};
148pub use crate::decode::Decoder;
149pub use crate::fill::{FillEngine, FillResult};
150pub use crate::stream::{MarketStream, StreamManager, WebSocketBookApplier, WebSocketStream};
151pub use crate::ws_hot_path::{WsBookApplyStats, WsBookUpdateProcessor};
152
153// Re-export utilities
154pub use crate::utils::{crypto, math, rate_limit, retry, time, url};
155
156// Module declarations
157pub mod auth;
158pub mod book;
159pub mod buffer_pool;
160pub mod client;
161pub mod connection_manager;
162pub mod decode;
163pub mod dns_cache;
164pub mod errors;
165pub mod fill;
166pub mod http_config;
167pub mod orders;
168pub mod stream;
169pub mod types;
170pub mod utils;
171pub mod ws_hot_path;
172
173// Benchmarks
174#[cfg(test)]
175mod benches {
176    use crate::{OrderBookManager, OrderDelta, Side};
177    use chrono::Utc;
178    use criterion::{criterion_group, criterion_main};
179    use rust_decimal::Decimal;
180    use std::str::FromStr;
181
182    #[allow(dead_code)]
183    fn order_book_benchmark(c: &mut criterion::Criterion) {
184        let book_manager = OrderBookManager::new(100);
185
186        c.bench_function("apply_order_delta", |b| {
187            b.iter(|| {
188                let delta = OrderDelta {
189                    token_id: "test_token".to_string(),
190                    timestamp: Utc::now(),
191                    side: Side::BUY,
192                    price: Decimal::from_str("0.75").unwrap(),
193                    size: Decimal::from_str("100.0").unwrap(),
194                    sequence: 1,
195                };
196
197                let _ = book_manager.apply_delta(delta);
198            });
199        });
200    }
201
202    criterion_group!(benches, order_book_benchmark);
203    criterion_main!(benches);
204}
205
206#[cfg(test)]
207mod tests {
208    use super::*;
209    use rust_decimal::Decimal;
210    use std::str::FromStr;
211
212    #[test]
213    fn test_client_creation() {
214        let _client = ClobClient::new("https://test.example.com");
215        // Test that the client was created successfully
216        // We can't test private fields, but we can verify the client exists
217        // Client creation successful
218    }
219
220    #[test]
221    fn test_order_args_creation() {
222        let args = OrderArgs::new(
223            "test_token",
224            Decimal::from_str("0.75").unwrap(),
225            Decimal::from_str("100.0").unwrap(),
226            Side::BUY,
227        );
228
229        assert_eq!(args.token_id, "test_token");
230        assert_eq!(args.side, Side::BUY);
231    }
232
233    #[test]
234    fn test_order_args_default() {
235        let args = OrderArgs::default();
236        assert_eq!(args.token_id, "");
237        assert_eq!(args.price, Decimal::ZERO);
238        assert_eq!(args.size, Decimal::ZERO);
239        assert_eq!(args.side, Side::BUY);
240    }
241}