hyperliquid_sdk_rs/types/
requests.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4// ==================== Order Types ====================
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct OrderRequest {
9    #[serde(rename = "a")]
10    pub asset: u32,
11    #[serde(rename = "b")]
12    pub is_buy: bool,
13    #[serde(rename = "p")]
14    pub limit_px: String,
15    #[serde(rename = "s")]
16    pub sz: String,
17    #[serde(rename = "r", default)]
18    pub reduce_only: bool,
19    #[serde(rename = "t")]
20    pub order_type: OrderType,
21    #[serde(rename = "c", skip_serializing_if = "Option::is_none")]
22    pub cloid: Option<String>,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub enum OrderType {
28    Limit(Limit),
29    Trigger(Trigger),
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct Limit {
34    pub tif: String, // "Alo", "Ioc", "Gtc"
35}
36
37/// Trigger order type for stop-loss and take-profit orders.
38///
39/// **Important**: Field order matters for MessagePack serialization!
40/// The order must match the Hyperliquid Python SDK: isMarket, triggerPx, tpsl
41#[derive(Debug, Clone, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct Trigger {
44    #[serde(rename = "isMarket")]
45    pub is_market: bool,
46    #[serde(rename = "triggerPx")]
47    pub trigger_px: String,
48    pub tpsl: String, // "tp" or "sl"
49}
50
51// ==================== Cancel Types ====================
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct CancelRequest {
55    #[serde(rename = "a")]
56    pub asset: u32,
57    #[serde(rename = "o")]
58    pub oid: u64,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct CancelRequestCloid {
63    pub asset: u32,
64    pub cloid: String,
65}
66
67// ==================== Modify Types ====================
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct ModifyRequest {
71    pub oid: u64,
72    pub order: OrderRequest,
73}
74
75// ==================== Builder Types ====================
76
77#[derive(Debug, Clone, Default, Serialize, Deserialize)]
78#[serde(rename_all = "camelCase")]
79pub struct BuilderInfo {
80    #[serde(rename = "b")]
81    pub builder: String,
82    #[serde(rename = "f")]
83    pub fee: u64,
84}
85
86// ==================== Convenience Methods ====================
87
88impl OrderRequest {
89    /// Create a limit order
90    pub fn limit(
91        asset: u32,
92        is_buy: bool,
93        limit_px: impl Into<String>,
94        sz: impl Into<String>,
95        tif: impl Into<String>,
96    ) -> Self {
97        Self {
98            asset,
99            is_buy,
100            limit_px: limit_px.into(),
101            sz: sz.into(),
102            reduce_only: false,
103            order_type: OrderType::Limit(Limit { tif: tif.into() }),
104            cloid: None,
105        }
106    }
107
108    /// Create a trigger order (stop loss or take profit)
109    pub fn trigger(
110        asset: u32,
111        is_buy: bool,
112        trigger_px: impl Into<String>,
113        sz: impl Into<String>,
114        tpsl: impl Into<String>,
115        is_market: bool,
116    ) -> Self {
117        Self {
118            asset,
119            is_buy,
120            limit_px: "0".to_string(), // Triggers don't use limit_px
121            sz: sz.into(),
122            reduce_only: false,
123            order_type: OrderType::Trigger(Trigger {
124                is_market,
125                trigger_px: trigger_px.into(),
126                tpsl: tpsl.into(),
127            }),
128            cloid: None,
129        }
130    }
131
132    /// Set client order ID
133    pub fn with_cloid(mut self, cloid: Option<Uuid>) -> Self {
134        self.cloid = cloid.map(|id| format!("{:032x}", id.as_u128()));
135        self
136    }
137
138    /// Set reduce only
139    pub fn reduce_only(mut self, reduce_only: bool) -> Self {
140        self.reduce_only = reduce_only;
141        self
142    }
143}
144
145// Convenience constructors for Cancel types
146impl CancelRequest {
147    pub fn new(asset: u32, oid: u64) -> Self {
148        Self { asset, oid }
149    }
150}
151
152impl CancelRequestCloid {
153    pub fn new(asset: u32, cloid: Uuid) -> Self {
154        Self {
155            asset,
156            cloid: format!("{:032x}", cloid.as_u128()),
157        }
158    }
159}