1use crate::Decimal;
2
3use crate::SignedOrderRequest;
4use alloy_primitives::U256;
5use serde::{Deserialize, Deserializer, Serialize};
6use std::fmt::Display;
7use std::str::FromStr;
8
9const ZERO_ADDRESS: &str = "0x0000000000000000000000000000000000000000";
10
11pub enum AssetType {
12 COLLATERAL,
13 CONDITIONAL,
14}
15
16#[allow(clippy::to_string_trait_impl)]
17impl ToString for AssetType {
18 fn to_string(&self) -> String {
19 match self {
20 AssetType::COLLATERAL => "COLLATERAL".to_string(),
21 AssetType::CONDITIONAL => "CONDITIONAL".to_string(),
22 }
23 }
24}
25
26#[derive(Default)]
27pub struct BalanceAllowanceParams {
28 pub asset_type: Option<AssetType>,
29 pub token_id: Option<String>,
30 pub signature_type: Option<u8>,
31}
32
33impl BalanceAllowanceParams {
34 pub fn to_query_params(&self) -> Vec<(&str, String)> {
35 let mut params = Vec::with_capacity(3);
36
37 if let Some(x) = &self.asset_type {
38 params.push(("asset_type", x.to_string()));
39 }
40
41 if let Some(x) = &self.token_id {
42 params.push(("token_id", x.to_string()));
43 }
44
45 if let Some(x) = &self.signature_type {
46 params.push(("signature_type", x.to_string()));
47 }
48 params
49 }
50}
51
52impl BalanceAllowanceParams {
53 pub fn set_signature_type(&mut self, s: u8) {
54 self.signature_type = Some(s);
55 }
56}
57
58#[derive(Debug)]
59pub struct TradeParams {
60 pub id: Option<String>,
61 pub maker_address: Option<String>,
62 pub market: Option<String>,
63 pub asset_id: Option<String>,
64 pub before: Option<u64>,
65 pub after: Option<u64>,
66}
67
68impl TradeParams {
69 pub fn to_query_params(&self) -> Vec<(&str, String)> {
70 let mut params = Vec::with_capacity(4);
71
72 if let Some(x) = &self.id {
73 params.push(("id", x.clone()));
74 }
75
76 if let Some(x) = &self.asset_id {
77 params.push(("asset_id", x.clone()));
78 }
79
80 if let Some(x) = &self.market {
81 params.push(("market", x.clone()));
82 }
83 if let Some(x) = &self.before {
84 params.push(("before", x.to_string()));
85 }
86 if let Some(x) = &self.after {
87 params.push(("after", x.to_string()));
88 }
89 params
90 }
91}
92
93#[derive(Debug, Deserialize)]
94pub struct OpenOrder {
95 pub associate_trades: Vec<String>,
96 pub id: String,
97 pub status: String,
98 pub market: String,
99
100 #[serde(with = "rust_decimal::serde::str")]
101 pub original_size: Decimal,
102 pub outcome: String,
103 pub maker_address: String,
104 pub owner: String,
105
106 #[serde(with = "rust_decimal::serde::str")]
107 pub price: Decimal,
108 pub side: Side,
109
110 #[serde(with = "rust_decimal::serde::str")]
111 pub size_matched: Decimal,
112 pub asset_id: String,
113 #[serde(deserialize_with = "deserialize_number_from_string")]
114 pub expiration: u64,
115 #[serde(rename = "type")]
116 pub order_type: OrderType,
117 #[serde(deserialize_with = "deserialize_number_from_string")]
118 pub created_at: u64,
119}
120
121#[derive(Debug)]
122pub struct OpenOrderParams {
123 pub id: Option<String>,
124 pub asset_id: Option<String>,
125 pub market: Option<String>,
126}
127
128impl OpenOrderParams {
129 pub fn to_query_params(&self) -> Vec<(&str, &String)> {
130 let mut params = Vec::with_capacity(4);
131
132 if let Some(x) = &self.id {
133 params.push(("id", x));
134 }
135
136 if let Some(x) = &self.asset_id {
137 params.push(("asset_id", x));
138 }
139
140 if let Some(x) = &self.market {
141 params.push(("market", x));
142 }
143 params
144 }
145}
146
147fn deserialize_number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
148where
149 D: Deserializer<'de>,
150 T: FromStr + serde::Deserialize<'de>,
151 <T as FromStr>::Err: Display,
152{
153 #[derive(Deserialize)]
154 #[serde(untagged)]
155 enum StringOrInt<T> {
156 String(String),
157 Number(T),
158 }
159
160 match StringOrInt::<T>::deserialize(deserializer)? {
161 StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
162 StringOrInt::Number(i) => Ok(i),
163 }
164}
165
166#[derive(Debug, Serialize)]
167#[serde(rename_all = "camelCase")]
168pub struct PostOrder {
169 order: SignedOrderRequest,
170 owner: String,
171 order_type: OrderType,
172}
173
174impl PostOrder {
175 pub fn new(order: SignedOrderRequest, owner: String, order_type: OrderType) -> Self {
176 PostOrder {
177 order,
178 owner,
179 order_type,
180 }
181 }
182}
183
184#[derive(Debug)]
185pub struct OrderArgs {
186 pub token_id: String,
187 pub price: Decimal,
188 pub size: Decimal,
189 pub side: Side,
190}
191
192#[derive(Debug, Deserialize)]
193pub struct OrderBookSummary {
194 pub market: String,
195 pub asset_id: String,
196 pub hash: String,
197 #[serde(deserialize_with = "deserialize_number_from_string")]
198 pub timestamp: u64,
199 pub bids: Vec<OrderSummary>,
200 pub asks: Vec<OrderSummary>,
201}
202
203#[derive(Debug)]
204pub struct MarketOrderArgs {
205 pub token_id: String,
206 pub amount: Decimal,
207}
208
209#[derive(Debug, Deserialize)]
210pub struct OrderSummary {
211 #[serde(with = "rust_decimal::serde::str")]
212 pub price: Decimal,
213 #[serde(with = "rust_decimal::serde::str")]
214 pub size: Decimal,
215}
216
217impl OrderArgs {
218 pub fn new(token_id: &str, price: Decimal, size: Decimal, side: Side) -> Self {
219 OrderArgs {
220 token_id: token_id.to_owned(),
221 price,
222 size,
223 side,
224 }
225 }
226}
227
228#[derive(Debug)]
229pub struct ExtraOrderArgs {
230 pub fee_rate_bps: u32,
231 pub nonce: U256,
232 pub taker: String,
233}
234
235impl Default for ExtraOrderArgs {
236 fn default() -> Self {
237 ExtraOrderArgs {
238 fee_rate_bps: 0,
239 nonce: U256::ZERO,
240 taker: ZERO_ADDRESS.into(),
241 }
242 }
243}
244
245#[derive(Debug, Default)]
246pub struct CreateOrderOptions {
247 pub tick_size: Option<Decimal>,
248 pub neg_risk: Option<bool>,
249}
250
251#[derive(Debug, Deserialize)]
252pub struct ApiKeysResponse {
253 #[serde(rename = "apiKeys")]
254 pub api_keys: Vec<String>,
255}
256
257#[derive(Debug, Deserialize, Serialize)]
258pub struct MidpointResponse {
259 #[serde(with = "rust_decimal::serde::str")]
260 pub mid: Decimal,
261}
262
263#[derive(Debug, Deserialize)]
264pub struct PriceResponse {
265 #[serde(with = "rust_decimal::serde::str")]
266 pub price: Decimal,
267}
268
269#[derive(Debug, Deserialize)]
270pub struct SpreadResponse {
271 #[serde(with = "rust_decimal::serde::str")]
272 pub spread: Decimal,
273}
274
275#[derive(Debug, Deserialize)]
276pub struct TickSizeResponse {
277 pub minimum_tick_size: Decimal,
278}
279
280#[derive(Debug, Deserialize)]
281pub struct NegRiskResponse {
282 pub neg_risk: bool,
283}
284
285#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, Eq, PartialEq)]
286pub enum OrderType {
287 GTC,
288 FOK,
289 GTD,
290}
291
292impl OrderType {
293 pub fn as_str(&self) -> &'static str {
294 match self {
295 OrderType::GTC => "GTC",
296 OrderType::FOK => "FOK",
297 OrderType::GTD => "GTD",
298 }
299 }
300}
301
302#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, Eq, PartialEq)]
303pub enum Side {
304 BUY = 0,
305 SELL = 1,
306}
307
308impl Side {
309 pub fn as_str(&self) -> &'static str {
310 match self {
311 Side::BUY => "BUY",
312 Side::SELL => "SELL",
313 }
314 }
315}
316
317#[derive(Debug, Serialize, Deserialize)]
318pub struct BookParams {
319 pub token_id: String,
320 pub side: Side,
321}
322
323#[derive(Default, Debug, Serialize, Deserialize)]
324pub struct ApiCreds {
325 #[serde(rename = "apiKey")]
326 pub api_key: String,
327 pub secret: String,
328 pub passphrase: String,
329}