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