From 9a6775c5583792d7b76a107f385e87765c4921ec Mon Sep 17 00:00:00 2001 From: tedison Date: Sat, 23 Nov 2024 14:25:55 -0500 Subject: [PATCH 01/10] make all crates public --- src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 37634203..0e21bde0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,16 @@ #![deny(unreachable_pub)] -mod consts; -mod errors; -mod exchange; -mod helpers; -mod info; -mod market_maker; -mod meta; -mod prelude; -mod proxy_digest; -mod req; -mod signature; -mod ws; +pub mod consts; +pub mod errors; +pub mod exchange; +pub mod helpers; +pub mod info; +pub mod market_maker; +pub mod meta; +pub mod prelude; +pub mod proxy_digest; +pub mod req; +pub mod signature; +pub mod ws; pub use consts::{EPSILON, LOCAL_API_URL, MAINNET_API_URL, TESTNET_API_URL}; pub use errors::Error; pub use exchange::*; From 66f64882cecdacd4bb00a6945e8edc223321fa7a Mon Sep 17 00:00:00 2001 From: tedison Date: Sun, 24 Nov 2024 17:47:22 -0500 Subject: [PATCH 02/10] qol --- src/exchange/exchange_client.rs | 1 + src/exchange/order.rs | 5 +++++ src/info/info_client.rs | 2 ++ src/info/sub_structs.rs | 2 +- src/meta.rs | 16 ++++++++++++++++ src/req.rs | 1 + src/ws/ws_manager.rs | 2 ++ 7 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/exchange/exchange_client.rs b/src/exchange/exchange_client.rs index c4562352..34cbc4e5 100644 --- a/src/exchange/exchange_client.rs +++ b/src/exchange/exchange_client.rs @@ -32,6 +32,7 @@ use super::cancel::ClientCancelRequestCloid; use super::order::{MarketCloseParams, MarketOrderParams}; use super::{ClientLimit, ClientOrder}; +#[derive(Debug, Clone)] pub struct ExchangeClient { pub http_client: HttpClient, pub wallet: LocalWallet, diff --git a/src/exchange/order.rs b/src/exchange/order.rs index a5c1bba9..f825c9e3 100644 --- a/src/exchange/order.rs +++ b/src/exchange/order.rs @@ -47,10 +47,12 @@ pub struct OrderRequest { pub cloid: Option, } +#[derive(Debug)] pub struct ClientLimit { pub tif: String, } +#[derive(Debug)] pub struct ClientTrigger { pub is_market: bool, pub trigger_px: f64, @@ -76,10 +78,13 @@ pub struct MarketCloseParams<'a> { pub wallet: Option<&'a LocalWallet>, } +#[derive(Debug)] pub enum ClientOrder { Limit(ClientLimit), Trigger(ClientTrigger), } + +#[derive(Debug)] pub struct ClientOrderRequest { pub asset: String, pub is_buy: bool, diff --git a/src/info/info_client.rs b/src/info/info_client.rs index 03974737..eda7044a 100644 --- a/src/info/info_client.rs +++ b/src/info/info_client.rs @@ -12,6 +12,7 @@ use crate::{ }; use ethers::types::H160; +use log::info; use reqwest::Client; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -86,6 +87,7 @@ pub enum InfoRequest { }, } +#[derive(Clone)] pub struct InfoClient { pub http_client: HttpClient, pub(crate) ws_manager: Option, diff --git a/src/info/sub_structs.rs b/src/info/sub_structs.rs index 578289ae..ad35e314 100644 --- a/src/info/sub_structs.rs +++ b/src/info/sub_structs.rs @@ -98,7 +98,7 @@ pub struct Vip { pub ntl_cutoff: String, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] pub struct UserTokenBalance { pub coin: String, pub hold: String, diff --git a/src/meta.rs b/src/meta.rs index 23e9fc51..2a596b02 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -52,6 +52,21 @@ pub enum SpotMetaAndAssetCtxs { Context(Vec), } +impl SpotMetaAndAssetCtxs { + pub fn get_spot_meta(&self) -> &SpotMeta { + match self { + SpotMetaAndAssetCtxs::SpotMeta(meta) => meta, + _ => panic!("Not a spot meta"), + } + } + pub fn get_context(&self) -> &Vec { + match self { + SpotMetaAndAssetCtxs::Context(ctxs) => ctxs, + _ => panic!("Not a context"), + } + } +} + #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct SpotAssetContext { @@ -88,4 +103,5 @@ pub struct TokenInfo { pub index: usize, pub token_id: H128, pub is_canonical: bool, + pub full_name: Option, } diff --git a/src/req.rs b/src/req.rs index 8d15be27..1ecd3fff 100644 --- a/src/req.rs +++ b/src/req.rs @@ -9,6 +9,7 @@ struct ErrorData { msg: String, } +#[derive(Debug, Clone)] pub struct HttpClient { pub client: Client, pub base_url: String, diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index b0cd498f..a259936f 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -36,6 +36,8 @@ struct SubscriptionData { subscription_id: u32, id: String, } + +#[derive(Clone)] pub(crate) struct WsManager { stop_flag: Arc, writer: Arc>, protocol::Message>>>, From e21519b4d95a4bfb89a9aa0f83b960d3cc55e77e Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 25 Nov 2024 17:36:40 -0500 Subject: [PATCH 03/10] remove unused import --- src/info/info_client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/info/info_client.rs b/src/info/info_client.rs index eda7044a..9b3b2928 100644 --- a/src/info/info_client.rs +++ b/src/info/info_client.rs @@ -12,7 +12,6 @@ use crate::{ }; use ethers::types::H160; -use log::info; use reqwest::Client; use serde::{Deserialize, Serialize}; use std::collections::HashMap; From fe1527dff4f56f4c2b2a820a8f1e54f8f487aefc Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 23 Dec 2024 10:41:14 +0100 Subject: [PATCH 04/10] serialize spot meta and context --- src/meta.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/meta.rs b/src/meta.rs index 2a596b02..040836da 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -1,14 +1,14 @@ use std::collections::HashMap; use ethers::abi::ethereum_types::H128; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; #[derive(Deserialize, Debug, Clone)] pub struct Meta { pub universe: Vec, } -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Serialize)] pub struct SpotMeta { pub universe: Vec, pub tokens: Vec, @@ -67,7 +67,7 @@ impl SpotMetaAndAssetCtxs { } } -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct SpotAssetContext { pub day_ntl_vlm: String, @@ -85,7 +85,7 @@ pub struct AssetMeta { pub sz_decimals: u32, } -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct SpotAssetMeta { pub tokens: [usize; 2], @@ -94,7 +94,7 @@ pub struct SpotAssetMeta { pub is_canonical: bool, } -#[derive(Debug, Deserialize, Clone)] +#[derive(Debug, Deserialize, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct TokenInfo { pub name: String, From 85676828f13869d0d284cc39eef33411350c5bdb Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 23 Dec 2024 11:08:06 +0100 Subject: [PATCH 05/10] add Active asset context to ws subscription --- src/ws/ws_manager.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index 2174ed0b..82e74800 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -61,6 +61,7 @@ pub enum Subscription { UserNonFundingLedgerUpdates { user: H160 }, Notification { user: H160 }, WebData2 { user: H160 }, + ActiveAssetCtx { coin: String }, } #[derive(Deserialize, Clone, Debug)] From f1d4513bb021b91e510ff77fdd9dccb96c279e7c Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 23 Dec 2024 11:47:37 +0100 Subject: [PATCH 06/10] fix message types --- src/ws/message_types.rs | 6 +++++ src/ws/sub_structs.rs | 52 +++++++++++++++++++++++++++++++++++++++++ src/ws/ws_manager.rs | 15 ++++++++++++ 3 files changed, 73 insertions(+) diff --git a/src/ws/message_types.rs b/src/ws/message_types.rs index ddb3ced8..4348435c 100644 --- a/src/ws/message_types.rs +++ b/src/ws/message_types.rs @@ -55,3 +55,9 @@ pub struct Notification { pub struct WebData2 { pub data: WebData2Data, } + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ActiveAssetCtx { + pub data: ActiveAssetCtxData, +} diff --git a/src/ws/sub_structs.rs b/src/ws/sub_structs.rs index 7414844c..4393aef2 100644 --- a/src/ws/sub_structs.rs +++ b/src/ws/sub_structs.rs @@ -279,3 +279,55 @@ pub struct NotificationData { pub struct WebData2Data { pub user: H160, } + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub enum ActiveAssetCtxData { + WsActiveAssetCtx(WsActiveAssetCtx), + WsActiveSpotAssetCtx(WsActiveSpotAssetCtx), +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct WsActiveAssetCtx { + pub coin: String, + pub ctx: PerpsAssetCtx, +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct WsActiveSpotAssetCtx { + pub coin: String, + pub ctx: SpotAssetCtx, +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SharedAssetCtx { + pub day_ntl_vlm: u64, + pub prev_day_px: u64, + pub mark_px: u64, + pub mid_px: Option, +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpsAssetCtx { + pub day_ntl_vlm: u64, + pub prev_day_px: u64, + pub mark_px: u64, + pub mid_px: Option, + pub funding: u64, + pub open_interest: u64, + pub oracle_px: u64, +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotAssetCtx { + pub day_ntl_vlm: u64, + pub prev_day_px: u64, + pub mark_px: u64, + pub mid_px: Option, + pub circulating_supply: u64, +} diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index 82e74800..dc3fbea8 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -30,6 +30,8 @@ use tokio_tungstenite::{ use ethers::types::H160; +use super::{ActiveAssetCtx, ActiveAssetCtxData}; + #[derive(Debug)] struct SubscriptionData { sending_channel: UnboundedSender, @@ -82,6 +84,7 @@ pub enum Message { UserNonFundingLedgerUpdates(UserNonFundingLedgerUpdates), Notification(Notification), WebData2(WebData2), + ActiveAssetCtx(ActiveAssetCtx), Pong, } @@ -263,6 +266,18 @@ impl WsManager { Message::SubscriptionResponse | Message::Pong => Ok(String::default()), Message::NoData => Ok("".to_string()), Message::HyperliquidError(err) => Ok(format!("hyperliquid error: {err:?}")), + Message::ActiveAssetCtx(active_asset_ctx) => { + let coin = match &active_asset_ctx.data { + ActiveAssetCtxData::WsActiveAssetCtx(active_asset_ctx) => { + active_asset_ctx.coin.clone() + } + ActiveAssetCtxData::WsActiveSpotAssetCtx(active_asset_ctx) => { + active_asset_ctx.coin.clone() + } + }; + serde_json::to_string(&Subscription::ActiveAssetCtx { coin }) + .map_err(|e| Error::JsonParse(e.to_string())) + } } } From b3dd1240b4b5dcd31855d973858a859d00df238d Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 23 Dec 2024 12:56:54 +0100 Subject: [PATCH 07/10] Fix active assets --- src/ws/sub_structs.rs | 56 ++++++++++--------------------------------- src/ws/ws_manager.rs | 16 ++++--------- 2 files changed, 18 insertions(+), 54 deletions(-) diff --git a/src/ws/sub_structs.rs b/src/ws/sub_structs.rs index 4393aef2..06e47f44 100644 --- a/src/ws/sub_structs.rs +++ b/src/ws/sub_structs.rs @@ -282,52 +282,22 @@ pub struct WebData2Data { #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] -pub enum ActiveAssetCtxData { - WsActiveAssetCtx(WsActiveAssetCtx), - WsActiveSpotAssetCtx(WsActiveSpotAssetCtx), -} - -#[derive(Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct WsActiveAssetCtx { - pub coin: String, - pub ctx: PerpsAssetCtx, -} - -#[derive(Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct WsActiveSpotAssetCtx { +pub struct ActiveAssetCtxData { pub coin: String, - pub ctx: SpotAssetCtx, -} - -#[derive(Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct SharedAssetCtx { - pub day_ntl_vlm: u64, - pub prev_day_px: u64, - pub mark_px: u64, - pub mid_px: Option, -} - -#[derive(Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct PerpsAssetCtx { - pub day_ntl_vlm: u64, - pub prev_day_px: u64, - pub mark_px: u64, - pub mid_px: Option, - pub funding: u64, - pub open_interest: u64, - pub oracle_px: u64, + pub ctx: AssetCtx, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] -pub struct SpotAssetCtx { - pub day_ntl_vlm: u64, - pub prev_day_px: u64, - pub mark_px: u64, - pub mid_px: Option, - pub circulating_supply: u64, +pub struct AssetCtx { + pub funding: String, + pub open_interest: String, + pub prev_day_px: String, + pub day_ntl_vlm: String, + pub premium: String, + pub oracle_px: String, + pub mark_px: String, + pub mid_px: String, + pub impact_pxs: Vec, + pub day_base_vlm: String, } diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index dc3fbea8..2250bc60 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -30,7 +30,7 @@ use tokio_tungstenite::{ use ethers::types::H160; -use super::{ActiveAssetCtx, ActiveAssetCtxData}; +use super::ActiveAssetCtx; #[derive(Debug)] struct SubscriptionData { @@ -267,16 +267,10 @@ impl WsManager { Message::NoData => Ok("".to_string()), Message::HyperliquidError(err) => Ok(format!("hyperliquid error: {err:?}")), Message::ActiveAssetCtx(active_asset_ctx) => { - let coin = match &active_asset_ctx.data { - ActiveAssetCtxData::WsActiveAssetCtx(active_asset_ctx) => { - active_asset_ctx.coin.clone() - } - ActiveAssetCtxData::WsActiveSpotAssetCtx(active_asset_ctx) => { - active_asset_ctx.coin.clone() - } - }; - serde_json::to_string(&Subscription::ActiveAssetCtx { coin }) - .map_err(|e| Error::JsonParse(e.to_string())) + serde_json::to_string(&Subscription::ActiveAssetCtx { + coin: active_asset_ctx.data.coin.clone(), + }) + .map_err(|e| Error::JsonParse(e.to_string())) } } } From 8438736aacbbe40b13555d6eaace8b942e2085f7 Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 23 Dec 2024 15:09:49 +0100 Subject: [PATCH 08/10] resubscription --- src/errors.rs | 2 ++ src/ws/message_types.rs | 5 +++++ src/ws/ws_manager.rs | 26 +++++++++++++++++--------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 00d56fb1..db525233 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -61,4 +61,6 @@ pub enum Error { SignatureFailure(String), #[error("Vault address not found")] VaultAddressNotFound, + #[error("Subscription error: {0:?}")] + SubscriptionError(String), } diff --git a/src/ws/message_types.rs b/src/ws/message_types.rs index 4348435c..b9868d63 100644 --- a/src/ws/message_types.rs +++ b/src/ws/message_types.rs @@ -1,6 +1,11 @@ use crate::ws::sub_structs::*; use serde::Deserialize; +#[derive(Deserialize, Clone, Debug)] +pub struct SubscriptionError { + pub data: String, +} + #[derive(Deserialize, Clone, Debug)] pub struct Trades { pub data: Vec, diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index 2250bc60..28905e1c 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -30,7 +30,7 @@ use tokio_tungstenite::{ use ethers::types::H160; -use super::ActiveAssetCtx; +use super::{ActiveAssetCtx, SubscriptionError}; #[derive(Debug)] struct SubscriptionData { @@ -85,6 +85,7 @@ pub enum Message { Notification(Notification), WebData2(WebData2), ActiveAssetCtx(ActiveAssetCtx), + Error(SubscriptionError), Pong, } @@ -272,6 +273,15 @@ impl WsManager { }) .map_err(|e| Error::JsonParse(e.to_string())) } + Message::Error(err) => { + let error_str = err.data.to_string(); + let identifier = error_str + .split("Invalid subscription ") + .nth(1) + .unwrap_or("Invalid subscription") + .to_string(); + Ok(identifier) + } } } @@ -285,8 +295,10 @@ impl WsManager { if !data.starts_with('{') { return Ok(()); } + let message = serde_json::from_str::(&data) .map_err(|e| Error::JsonParse(e.to_string()))?; + let identifier = WsManager::get_identifier(&message)?; if identifier.is_empty() { return Ok(()); @@ -387,15 +399,11 @@ impl WsManager { ) -> Result { let mut subscriptions = self.subscriptions.lock().await; - let identifier_entry = if let Subscription::UserEvents { user: _ } = - serde_json::from_str::(&identifier) - .map_err(|e| Error::JsonParse(e.to_string()))? - { + let subscription = serde_json::from_str::(&identifier) + .map_err(|e| Error::JsonParse(e.to_string()))?; + let identifier_entry = if let Subscription::UserEvents { user: _ } = subscription { "userEvents".to_string() - } else if let Subscription::OrderUpdates { user: _ } = - serde_json::from_str::(&identifier) - .map_err(|e| Error::JsonParse(e.to_string()))? - { + } else if let Subscription::OrderUpdates { user: _ } = subscription { "orderUpdates".to_string() } else { identifier.clone() From ae84716563b389adaff4b0c74a6138e40602ac3d Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 30 Dec 2024 14:06:56 +0100 Subject: [PATCH 09/10] fix some info and ws types --- src/info/sub_structs.rs | 3 +++ src/ws/sub_structs.rs | 39 +++++++++++++++++++++++++++++++-------- src/ws/ws_manager.rs | 9 ++++++++- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/info/sub_structs.rs b/src/info/sub_structs.rs index ad35e314..f659ed51 100644 --- a/src/info/sub_structs.rs +++ b/src/info/sub_structs.rs @@ -99,10 +99,13 @@ pub struct Vip { } #[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] pub struct UserTokenBalance { pub coin: String, pub hold: String, pub total: String, + pub token: u32, + pub entry_ntl: String, } #[derive(Deserialize, Clone, Debug)] diff --git a/src/ws/sub_structs.rs b/src/ws/sub_structs.rs index 06e47f44..f1749d9e 100644 --- a/src/ws/sub_structs.rs +++ b/src/ws/sub_structs.rs @@ -284,20 +284,43 @@ pub struct WebData2Data { #[serde(rename_all = "camelCase")] pub struct ActiveAssetCtxData { pub coin: String, - pub ctx: AssetCtx, + pub ctx: ActiveAssetCtxEnum, +} + +#[derive(Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum ActiveAssetCtxEnum { + Perps(PerpsAssetCtx), + Spot(SpotAssetCtx), +} +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpsAssetCtx { + pub day_ntl_vlm: u64, + pub prev_day_px: u64, + pub mark_px: u64, + pub mid_px: Option, + pub funding: u64, + pub open_interest: u64, + pub oracle_px: u64, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] -pub struct AssetCtx { - pub funding: String, - pub open_interest: String, - pub prev_day_px: String, +pub struct SpotAssetDetails { + #[serde(rename = "prevDayPx")] + pub prev_day_px: String, // Ensure this matches the JSON field exactly pub day_ntl_vlm: String, - pub premium: String, - pub oracle_px: String, pub mark_px: String, pub mid_px: String, - pub impact_pxs: Vec, + pub circulating_supply: String, + pub coin: String, + pub total_supply: String, pub day_base_vlm: String, } + +#[derive(Deserialize, Clone, Debug)] +pub struct SpotAssetCtx { + pub coin: String, + pub data: SpotAssetDetails, +} diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index 28905e1c..77919649 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -30,7 +30,7 @@ use tokio_tungstenite::{ use ethers::types::H160; -use super::{ActiveAssetCtx, SubscriptionError}; +use super::{ActiveAssetCtx, SpotAssetCtx, SubscriptionError}; #[derive(Debug)] struct SubscriptionData { @@ -85,6 +85,7 @@ pub enum Message { Notification(Notification), WebData2(WebData2), ActiveAssetCtx(ActiveAssetCtx), + ActiveSpotAssetCtx(SpotAssetCtx), Error(SubscriptionError), Pong, } @@ -273,6 +274,12 @@ impl WsManager { }) .map_err(|e| Error::JsonParse(e.to_string())) } + Message::ActiveSpotAssetCtx(active_spot_asset_ctx) => { + serde_json::to_string(&Subscription::ActiveAssetCtx { + coin: active_spot_asset_ctx.data.coin.clone(), + }) + .map_err(|e| Error::JsonParse(e.to_string())) + } Message::Error(err) => { let error_str = err.data.to_string(); let identifier = error_str From 4cd47f540fecd3b449b4b9fc30dd20b1074b54c3 Mon Sep 17 00:00:00 2001 From: tedison Date: Mon, 17 Feb 2025 15:58:32 -0500 Subject: [PATCH 10/10] Allow posting raw action --- src/exchange/exchange_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exchange/exchange_client.rs b/src/exchange/exchange_client.rs index 34cbc4e5..6719662b 100644 --- a/src/exchange/exchange_client.rs +++ b/src/exchange/exchange_client.rs @@ -124,7 +124,7 @@ impl ExchangeClient { }) } - async fn post( + pub async fn post( &self, action: serde_json::Value, signature: Signature,