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