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//! - **Comprehensive 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    Rewards,
121    Side,
122    SimplifiedMarket,
123    SimplifiedMarketsResponse,
124    SpreadResponse,
125    StreamMessage,
126    TickSizeResponse,
127    Token,
128    TokenPrice,
129    TradeParams,
130    WssAuth,
131    WssChannelType,
132    WssSubscription,
133};
134
135// Re-export client
136pub use crate::client::{ClobClient, PolyfillClient};
137
138// Re-export compatibility types (for easy migration from polymarket-rs-client)
139pub use crate::client::OrderArgs;
140
141// Re-export error types
142pub use crate::errors::{PolyfillError, Result};
143
144// Re-export advanced components
145pub use crate::book::{OrderBook as OrderBookImpl, OrderBookManager};
146pub use crate::decode::Decoder;
147pub use crate::fill::{FillEngine, FillResult};
148pub use crate::stream::{MarketStream, StreamManager, WebSocketStream};
149
150// Re-export utilities
151pub use crate::utils::{crypto, math, rate_limit, retry, time, url};
152
153// Module declarations
154pub mod auth;
155pub mod book;
156pub mod buffer_pool;
157pub mod client;
158pub mod connection_manager;
159pub mod decode;
160pub mod dns_cache;
161pub mod errors;
162pub mod fill;
163pub mod http_config;
164pub mod orders;
165pub mod stream;
166pub mod types;
167pub mod utils;
168
169// Benchmarks
170#[cfg(test)]
171mod benches {
172    use crate::{OrderBookManager, OrderDelta, Side};
173    use chrono::Utc;
174    use criterion::{criterion_group, criterion_main};
175    use rust_decimal::Decimal;
176    use std::str::FromStr;
177
178    #[allow(dead_code)]
179    fn order_book_benchmark(c: &mut criterion::Criterion) {
180        let book_manager = OrderBookManager::new(100);
181
182        c.bench_function("apply_order_delta", |b| {
183            b.iter(|| {
184                let delta = OrderDelta {
185                    token_id: "test_token".to_string(),
186                    timestamp: Utc::now(),
187                    side: Side::BUY,
188                    price: Decimal::from_str("0.75").unwrap(),
189                    size: Decimal::from_str("100.0").unwrap(),
190                    sequence: 1,
191                };
192
193                let _ = book_manager.apply_delta(delta);
194            });
195        });
196    }
197
198    criterion_group!(benches, order_book_benchmark);
199    criterion_main!(benches);
200}
201
202#[cfg(test)]
203mod tests {
204    use super::*;
205    use rust_decimal::Decimal;
206    use std::str::FromStr;
207
208    #[test]
209    fn test_client_creation() {
210        let _client = ClobClient::new("https://test.example.com");
211        // Test that the client was created successfully
212        // We can't test private fields, but we can verify the client exists
213        // Client creation successful
214    }
215
216    #[test]
217    fn test_order_args_creation() {
218        let args = OrderArgs::new(
219            "test_token",
220            Decimal::from_str("0.75").unwrap(),
221            Decimal::from_str("100.0").unwrap(),
222            Side::BUY,
223        );
224
225        assert_eq!(args.token_id, "test_token");
226        assert_eq!(args.side, Side::BUY);
227    }
228
229    #[test]
230    fn test_order_args_default() {
231        let args = OrderArgs::default();
232        assert_eq!(args.token_id, "");
233        assert_eq!(args.price, Decimal::ZERO);
234        assert_eq!(args.size, Decimal::ZERO);
235        assert_eq!(args.side, Side::BUY);
236    }
237}