polyte_clob/ws/
mod.rs

1//! WebSocket client for real-time Polymarket CLOB updates.
2//!
3//! This module provides WebSocket connectivity to Polymarket's real-time data streams,
4//! including market data (order book updates, price changes) and user-specific updates
5//! (orders, trades).
6//!
7//! # Channels
8//!
9//! Two channels are available:
10//!
11//! - **Market Channel**: Public channel for order book and price updates. Subscribe with
12//!   asset IDs (token IDs) to receive [`BookMessage`], [`PriceChangeMessage`],
13//!   [`TickSizeChangeMessage`], and [`LastTradePriceMessage`] updates.
14//!
15//! - **User Channel**: Authenticated channel for user order and trade updates. Subscribe
16//!   with market condition IDs and API credentials to receive [`OrderMessage`] and
17//!   [`TradeMessage`] updates.
18//!
19//! # Basic Example
20//!
21//! ```no_run
22//! use polyte_clob::ws::{WebSocket, Channel, MarketMessage};
23//! use futures_util::StreamExt;
24//!
25//! #[tokio::main]
26//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
27//!     // Connect to market channel (no auth required)
28//!     let mut ws = WebSocket::connect_market(vec![
29//!         "asset_id_1".to_string(),
30//!         "asset_id_2".to_string(),
31//!     ]).await?;
32//!
33//!     // Process incoming messages
34//!     while let Some(msg) = ws.next().await {
35//!         match msg? {
36//!             Channel::Market(MarketMessage::Book(book)) => {
37//!                 println!("Order book: {} bids, {} asks", book.bids.len(), book.asks.len());
38//!             }
39//!             Channel::Market(MarketMessage::PriceChange(pc)) => {
40//!                 println!("Price change: {:?}", pc.price_changes);
41//!             }
42//!             _ => {}
43//!         }
44//!     }
45//!
46//!     Ok(())
47//! }
48//! ```
49//!
50//! # Authenticated User Channel
51//!
52//! ```no_run
53//! use polyte_clob::ws::{ApiCredentials, WebSocket, Channel, UserMessage};
54//! use futures_util::StreamExt;
55//!
56//! #[tokio::main]
57//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
58//!     let credentials = ApiCredentials::from_env()?;
59//!
60//!     let mut ws = WebSocket::connect_user(
61//!         vec!["condition_id".to_string()],
62//!         credentials,
63//!     ).await?;
64//!
65//!     while let Some(msg) = ws.next().await {
66//!         match msg? {
67//!             Channel::User(UserMessage::Order(order)) => {
68//!                 println!("Order update: {} {:?}", order.id, order.order_type);
69//!             }
70//!             Channel::User(UserMessage::Trade(trade)) => {
71//!                 println!("Trade: {} @ {}", trade.size, trade.price);
72//!             }
73//!             _ => {}
74//!         }
75//!     }
76//!
77//!     Ok(())
78//! }
79//! ```
80//!
81//! # Auto-Ping with WebSocketBuilder
82//!
83//! For long-running connections, use [`WebSocketBuilder`] to automatically send
84//! keep-alive pings:
85//!
86//! ```no_run
87//! use polyte_clob::ws::{WebSocketBuilder, Channel};
88//! use std::time::Duration;
89//!
90//! #[tokio::main]
91//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
92//!     let ws = WebSocketBuilder::new()
93//!         .ping_interval(Duration::from_secs(10))
94//!         .connect_market(vec!["asset_id".to_string()])
95//!         .await?;
96//!
97//!     ws.run(|msg| async move {
98//!         println!("Received: {:?}", msg);
99//!         Ok(())
100//!     }).await?;
101//!
102//!     Ok(())
103//! }
104//! ```
105
106mod auth;
107mod client;
108mod error;
109mod market;
110mod subscription;
111mod user;
112
113pub use auth::ApiCredentials;
114pub use client::{WebSocket, WebSocketBuilder, WebSocketWithPing};
115pub use error::WebSocketError;
116pub use market::{
117    BookMessage, LastTradePriceMessage, MarketMessage, OrderSummary, PriceChange,
118    PriceChangeMessage, TickSizeChangeMessage,
119};
120pub use subscription::ChannelType;
121pub use user::{MakerOrder, OrderEventType, OrderMessage, TradeMessage, TradeStatus, UserMessage};
122
123/// All possible WebSocket channel messages
124#[derive(Debug, Clone)]
125pub enum Channel {
126    /// Market channel message
127    Market(MarketMessage),
128    /// User channel message
129    User(UserMessage),
130}