Skip to content

Commit 98c0410

Browse files
Merge pull request #4 from austinzhang1018/ws-place-cancel
added ws place and cancel methods
2 parents 4abb2cb + 4cc2e7f commit 98c0410

File tree

3 files changed

+388
-0
lines changed

3 files changed

+388
-0
lines changed

src/exchange/exchange_client.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::{
1515
prelude::*,
1616
req::HttpClient,
1717
signature::sign_l1_action,
18+
ws::WsPostClient,
1819
BaseUrl, BulkCancelCloid, Error, ExchangeResponseStatus,
1920
};
2021
use crate::{ClassTransfer, SpotSend, SpotUser, VaultTransfer, Withdraw3};
@@ -39,6 +40,7 @@ pub struct ExchangeClient {
3940
pub meta: Meta,
4041
pub vault_address: Option<H160>,
4142
pub coin_to_asset: HashMap<String, u32>,
43+
pub ws_post_client: Option<WsPostClient>,
4244
}
4345

4446
#[derive(Serialize, Deserialize)]
@@ -122,6 +124,7 @@ impl ExchangeClient {
122124
base_url: base_url.get_url(),
123125
},
124126
coin_to_asset,
127+
ws_post_client: None,
125128
})
126129
}
127130

@@ -759,6 +762,75 @@ impl ExchangeClient {
759762
let signature = sign_l1_action(wallet, connection_id, is_mainnet)?;
760763
self.post(action, signature, timestamp).await
761764
}
765+
766+
/// Initialize WebSocket post client for faster order execution
767+
pub async fn init_ws_post_client(&mut self) -> Result<()> {
768+
let base_url = match self.http_client.base_url.as_str() {
769+
"https://api.hyperliquid.xyz" => BaseUrl::Mainnet,
770+
"https://api.hyperliquid-testnet.xyz" => BaseUrl::Testnet,
771+
_ => return Err(Error::GenericRequest("Invalid base URL".to_string())),
772+
};
773+
774+
self.ws_post_client = Some(WsPostClient::new(base_url).await?);
775+
Ok(())
776+
}
777+
778+
/// Execute bulk order via WebSocket for lower latency
779+
pub async fn bulk_order_ws(
780+
&self,
781+
orders: Vec<ClientOrderRequest>,
782+
wallet: Option<&LocalWallet>,
783+
) -> Result<ExchangeResponseStatus> {
784+
let ws_client = self.ws_post_client.as_ref()
785+
.ok_or_else(|| Error::GenericRequest("WebSocket client not initialized. Call init_ws_post_client() first.".to_string()))?;
786+
787+
let wallet = wallet.unwrap_or(&self.wallet);
788+
let mut transformed_orders = Vec::new();
789+
790+
for order in orders {
791+
transformed_orders.push(order.convert(&self.coin_to_asset)?);
792+
}
793+
794+
let action = BulkOrder {
795+
orders: transformed_orders,
796+
grouping: "na".to_string(),
797+
builder: None,
798+
};
799+
800+
let is_mainnet = self.http_client.is_mainnet();
801+
ws_client.bulk_order(action, wallet, is_mainnet, self.vault_address).await
802+
}
803+
804+
/// Execute bulk cancel by cloid via WebSocket for lower latency
805+
pub async fn bulk_cancel_by_cloid_ws(
806+
&self,
807+
cancels: Vec<ClientCancelRequestCloid>,
808+
wallet: Option<&LocalWallet>,
809+
) -> Result<ExchangeResponseStatus> {
810+
let ws_client = self.ws_post_client.as_ref()
811+
.ok_or_else(|| Error::GenericRequest("WebSocket client not initialized. Call init_ws_post_client() first.".to_string()))?;
812+
813+
let wallet = wallet.unwrap_or(&self.wallet);
814+
let mut transformed_cancels: Vec<CancelRequestCloid> = Vec::new();
815+
816+
for cancel in cancels.into_iter() {
817+
let &asset = self
818+
.coin_to_asset
819+
.get(&cancel.asset)
820+
.ok_or(Error::AssetNotFound)?;
821+
transformed_cancels.push(CancelRequestCloid {
822+
asset,
823+
cloid: uuid_to_hex_string(cancel.cloid),
824+
});
825+
}
826+
827+
let action = BulkCancelCloid {
828+
cancels: transformed_cancels,
829+
};
830+
831+
let is_mainnet = self.http_client.is_mainnet();
832+
ws_client.bulk_cancel_by_cloid(action, wallet, is_mainnet, self.vault_address).await
833+
}
762834
}
763835

764836
fn round_to_decimals(value: f64, decimals: u32) -> f64 {

src/ws/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
mod message_types;
22
mod sub_structs;
33
mod ws_manager;
4+
mod ws_post_client;
45
pub use message_types::*;
56
pub use sub_structs::*;
67
pub(crate) use ws_manager::WsManager;
78
pub use ws_manager::{Message, Subscription};
9+
pub use ws_post_client::WsPostClient;

0 commit comments

Comments
 (0)