mirror of
https://github.com/floor-licker/polyfill-rs.git
synced 2026-08-16 05:58:06 +00:00
fix: fix to wss subscription sigs
This commit is contained in:
+65
-41
@@ -160,12 +160,10 @@ impl WebSocketStream {
|
||||
}
|
||||
|
||||
// Send subscription message in the format expected by Polymarket
|
||||
let message = serde_json::json!({
|
||||
"auth": subscription.auth,
|
||||
"markets": subscription.markets,
|
||||
"asset_ids": subscription.asset_ids,
|
||||
"type": subscription.channel_type,
|
||||
});
|
||||
// The subscription struct will serialize correctly with proper field names
|
||||
let message = serde_json::to_value(&subscription).map_err(|e| {
|
||||
PolyfillError::parse(format!("Failed to serialize subscription: {}", e), None)
|
||||
})?;
|
||||
|
||||
self.send_message(message).await?;
|
||||
self.subscriptions.push(subscription.clone());
|
||||
@@ -183,17 +181,67 @@ impl WebSocketStream {
|
||||
.clone();
|
||||
|
||||
let subscription = WssSubscription {
|
||||
auth,
|
||||
markets: Some(markets),
|
||||
asset_ids: None,
|
||||
channel_type: "USER".to_string(),
|
||||
channel_type: "user".to_string(),
|
||||
operation: Some("subscribe".to_string()),
|
||||
markets,
|
||||
asset_ids: Vec::new(),
|
||||
initial_dump: Some(true),
|
||||
custom_feature_enabled: None,
|
||||
auth: Some(auth),
|
||||
};
|
||||
|
||||
self.subscribe_async(subscription).await
|
||||
}
|
||||
|
||||
/// Subscribe to market channel (order book and trades)
|
||||
/// Market subscriptions do not require authentication
|
||||
pub async fn subscribe_market_channel(&mut self, asset_ids: Vec<String>) -> Result<()> {
|
||||
let subscription = WssSubscription {
|
||||
channel_type: "market".to_string(),
|
||||
operation: Some("subscribe".to_string()),
|
||||
markets: Vec::new(),
|
||||
asset_ids,
|
||||
initial_dump: Some(true),
|
||||
custom_feature_enabled: None,
|
||||
auth: None,
|
||||
};
|
||||
|
||||
self.subscribe_async(subscription).await
|
||||
}
|
||||
|
||||
/// Subscribe to market channel with custom features enabled
|
||||
/// Custom features include: best_bid_ask, new_market, market_resolved events
|
||||
pub async fn subscribe_market_channel_with_features(&mut self, asset_ids: Vec<String>) -> Result<()> {
|
||||
let subscription = WssSubscription {
|
||||
channel_type: "market".to_string(),
|
||||
operation: Some("subscribe".to_string()),
|
||||
markets: Vec::new(),
|
||||
asset_ids,
|
||||
initial_dump: Some(true),
|
||||
custom_feature_enabled: Some(true),
|
||||
auth: None,
|
||||
};
|
||||
|
||||
self.subscribe_async(subscription).await
|
||||
}
|
||||
|
||||
/// Unsubscribe from market channel
|
||||
pub async fn unsubscribe_market_channel(&mut self, asset_ids: Vec<String>) -> Result<()> {
|
||||
let subscription = WssSubscription {
|
||||
channel_type: "market".to_string(),
|
||||
operation: Some("unsubscribe".to_string()),
|
||||
markets: Vec::new(),
|
||||
asset_ids,
|
||||
initial_dump: None,
|
||||
custom_feature_enabled: None,
|
||||
auth: None,
|
||||
};
|
||||
|
||||
self.subscribe_async(subscription).await
|
||||
}
|
||||
|
||||
/// Unsubscribe from user channel
|
||||
pub async fn unsubscribe_user_channel(&mut self, markets: Vec<String>) -> Result<()> {
|
||||
let auth = self
|
||||
.auth
|
||||
.as_ref()
|
||||
@@ -201,42 +249,18 @@ impl WebSocketStream {
|
||||
.clone();
|
||||
|
||||
let subscription = WssSubscription {
|
||||
auth,
|
||||
markets: None,
|
||||
asset_ids: Some(asset_ids),
|
||||
channel_type: "MARKET".to_string(),
|
||||
channel_type: "user".to_string(),
|
||||
operation: Some("unsubscribe".to_string()),
|
||||
markets,
|
||||
asset_ids: Vec::new(),
|
||||
initial_dump: None,
|
||||
custom_feature_enabled: None,
|
||||
auth: Some(auth),
|
||||
};
|
||||
|
||||
self.subscribe_async(subscription).await
|
||||
}
|
||||
|
||||
/// Unsubscribe from market data
|
||||
pub async fn unsubscribe_async(&mut self, token_ids: &[String]) -> Result<()> {
|
||||
// Note: Polymarket WebSocket API doesn't seem to have explicit unsubscribe
|
||||
// We'll just remove from our local subscriptions
|
||||
self.subscriptions
|
||||
.retain(|sub| match sub.channel_type.as_str() {
|
||||
"USER" => {
|
||||
if let Some(markets) = &sub.markets {
|
||||
!token_ids.iter().any(|id| markets.contains(id))
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
"MARKET" => {
|
||||
if let Some(asset_ids) = &sub.asset_ids {
|
||||
!token_ids.iter().any(|id| asset_ids.contains(id))
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
_ => true,
|
||||
});
|
||||
|
||||
info!("Unsubscribed from {} tokens", token_ids.len());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handle incoming WebSocket messages
|
||||
#[allow(dead_code)]
|
||||
async fn handle_message(
|
||||
|
||||
+20
-7
@@ -675,15 +675,28 @@ pub struct WssAuth {
|
||||
/// WebSocket subscription request
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WssSubscription {
|
||||
/// Authentication information
|
||||
pub auth: WssAuth,
|
||||
/// Array of markets (condition IDs) for USER channel
|
||||
pub markets: Option<Vec<String>>,
|
||||
/// Array of asset IDs (token IDs) for MARKET channel
|
||||
pub asset_ids: Option<Vec<String>>,
|
||||
/// Channel type: "USER" or "MARKET"
|
||||
/// Channel type: "market" or "user"
|
||||
#[serde(rename = "type")]
|
||||
pub channel_type: String,
|
||||
/// Operation type: "subscribe" or "unsubscribe"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub operation: Option<String>,
|
||||
/// Array of markets (condition IDs) for USER channel
|
||||
#[serde(default)]
|
||||
pub markets: Vec<String>,
|
||||
/// Array of asset IDs (token IDs) for MARKET channel
|
||||
/// Note: Field name is "assets_ids" (with 's') per Polymarket API spec
|
||||
#[serde(rename = "assets_ids", default)]
|
||||
pub asset_ids: Vec<String>,
|
||||
/// Request initial state dump
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub initial_dump: Option<bool>,
|
||||
/// Enable custom features (best_bid_ask, new_market, market_resolved)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub custom_feature_enabled: Option<bool>,
|
||||
/// Authentication information (only for USER channel)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub auth: Option<WssAuth>,
|
||||
}
|
||||
|
||||
/// WebSocket message types for streaming
|
||||
|
||||
Reference in New Issue
Block a user