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    FeeRateResponse,
103    FillEvent,
104    Market,
105    MarketSnapshot,
106    MarketsResponse,
107    MidpointResponse,
108    NegRiskResponse,
109    NotificationParams,
110    OpenOrder,
111    OpenOrderParams,
112    Order,
113    OrderBook,
114    OrderBookSummary,
115    OrderDelta,
116    OrderRequest,
117    OrderStatus,
118    OrderSummary,
119    OrderType,
120    PriceResponse,
121    PricesHistoryInterval,
122    PricesHistoryResponse,
123    Rewards,
124    RfqApproveOrderResponse,
125    RfqCancelQuote,
126    RfqCancelRequest,
127    RfqCreateQuote,
128    RfqCreateQuoteResponse,
129    RfqCreateRequest,
130    RfqCreateRequestResponse,
131    RfqListResponse,
132    RfqOrderExecutionRequest,
133    RfqQuoteData,
134    RfqQuotesParams,
135    RfqRequestData,
136    RfqRequestsParams,
137    Side,
138    SimplifiedMarket,
139    SimplifiedMarketsResponse,
140    SpreadResponse,
141    StreamMessage,
142    TickSizeResponse,
143    Token,
144    TokenPrice,
145    TradeParams,
146    WssAuth,
147    WssChannelType,
148    WssSubscription,
149};
150
151// Re-export client
152pub use crate::client::{ClobClient, PolyfillClient};
153
154// Re-export compatibility types (for easy migration from polymarket-rs-client)
155pub use crate::client::OrderArgs;
156
157// Re-export error types
158pub use crate::errors::{PolyfillError, Result};
159
160// Re-export advanced components
161pub use crate::book::{OrderBook as OrderBookImpl, OrderBookManager};
162pub use crate::decode::Decoder;
163pub use crate::fill::{FillEngine, FillResult};
164pub use crate::stream::{MarketStream, StreamManager, WebSocketBookApplier, WebSocketStream};
165pub use crate::ws_hot_path::{WsBookApplyStats, WsBookUpdateProcessor};
166
167// Re-export utilities
168pub use crate::utils::{crypto, math, rate_limit, retry, time, url};
169
170// Module declarations
171pub mod auth;
172pub mod book;
173pub mod buffer_pool;
174pub mod client;
175pub mod connection_manager;
176pub mod decode;
177pub mod dns_cache;
178pub mod errors;
179pub mod fill;
180pub mod http_config;
181pub mod orders;
182pub mod stream;
183pub mod types;
184pub mod utils;
185pub mod ws_hot_path;
186
187// Benchmarks
188#[cfg(test)]
189mod benches {
190    use crate::{OrderBookManager, OrderDelta, Side};
191    use chrono::Utc;
192    use criterion::{criterion_group, criterion_main};
193    use rust_decimal::Decimal;
194    use std::str::FromStr;
195
196    #[allow(dead_code)]
197    fn order_book_benchmark(c: &mut criterion::Criterion) {
198        let book_manager = OrderBookManager::new(100);
199
200        c.bench_function("apply_order_delta", |b| {
201            b.iter(|| {
202                let delta = OrderDelta {
203                    token_id: "test_token".to_string(),
204                    timestamp: Utc::now(),
205                    side: Side::BUY,
206                    price: Decimal::from_str("0.75").unwrap(),
207                    size: Decimal::from_str("100.0").unwrap(),
208                    sequence: 1,
209                };
210
211                let _ = book_manager.apply_delta(delta);
212            });
213        });
214    }
215
216    criterion_group!(benches, order_book_benchmark);
217    criterion_main!(benches);
218}
219
220#[cfg(test)]
221mod tests {
222    use super::*;
223    use rust_decimal::Decimal;
224    use std::str::FromStr;
225
226    #[test]
227    fn test_client_creation() {
228        let _client = ClobClient::new("https://test.example.com");
229        // Test that the client was created successfully
230        // We can't test private fields, but we can verify the client exists
231        // Client creation successful
232    }
233
234    #[test]
235    fn test_order_args_creation() {
236        let args = OrderArgs::new(
237            "test_token",
238            Decimal::from_str("0.75").unwrap(),
239            Decimal::from_str("100.0").unwrap(),
240            Side::BUY,
241        );
242
243        assert_eq!(args.token_id, "test_token");
244        assert_eq!(args.side, Side::BUY);
245    }
246
247    #[test]
248    fn test_order_args_default() {
249        let args = OrderArgs::default();
250        assert_eq!(args.token_id, "");
251        assert_eq!(args.price, Decimal::ZERO);
252        assert_eq!(args.size, Decimal::ZERO);
253        assert_eq!(args.side, Side::BUY);
254    }
255}