1use eyre::{eyre, Result};
2use std::collections::HashMap;
3use std::str::FromStr;
4use std::sync::atomic::{AtomicU8, Ordering};
5use crate::bindings::querier::{
7 BookInfo, HealthInfo, PerpBalance, PerpProduct, ProductInfo, Risk, SpotBalance, SubaccountInfo,
8};
9use crate::eip712_structs::{
10 BurnNlp, Cancellation, CancellationProducts, LinkSigner, LiquidateSubaccount, MintNlp, Order,
11 TransferQuote, WithdrawCollateral, WithdrawCollateralV2,
12};
13use crate::product::Product;
14use crate::serialize_utils::{
15 deserialize_bytes20, deserialize_bytes32, deserialize_i128, deserialize_nested_vec_i128,
16 deserialize_option_bytes32, deserialize_option_i128, deserialize_option_vec_u8,
17 deserialize_u128, deserialize_u64, deserialize_u64_keyed_map, deserialize_vec_bytes32,
18 deserialize_vec_i128, deserialize_vec_u8, serialize_bytes20, serialize_bytes32, serialize_i128,
19 serialize_nested_vec_i128, serialize_option_bytes32, serialize_option_i128,
20 serialize_option_vec_u8, serialize_u128, serialize_u64, serialize_u64_keyed_map,
21 serialize_vec_bytes32, serialize_vec_i128, serialize_vec_u8, str_or_u32, WrappedI128,
22};
23use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
24use serde::{Deserialize, Serialize};
25#[derive(
28 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
29)]
30#[serde(rename_all = "snake_case")]
31#[archive(check_bytes)]
32pub enum Direction {
33 Long,
34 Short,
35}
36
37#[derive(Clone, Debug, Serialize, Deserialize)]
38pub struct ProductDelta {
39 pub product_id: u32,
40 #[serde(
41 serialize_with = "serialize_bytes32",
42 deserialize_with = "deserialize_bytes32"
43 )]
44 pub subaccount: [u8; 32],
45 #[serde(
46 serialize_with = "serialize_i128",
47 deserialize_with = "deserialize_i128"
48 )]
49 pub amount_delta: i128,
50 #[serde(
51 serialize_with = "serialize_i128",
52 deserialize_with = "deserialize_i128"
53 )]
54 pub v_quote_delta: i128,
55}
56
57#[derive(Clone, Debug, Serialize, Deserialize)]
58#[serde(rename_all = "snake_case")]
59pub enum Txn {
60 ApplyDelta(ProductDelta),
61}
62
63#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug, Clone)]
64#[archive(check_bytes)]
65#[serde(rename_all = "snake_case")]
66#[serde(tag = "type")]
67pub enum Query {
70 Status {},
71
72 Contracts {},
73
74 Nonces {
75 #[serde(
76 serialize_with = "serialize_bytes20",
77 deserialize_with = "deserialize_bytes20"
78 )]
79 address: [u8; 20],
80 },
81
82 LinkedSigner {
83 #[serde(
84 serialize_with = "serialize_bytes32",
85 deserialize_with = "deserialize_bytes32"
86 )]
87 subaccount: [u8; 32],
88 },
89
90 SubaccountInfo {
91 #[serde(
92 serialize_with = "serialize_bytes32",
93 deserialize_with = "deserialize_bytes32"
94 )]
95 subaccount: [u8; 32],
96 txns: Option<String>,
97 pre_state: Option<String>,
98 },
99
100 AllProducts {},
101
102 EdgeAllProducts {},
103
104 MarketPrice {
105 #[serde(deserialize_with = "str_or_u32")]
106 product_id: u32,
107 },
108
109 MarketPrices {
110 product_ids: Vec<u32>,
111 },
112
113 Order {
114 #[serde(deserialize_with = "str_or_u32")]
115 product_id: u32,
116 #[serde(
117 serialize_with = "serialize_bytes32",
118 deserialize_with = "deserialize_bytes32"
119 )]
120 digest: [u8; 32],
121 },
122
123 Orders {
124 #[serde(
126 serialize_with = "serialize_bytes32",
127 deserialize_with = "deserialize_bytes32"
128 )]
129 sender: [u8; 32],
130 product_ids: Vec<u32>,
131 },
132
133 ValidateOrder {
134 product_id: u32,
135 #[serde(
136 serialize_with = "serialize_vec_u8",
137 deserialize_with = "deserialize_vec_u8"
138 )]
139 order: Vec<u8>,
140 },
141
142 FeeRates {
143 #[serde(
144 serialize_with = "serialize_bytes32",
145 deserialize_with = "deserialize_bytes32"
146 )]
147 sender: [u8; 32],
148 },
149
150 SubaccountOrders {
151 #[serde(
153 serialize_with = "serialize_bytes32",
154 deserialize_with = "deserialize_bytes32"
155 )]
156 sender: [u8; 32],
157 #[serde(deserialize_with = "str_or_u32")]
158 product_id: u32,
159 },
160
161 MarketLiquidity {
162 #[serde(deserialize_with = "str_or_u32")]
163 product_id: u32,
164 #[serde(deserialize_with = "str_or_u32")]
165 depth: u32,
166 },
167
168 MaxOrderSize {
169 #[serde(
170 serialize_with = "serialize_bytes32",
171 deserialize_with = "deserialize_bytes32"
172 )]
173 sender: [u8; 32],
174 #[serde(deserialize_with = "str_or_u32")]
175 product_id: u32,
176 #[serde(
177 serialize_with = "serialize_i128",
178 deserialize_with = "deserialize_i128"
179 )]
180 price_x18: i128,
181 direction: Direction,
182 spot_leverage: Option<String>,
183 reduce_only: Option<String>,
184 isolated: Option<String>,
185 borrow_margin: Option<String>,
186 #[serde(
187 serialize_with = "serialize_option_i128",
188 deserialize_with = "deserialize_option_i128"
189 )]
190 #[serde(skip_serializing_if = "Option::is_none")]
191 #[serde(default)]
192 avg_price_x18: Option<i128>,
193 },
194
195 MaxWithdrawable {
196 #[serde(
197 serialize_with = "serialize_bytes32",
198 deserialize_with = "deserialize_bytes32"
199 )]
200 sender: [u8; 32],
201 #[serde(deserialize_with = "str_or_u32")]
202 product_id: u32,
203 spot_leverage: Option<String>,
204 },
205
206 MaxNlpMintable {
207 #[serde(
208 serialize_with = "serialize_bytes32",
209 deserialize_with = "deserialize_bytes32"
210 )]
211 sender: [u8; 32],
212 spot_leverage: Option<String>,
213 },
214
215 MaxNlpBurnable {
216 #[serde(
217 serialize_with = "serialize_bytes32",
218 deserialize_with = "deserialize_bytes32"
219 )]
220 sender: [u8; 32],
221 },
222
223 IsolatedPositions {
224 #[serde(
225 serialize_with = "serialize_bytes32",
226 deserialize_with = "deserialize_bytes32"
227 )]
228 subaccount: [u8; 32],
229 },
230
231 HealthGroups {},
232
233 Insurance {},
234
235 Versions {},
236
237 Symbols {
238 product_ids: Option<Vec<u32>>,
239 product_type: Option<String>,
240 },
241
242 NlpPoolInfo {},
243
244 NlpLockedBalances {
245 #[serde(
246 serialize_with = "serialize_bytes32",
247 deserialize_with = "deserialize_bytes32"
248 )]
249 subaccount: [u8; 32],
250 },
251}
252
253#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
254#[archive(check_bytes)]
255#[serde(rename_all = "snake_case")]
256pub struct PlaceOrder {
257 pub order: Order,
258 #[serde(
259 serialize_with = "serialize_vec_u8",
260 deserialize_with = "deserialize_vec_u8"
261 )]
262 pub signature: Vec<u8>,
263 pub product_id: u32,
264 #[serde(
265 serialize_with = "serialize_option_bytes32",
266 deserialize_with = "deserialize_option_bytes32"
267 )]
268 #[serde(default)]
269 pub digest: Option<[u8; 32]>,
270 #[serde(skip_serializing_if = "Option::is_none")]
272 #[serde(default)]
273 pub id: Option<u64>,
274 pub spot_leverage: Option<bool>,
275 pub borrow_margin: Option<bool>,
276}
277
278#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
279#[archive(check_bytes)]
280#[serde(rename_all = "snake_case")]
281pub struct MatchOrdersOtcLeg {
282 pub taker: PlaceOrder,
283 pub makers: Vec<PlaceOrder>,
284}
285
286#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
287#[archive(check_bytes)]
288#[serde(rename_all = "camelCase")]
289pub struct Artifact {
290 pub bytecode: String,
291 pub deployed_bytecode: String,
292}
293
294#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
295#[archive(check_bytes)]
296#[serde(rename_all = "snake_case")]
297pub enum Execute {
300 LiquidateSubaccount {
301 tx: LiquidateSubaccount,
302 #[serde(
303 serialize_with = "serialize_vec_u8",
304 deserialize_with = "deserialize_vec_u8"
305 )]
306 signature: Vec<u8>,
307 },
308 WithdrawCollateral {
309 tx: WithdrawCollateral,
310 #[serde(
311 serialize_with = "serialize_vec_u8",
312 deserialize_with = "deserialize_vec_u8"
313 )]
314 signature: Vec<u8>,
315 spot_leverage: Option<bool>,
316 sequencer_risk_check: Option<bool>,
317 },
318 WithdrawCollateralV2 {
319 tx: WithdrawCollateralV2,
320 #[serde(
321 serialize_with = "serialize_vec_u8",
322 deserialize_with = "deserialize_vec_u8"
323 )]
324 signature: Vec<u8>,
325 spot_leverage: Option<bool>,
326 sequencer_risk_check: Option<bool>,
327 },
328 PlaceOrder(PlaceOrder),
329 CancelOrders {
330 tx: Cancellation,
331 #[serde(
332 serialize_with = "serialize_vec_u8",
333 deserialize_with = "deserialize_vec_u8"
334 )]
335 signature: Vec<u8>,
336 #[serde(
337 serialize_with = "serialize_option_i128",
338 deserialize_with = "deserialize_option_i128"
339 )]
340 #[serde(skip_serializing_if = "Option::is_none")]
341 #[serde(default)]
342 required_unfilled_amount: Option<i128>,
343 #[serde(skip_serializing_if = "Option::is_none")]
344 #[serde(default)]
345 id: Option<u64>,
346 },
347 CancelProductOrders {
348 tx: CancellationProducts,
349 #[serde(
350 serialize_with = "serialize_vec_u8",
351 deserialize_with = "deserialize_vec_u8"
352 )]
353 signature: Vec<u8>,
354 #[serde(
355 serialize_with = "serialize_option_bytes32",
356 deserialize_with = "deserialize_option_bytes32"
357 )]
358 #[serde(default)]
359 digest: Option<[u8; 32]>,
360 #[serde(skip_serializing_if = "Option::is_none")]
361 #[serde(default)]
362 id: Option<u64>,
363 },
364 LinkSigner {
365 tx: LinkSigner,
366 #[serde(
367 serialize_with = "serialize_vec_u8",
368 deserialize_with = "deserialize_vec_u8"
369 )]
370 signature: Vec<u8>,
371 },
372 CancelAndPlace {
373 cancel_tx: Cancellation,
374 #[serde(
375 serialize_with = "serialize_vec_u8",
376 deserialize_with = "deserialize_vec_u8"
377 )]
378 cancel_signature: Vec<u8>,
379 place_order: PlaceOrder,
380 #[serde(default)]
381 place_requires_unfilled: Option<bool>,
382 #[serde(
383 serialize_with = "serialize_option_i128",
384 deserialize_with = "deserialize_option_i128"
385 )]
386 #[serde(skip_serializing_if = "Option::is_none")]
387 #[serde(default)]
388 required_unfilled_amount: Option<i128>,
389 },
390
391 TransferQuote {
392 tx: TransferQuote,
393 #[serde(
394 serialize_with = "serialize_vec_u8",
395 deserialize_with = "deserialize_vec_u8"
396 )]
397 signature: Vec<u8>,
398 },
399
400 MintNlp {
401 tx: MintNlp,
402 #[serde(
403 serialize_with = "serialize_vec_u8",
404 deserialize_with = "deserialize_vec_u8"
405 )]
406 signature: Vec<u8>,
407 spot_leverage: Option<bool>,
408 },
409 BurnNlp {
410 tx: BurnNlp,
411 #[serde(
412 serialize_with = "serialize_vec_u8",
413 deserialize_with = "deserialize_vec_u8"
414 )]
415 signature: Vec<u8>,
416 },
417}
418
419#[derive(
420 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
421)]
422#[archive(check_bytes)]
423pub struct TradingStatusUpdate {
424 pub product_id: u32,
425 pub trading_status: TradingStatus,
426}
427
428#[derive(
429 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
430)]
431#[archive(check_bytes)]
432pub struct OiCapUpdate {
433 pub product_id: u32,
434 #[serde(
435 serialize_with = "serialize_i128",
436 deserialize_with = "deserialize_i128"
437 )]
438 pub oi_cap_x18: i128,
439}
440
441#[derive(
442 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
443)]
444#[archive(check_bytes)]
445pub struct NlpSlippageUpdate {
446 pub product_id: u32,
447 #[serde(
448 serialize_with = "serialize_i128",
449 deserialize_with = "deserialize_i128"
450 )]
451 pub slippage_x18: i128,
452}
453
454#[derive(
455 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
456)]
457#[archive(check_bytes)]
458pub struct IsolatedOnlyUpdate {
459 pub product_id: u32,
460 pub isolated_only: bool,
461}
462
463#[derive(
464 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
465)]
466#[archive(check_bytes)]
467pub struct NlpLiquidationUpdate {
468 pub product_id: u32,
469 pub is_nlp_liquidation: bool,
470}
471
472#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug)]
473#[serde(untagged)]
474#[archive(check_bytes)]
475pub enum EngineMessage {
476 Query(Query),
477 Execute(Execute),
478}
479
480#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug)]
481#[archive(check_bytes)]
482pub struct LabeledEngineMessage {
483 pub chain_id: u64,
484 pub msg: EngineMessage,
485}
486
487#[derive(
488 Archive,
489 RkyvDeserialize,
490 RkyvSerialize,
491 Serialize,
492 Deserialize,
493 Clone,
494 Debug,
495 Default,
496 Eq,
497 PartialEq,
498)]
499#[archive(check_bytes)]
500pub struct Config {
501 #[serde(
502 serialize_with = "serialize_bytes20",
503 deserialize_with = "deserialize_bytes20"
504 )]
505 pub token: [u8; 20],
506 #[serde(
507 serialize_with = "serialize_i128",
508 deserialize_with = "deserialize_i128"
509 )]
510 pub interest_inflection_util_x18: i128,
511 #[serde(
512 serialize_with = "serialize_i128",
513 deserialize_with = "deserialize_i128"
514 )]
515 pub interest_floor_x18: i128,
516 #[serde(
517 serialize_with = "serialize_i128",
518 deserialize_with = "deserialize_i128"
519 )]
520 pub interest_small_cap_x18: i128,
521 #[serde(
522 serialize_with = "serialize_i128",
523 deserialize_with = "deserialize_i128"
524 )]
525 pub interest_large_cap_x18: i128,
526 #[serde(
527 serialize_with = "serialize_i128",
528 deserialize_with = "deserialize_i128"
529 )]
530 pub withdraw_fee_x18: i128,
531 #[serde(
532 serialize_with = "serialize_i128",
533 deserialize_with = "deserialize_i128"
534 )]
535 pub min_deposit_rate_x18: i128,
536}
537
538impl From<crate::bindings::querier::Config> for Config {
539 fn from(config: crate::bindings::querier::Config) -> Self {
540 Config {
541 token: config.token.into(),
542 interest_inflection_util_x18: config.interest_inflection_util_x18,
543 interest_floor_x18: config.interest_floor_x18,
544 interest_small_cap_x18: config.interest_small_cap_x18,
545 interest_large_cap_x18: config.interest_large_cap_x18,
546 withdraw_fee_x18: config.withdraw_fee_x18,
547 min_deposit_rate_x18: config.min_deposit_rate_x18,
548 }
549 }
550}
551
552#[derive(
553 Archive,
554 RkyvDeserialize,
555 RkyvSerialize,
556 Serialize,
557 Deserialize,
558 Clone,
559 Debug,
560 Default,
561 Eq,
562 PartialEq,
563)]
564#[archive(check_bytes)]
565pub struct SpotProduct {
566 pub product_id: u32,
567 #[serde(
568 serialize_with = "serialize_i128",
569 deserialize_with = "deserialize_i128"
570 )]
571 pub oracle_price_x18: i128,
572 pub risk: Risk,
573 pub config: Config,
574 pub state: crate::bindings::spot_engine::State,
575 pub book_info: BookInfo,
576}
577
578impl From<crate::bindings::querier::SpotProduct> for SpotProduct {
579 fn from(spot_product: crate::bindings::querier::SpotProduct) -> Self {
580 SpotProduct {
581 product_id: spot_product.product_id,
582 oracle_price_x18: spot_product.oracle_price_x18,
583 risk: spot_product.risk,
584 config: Config::from(spot_product.config),
585 state: spot_product.state,
586 book_info: spot_product.book_info,
587 }
588 }
589}
590
591#[derive(
592 Archive,
593 RkyvDeserialize,
594 RkyvSerialize,
595 Serialize,
596 Deserialize,
597 Clone,
598 Debug,
599 Default,
600 Eq,
601 PartialEq,
602)]
603#[archive(check_bytes)]
604pub struct AllProductsResponse {
605 pub spot_products: ::std::vec::Vec<SpotProduct>,
606 pub perp_products: ::std::vec::Vec<PerpProduct>,
607}
608
609impl From<ProductInfo> for AllProductsResponse {
610 fn from(product_info: ProductInfo) -> Self {
611 AllProductsResponse {
612 spot_products: product_info
613 .spot_products
614 .into_iter()
615 .map(SpotProduct::from)
616 .collect(),
617 perp_products: product_info.perp_products,
618 }
619 }
620}
621#[derive(
622 Archive,
623 RkyvDeserialize,
624 RkyvSerialize,
625 Serialize,
626 Deserialize,
627 Clone,
628 Debug,
629 Default,
630 Eq,
631 PartialEq,
632)]
633#[archive(check_bytes)]
634pub struct EdgeAllProductsResponse {
635 #[serde(
636 serialize_with = "serialize_u64_keyed_map",
637 deserialize_with = "deserialize_u64_keyed_map"
638 )]
639 pub edge_all_products: HashMap<u64, AllProductsResponse>,
640}
641
642#[derive(
643 Clone,
644 Debug,
645 Default,
646 Eq,
647 PartialEq,
648 Serialize,
649 Deserialize,
650 Archive,
651 RkyvSerialize,
652 RkyvDeserialize,
653)]
654#[archive(check_bytes)]
655pub struct PreState {
656 pub healths: ::std::vec::Vec<HealthInfo>,
657 #[serde(
658 serialize_with = "serialize_nested_vec_i128",
659 deserialize_with = "deserialize_nested_vec_i128"
660 )]
661 pub health_contributions: Vec<Vec<i128>>,
662 pub spot_balances: ::std::vec::Vec<SpotBalance>,
663 pub perp_balances: ::std::vec::Vec<PerpBalance>,
664}
665
666#[derive(
667 Clone,
668 Debug,
669 Default,
670 Eq,
671 PartialEq,
672 Serialize,
673 Deserialize,
674 Archive,
675 RkyvSerialize,
676 RkyvDeserialize,
677)]
678#[archive(check_bytes)]
679pub struct SubaccountInfoResponse {
680 #[serde(
681 serialize_with = "serialize_bytes32",
682 deserialize_with = "deserialize_bytes32"
683 )]
684 pub subaccount: [u8; 32],
685 pub exists: bool,
686 pub healths: ::std::vec::Vec<HealthInfo>,
687 #[serde(
688 serialize_with = "serialize_nested_vec_i128",
689 deserialize_with = "deserialize_nested_vec_i128"
690 )]
691 pub health_contributions: Vec<Vec<i128>>,
692 pub spot_count: u32,
693 pub perp_count: u32,
694 pub spot_balances: ::std::vec::Vec<SpotBalance>,
695 pub perp_balances: ::std::vec::Vec<PerpBalance>,
696 pub spot_products: ::std::vec::Vec<SpotProduct>,
697 pub perp_products: ::std::vec::Vec<PerpProduct>,
698 #[serde(skip_serializing_if = "Option::is_none")]
699 pub pre_state: Option<PreState>,
700}
701
702impl From<SubaccountInfo> for SubaccountInfoResponse {
703 fn from(subaccount_info: SubaccountInfo) -> Self {
704 SubaccountInfoResponse {
705 subaccount: subaccount_info.subaccount,
706 exists: subaccount_info.exists,
707 healths: subaccount_info.healths,
708 health_contributions: subaccount_info.health_contributions,
709 spot_count: subaccount_info.spot_count,
710 perp_count: subaccount_info.perp_count,
711 spot_balances: subaccount_info.spot_balances,
712 perp_balances: subaccount_info.perp_balances,
713 spot_products: subaccount_info
714 .spot_products
715 .into_iter()
716 .map(SpotProduct::from)
717 .collect(),
718 perp_products: subaccount_info.perp_products,
719 pre_state: None,
720 }
721 }
722}
723
724impl SubaccountInfoResponse {
725 pub fn from_with_pre_state(
726 subaccount_info: SubaccountInfo,
727 pre_state: Option<PreState>,
728 ) -> Self {
729 let mut resp = SubaccountInfoResponse::from(subaccount_info);
730 resp.pre_state = pre_state;
731 resp
732 }
733}
734
735#[derive(
736 Clone,
737 Debug,
738 Default,
739 Eq,
740 PartialEq,
741 Serialize,
742 Deserialize,
743 Archive,
744 RkyvSerialize,
745 RkyvDeserialize,
746)]
747#[archive(check_bytes)]
748pub struct ContractsResponse {
749 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
750 pub chain_id: u64,
753 #[serde(
754 serialize_with = "serialize_bytes20",
755 deserialize_with = "deserialize_bytes20"
756 )]
757 pub endpoint_addr: [u8; 20],
758}
759
760#[derive(
761 Clone,
762 Debug,
763 Default,
764 Eq,
765 PartialEq,
766 Serialize,
767 Deserialize,
768 Archive,
769 RkyvSerialize,
770 RkyvDeserialize,
771)]
772#[archive(check_bytes)]
773pub struct NoncesResponse {
774 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
775 pub tx_nonce: u64,
776 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
777 pub order_nonce: u64,
778}
779
780#[derive(
781 Clone,
782 Debug,
783 Default,
784 Eq,
785 PartialEq,
786 Serialize,
787 Deserialize,
788 Archive,
789 RkyvSerialize,
790 RkyvDeserialize,
791)]
792#[archive(check_bytes)]
793pub struct LinkedSignerResponse {
794 #[serde(
795 serialize_with = "serialize_bytes20",
796 deserialize_with = "deserialize_bytes20"
797 )]
798 pub linked_signer: [u8; 20],
799}
800
801#[derive(
802 Clone,
803 Debug,
804 Default,
805 Eq,
806 PartialEq,
807 Serialize,
808 Deserialize,
809 Archive,
810 RkyvSerialize,
811 RkyvDeserialize,
812)]
813#[archive(check_bytes)]
814pub struct MarketPriceResponse {
817 pub product_id: u32,
818 #[serde(
819 serialize_with = "serialize_i128",
820 deserialize_with = "deserialize_i128"
821 )]
822 pub bid_x18: i128,
824 #[serde(
825 serialize_with = "serialize_i128",
826 deserialize_with = "deserialize_i128"
827 )]
828 pub ask_x18: i128,
830}
831
832#[derive(
833 Clone,
834 Debug,
835 Default,
836 Eq,
837 PartialEq,
838 Serialize,
839 Deserialize,
840 Archive,
841 RkyvSerialize,
842 RkyvDeserialize,
843)]
844#[archive(check_bytes)]
845pub struct MarketPricesResponse {
848 pub market_prices: Vec<MarketPriceResponse>,
849}
850
851#[derive(
852 Clone,
853 Debug,
854 Default,
855 Eq,
856 PartialEq,
857 Serialize,
858 Deserialize,
859 Archive,
860 RkyvSerialize,
861 RkyvDeserialize,
862)]
863#[archive(check_bytes)]
864pub struct OrderResponse {
867 pub product_id: u32,
868 #[serde(
870 serialize_with = "serialize_bytes32",
871 deserialize_with = "deserialize_bytes32"
872 )]
873 pub sender: [u8; 32],
874 #[serde(
875 serialize_with = "serialize_i128",
876 deserialize_with = "deserialize_i128"
877 )]
878 pub price_x18: i128,
880 #[serde(
881 serialize_with = "serialize_i128",
882 deserialize_with = "deserialize_i128"
883 )]
884 pub amount: i128,
886 pub expiration: String,
887 pub order_type: String,
888 pub nonce: String,
889 #[serde(
890 serialize_with = "serialize_u128",
891 deserialize_with = "deserialize_u128"
892 )]
893 pub appendix: u128,
895 #[serde(
896 serialize_with = "serialize_i128",
897 deserialize_with = "deserialize_i128"
898 )]
899 pub unfilled_amount: i128,
901 #[serde(
902 serialize_with = "serialize_bytes32",
903 deserialize_with = "deserialize_bytes32"
904 )]
905 pub digest: [u8; 32],
906 pub placed_at: u64,
907 #[serde(skip_serializing_if = "Option::is_none")]
908 pub id: Option<u64>,
909}
910
911#[derive(
912 Clone,
913 Debug,
914 Default,
915 Eq,
916 PartialEq,
917 Serialize,
918 Deserialize,
919 Archive,
920 RkyvSerialize,
921 RkyvDeserialize,
922)]
923#[archive(check_bytes)]
924pub struct ValidateOrderResponse {
927 pub product_id: u32,
928 #[serde(
929 serialize_with = "serialize_vec_u8",
930 deserialize_with = "deserialize_vec_u8"
931 )]
932 pub order: Vec<u8>,
933 pub valid: bool,
934}
935
936#[derive(
937 Clone,
938 Debug,
939 Default,
940 Eq,
941 PartialEq,
942 Serialize,
943 Deserialize,
944 Archive,
945 RkyvSerialize,
946 RkyvDeserialize,
947)]
948#[archive(check_bytes)]
949pub struct FeeRatesResponse {
952 #[serde(
953 serialize_with = "serialize_vec_i128",
954 deserialize_with = "deserialize_vec_i128"
955 )]
956 pub taker_fee_rates_x18: Vec<i128>,
957 #[serde(
958 serialize_with = "serialize_vec_i128",
959 deserialize_with = "deserialize_vec_i128"
960 )]
961 pub maker_fee_rates_x18: Vec<i128>,
962 #[serde(
963 serialize_with = "serialize_i128",
964 deserialize_with = "deserialize_i128"
965 )]
966 pub liquidation_sequencer_fee: i128,
967 #[serde(
968 serialize_with = "serialize_i128",
969 deserialize_with = "deserialize_i128"
970 )]
971 pub health_check_sequencer_fee: i128,
972 #[serde(
973 serialize_with = "serialize_i128",
974 deserialize_with = "deserialize_i128"
975 )]
976 pub taker_sequencer_fee: i128,
977 #[serde(
978 serialize_with = "serialize_vec_i128",
979 deserialize_with = "deserialize_vec_i128"
980 )]
981 pub withdraw_sequencer_fees: Vec<i128>,
982 pub fee_tier: u32,
983}
984
985#[derive(
986 Clone,
987 Debug,
988 Default,
989 Eq,
990 PartialEq,
991 Serialize,
992 Deserialize,
993 Archive,
994 RkyvSerialize,
995 RkyvDeserialize,
996)]
997#[archive(check_bytes)]
998pub struct SubaccountOrdersResponse {
1001 #[serde(
1002 serialize_with = "serialize_bytes32",
1003 deserialize_with = "deserialize_bytes32"
1004 )]
1005 pub sender: [u8; 32],
1006 pub product_id: u32,
1007 pub orders: Vec<OrderResponse>,
1008}
1009
1010#[derive(
1011 Clone,
1012 Debug,
1013 Default,
1014 Eq,
1015 PartialEq,
1016 Serialize,
1017 Deserialize,
1018 Archive,
1019 RkyvSerialize,
1020 RkyvDeserialize,
1021)]
1022#[archive(check_bytes)]
1023pub struct ProductOrdersResponse {
1026 pub product_id: u32,
1027 pub orders: Vec<OrderResponse>,
1028}
1029
1030#[derive(
1031 Clone,
1032 Debug,
1033 Default,
1034 Eq,
1035 PartialEq,
1036 Serialize,
1037 Deserialize,
1038 Archive,
1039 RkyvSerialize,
1040 RkyvDeserialize,
1041)]
1042#[archive(check_bytes)]
1043pub struct OrdersResponse {
1046 #[serde(
1047 serialize_with = "serialize_bytes32",
1048 deserialize_with = "deserialize_bytes32"
1049 )]
1050 pub sender: [u8; 32],
1051 pub product_orders: Vec<ProductOrdersResponse>,
1052}
1053
1054#[derive(
1055 Clone,
1056 Debug,
1057 Default,
1058 Eq,
1059 PartialEq,
1060 Serialize,
1061 Deserialize,
1062 Archive,
1063 RkyvSerialize,
1064 RkyvDeserialize,
1065)]
1066#[archive(check_bytes)]
1067pub struct MaxOrderSizeResponse {
1070 #[serde(
1072 serialize_with = "serialize_i128",
1073 deserialize_with = "deserialize_i128"
1074 )]
1075 pub max_order_size: i128,
1076}
1077
1078#[derive(
1079 Clone,
1080 Debug,
1081 Default,
1082 Eq,
1083 PartialEq,
1084 Serialize,
1085 Deserialize,
1086 Archive,
1087 RkyvSerialize,
1088 RkyvDeserialize,
1089)]
1090#[archive(check_bytes)]
1091pub struct MaxWithdrawableResponse {
1094 #[serde(
1096 serialize_with = "serialize_i128",
1097 deserialize_with = "deserialize_i128"
1098 )]
1099 pub max_withdrawable: i128,
1100}
1101
1102#[derive(
1103 Clone,
1104 Debug,
1105 Default,
1106 Eq,
1107 PartialEq,
1108 Serialize,
1109 Deserialize,
1110 Archive,
1111 RkyvSerialize,
1112 RkyvDeserialize,
1113)]
1114#[archive(check_bytes)]
1115pub struct MaxNlpMintableResponse {
1118 #[serde(
1120 serialize_with = "serialize_i128",
1121 deserialize_with = "deserialize_i128"
1122 )]
1123 pub max_quote_amount: i128,
1124}
1125
1126#[derive(
1127 Clone,
1128 Debug,
1129 Default,
1130 Eq,
1131 PartialEq,
1132 Serialize,
1133 Deserialize,
1134 Archive,
1135 RkyvSerialize,
1136 RkyvDeserialize,
1137)]
1138#[archive(check_bytes)]
1139pub struct MaxNlpBurnableResponse {
1142 #[serde(
1144 serialize_with = "serialize_i128",
1145 deserialize_with = "deserialize_i128"
1146 )]
1147 pub max_nlp_amount: i128,
1148}
1149
1150#[derive(
1151 Clone,
1152 Debug,
1153 Default,
1154 Eq,
1155 PartialEq,
1156 Serialize,
1157 Deserialize,
1158 Archive,
1159 RkyvSerialize,
1160 RkyvDeserialize,
1161)]
1162#[archive(check_bytes)]
1163pub struct HealthGroupsResponse {
1166 pub health_groups: Vec<(u32, u32)>,
1168}
1169
1170#[derive(
1171 Clone,
1172 Debug,
1173 Default,
1174 Eq,
1175 PartialEq,
1176 Serialize,
1177 Deserialize,
1178 Archive,
1179 RkyvSerialize,
1180 RkyvDeserialize,
1181)]
1182#[archive(check_bytes)]
1183pub struct InsuranceResponse {
1186 #[serde(
1188 serialize_with = "serialize_i128",
1189 deserialize_with = "deserialize_i128"
1190 )]
1191 pub insurance: i128,
1192}
1193
1194#[derive(
1195 Clone,
1196 Debug,
1197 Default,
1198 Eq,
1199 PartialEq,
1200 Serialize,
1201 Deserialize,
1202 Archive,
1203 RkyvSerialize,
1204 RkyvDeserialize,
1205)]
1206#[archive(check_bytes)]
1207pub struct SymbolsResponse {
1208 pub symbols: HashMap<String, SymbolsResponseData>,
1209}
1210
1211#[derive(
1212 Clone,
1213 Debug,
1214 Default,
1215 Eq,
1216 PartialEq,
1217 Serialize,
1218 Deserialize,
1219 Archive,
1220 RkyvSerialize,
1221 RkyvDeserialize,
1222)]
1223#[archive(check_bytes)]
1224pub struct NlpPool {
1225 pub pool_id: u64,
1226 #[serde(
1227 serialize_with = "serialize_bytes32",
1228 deserialize_with = "deserialize_bytes32"
1229 )]
1230 pub subaccount: [u8; 32],
1231 #[serde(
1232 serialize_with = "serialize_bytes20",
1233 deserialize_with = "deserialize_bytes20"
1234 )]
1235 pub owner: [u8; 20],
1236 #[serde(
1237 serialize_with = "serialize_u128",
1238 deserialize_with = "deserialize_u128"
1239 )]
1240 pub balance_weight_x18: u128,
1241 pub subaccount_info: SubaccountInfoResponse,
1242 pub open_orders: Vec<OrderResponse>,
1243}
1244
1245#[derive(
1246 Clone,
1247 Debug,
1248 Default,
1249 Eq,
1250 PartialEq,
1251 Serialize,
1252 Deserialize,
1253 Archive,
1254 RkyvSerialize,
1255 RkyvDeserialize,
1256)]
1257#[archive(check_bytes)]
1258pub struct NlpPoolInfoResponse {
1259 pub nlp_pools: Vec<NlpPool>,
1260}
1261
1262#[derive(
1263 Clone,
1264 Debug,
1265 Default,
1266 Eq,
1267 PartialEq,
1268 Serialize,
1269 Deserialize,
1270 Archive,
1271 RkyvSerialize,
1272 RkyvDeserialize,
1273)]
1274#[archive(check_bytes)]
1275pub struct NlpLockedBalance {
1276 pub balance: SpotBalance,
1277 pub unlocked_at: u64,
1278}
1279
1280#[derive(
1281 Clone,
1282 Debug,
1283 Default,
1284 Eq,
1285 PartialEq,
1286 Serialize,
1287 Deserialize,
1288 Archive,
1289 RkyvSerialize,
1290 RkyvDeserialize,
1291)]
1292#[archive(check_bytes)]
1293pub struct NlpLockedBalancesResponse {
1294 pub balance_locked: SpotBalance,
1295 pub balance_unlocked: SpotBalance,
1296 pub locked_balances: Vec<NlpLockedBalance>,
1297}
1298
1299#[derive(
1300 Clone,
1301 Debug,
1302 Default,
1303 Eq,
1304 PartialEq,
1305 Serialize,
1306 Deserialize,
1307 Archive,
1308 RkyvSerialize,
1309 RkyvDeserialize,
1310)]
1311#[archive(check_bytes)]
1312pub struct SymbolsResponseData {
1313 #[serde(rename = "type")]
1314 pub product_type: String,
1315 pub product_id: u32,
1316 pub symbol: String,
1317 #[serde(
1318 serialize_with = "serialize_i128",
1319 deserialize_with = "deserialize_i128"
1320 )]
1321 pub price_increment_x18: i128,
1322 #[serde(
1323 serialize_with = "serialize_i128",
1324 deserialize_with = "deserialize_i128"
1325 )]
1326 pub size_increment: i128,
1327 #[serde(
1328 serialize_with = "serialize_i128",
1329 deserialize_with = "deserialize_i128"
1330 )]
1331 pub min_size: i128,
1332 #[serde(
1333 serialize_with = "serialize_i128",
1334 deserialize_with = "deserialize_i128"
1335 )]
1336 pub maker_fee_rate_x18: i128,
1337 #[serde(
1338 serialize_with = "serialize_i128",
1339 deserialize_with = "deserialize_i128"
1340 )]
1341 pub taker_fee_rate_x18: i128,
1342 #[serde(
1343 serialize_with = "serialize_i128",
1344 deserialize_with = "deserialize_i128"
1345 )]
1346 pub long_weight_initial_x18: i128,
1347 #[serde(
1348 serialize_with = "serialize_i128",
1349 deserialize_with = "deserialize_i128"
1350 )]
1351 pub long_weight_maintenance_x18: i128,
1352 pub max_open_interest_x18: Option<WrappedI128>,
1353 #[serde(default)]
1354 pub trading_status: TradingStatus,
1355 #[serde(default)]
1356 pub isolated_only: bool,
1357}
1358
1359impl SymbolsResponseData {
1360 pub fn placeholder() -> Self {
1361 Self {
1362 product_type: "placeholder".to_string(),
1363 ..Self::default()
1364 }
1365 }
1366}
1367
1368impl From<&Product> for SymbolsResponseData {
1369 fn from(product: &Product) -> Self {
1370 let product_type = match product {
1371 Product::Spot { .. } => "spot",
1372 Product::Perp { .. } => "perp",
1373 }
1374 .to_string();
1375 let max_open_interest = product.max_open_interest().and_then(|oi| {
1376 if oi == 0 {
1377 None
1378 } else {
1379 Some(WrappedI128(oi))
1380 }
1381 });
1382
1383 match product {
1384 Product::Spot {
1385 symbol,
1386 long_weight_initial_x18,
1387 long_weight_maintenance_x18,
1388 size_increment_x18,
1389 price_increment_x18,
1390 min_size_x18,
1391 product_id,
1392 ..
1393 }
1394 | Product::Perp {
1395 symbol,
1396 long_weight_initial_x18,
1397 long_weight_maintenance_x18,
1398 size_increment_x18,
1399 price_increment_x18,
1400 min_size_x18,
1401 product_id,
1402 ..
1403 } => SymbolsResponseData {
1404 product_type,
1405 product_id: *product_id,
1406 symbol: symbol.clone(),
1407 price_increment_x18: *price_increment_x18,
1408 min_size: *min_size_x18,
1409 size_increment: *size_increment_x18,
1410 long_weight_initial_x18: *long_weight_initial_x18,
1411 long_weight_maintenance_x18: *long_weight_maintenance_x18,
1412 max_open_interest_x18: max_open_interest,
1413 ..Self::default()
1414 },
1415 }
1416 }
1417}
1418
1419#[derive(
1420 Clone,
1421 Debug,
1422 Default,
1423 Eq,
1424 PartialEq,
1425 Serialize,
1426 Deserialize,
1427 Archive,
1428 RkyvSerialize,
1429 RkyvDeserialize,
1430)]
1431#[archive(check_bytes)]
1432pub struct IsolatedPosition {
1433 #[serde(
1434 serialize_with = "serialize_bytes32",
1435 deserialize_with = "deserialize_bytes32"
1436 )]
1437 pub subaccount: [u8; 32],
1438 pub quote_balance: SpotBalance,
1439 pub base_balance: PerpBalance,
1440 pub quote_product: SpotProduct,
1441 pub base_product: PerpProduct,
1442 #[serde(
1443 serialize_with = "serialize_vec_i128",
1444 deserialize_with = "deserialize_vec_i128"
1445 )]
1446 pub quote_healths: Vec<i128>,
1447 #[serde(
1448 serialize_with = "serialize_vec_i128",
1449 deserialize_with = "deserialize_vec_i128"
1450 )]
1451 pub base_healths: Vec<i128>,
1452 pub healths: Vec<HealthInfo>,
1453}
1454
1455#[derive(
1456 Clone,
1457 Debug,
1458 Default,
1459 Eq,
1460 PartialEq,
1461 Serialize,
1462 Deserialize,
1463 Archive,
1464 RkyvSerialize,
1465 RkyvDeserialize,
1466)]
1467#[archive(check_bytes)]
1468pub struct IsolatedPositionsResponse {
1469 pub isolated_positions: Vec<IsolatedPosition>,
1470}
1471
1472#[derive(
1473 Clone,
1474 Debug,
1475 Default,
1476 Eq,
1477 PartialEq,
1478 Serialize,
1479 Deserialize,
1480 Archive,
1481 RkyvSerialize,
1482 RkyvDeserialize,
1483)]
1484#[archive(check_bytes)]
1485pub struct PriceLevel(
1488 #[serde(
1489 serialize_with = "serialize_i128",
1490 deserialize_with = "deserialize_i128"
1491 )]
1492 pub i128,
1494 #[serde(
1495 serialize_with = "serialize_i128",
1496 deserialize_with = "deserialize_i128"
1497 )]
1498 pub i128,
1500);
1501
1502#[derive(
1503 Clone,
1504 Debug,
1505 Default,
1506 Eq,
1507 PartialEq,
1508 Serialize,
1509 Deserialize,
1510 Archive,
1511 RkyvSerialize,
1512 RkyvDeserialize,
1513)]
1514#[archive(check_bytes)]
1515pub struct MarketLiquidityResponse {
1518 pub bids: Vec<PriceLevel>,
1519 pub asks: Vec<PriceLevel>,
1520 pub product_id: u32,
1521 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
1522 pub timestamp: u64,
1523}
1524
1525#[derive(
1526 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1527)]
1528#[archive(check_bytes)]
1529#[serde(rename_all = "snake_case")]
1532pub enum Status {
1533 Success,
1534 Failure,
1535}
1536
1537#[derive(
1538 Archive,
1539 RkyvDeserialize,
1540 RkyvSerialize,
1541 Clone,
1542 Copy,
1543 Debug,
1544 Eq,
1545 PartialEq,
1546 Serialize,
1547 Deserialize,
1548 Default,
1549)]
1550#[archive(check_bytes)]
1551#[serde(rename_all = "snake_case")]
1552pub enum TradingStatus {
1553 #[default]
1554 Live,
1555 PostOnly,
1556 NotTradable,
1557 ReduceOnly,
1558 SoftReduceOnly,
1559}
1560
1561impl FromStr for TradingStatus {
1562 type Err = eyre::Report;
1563
1564 fn from_str(trading_status: &str) -> Result<Self> {
1565 match trading_status.to_lowercase().as_str() {
1566 "live" => Ok(Self::Live),
1567 "post_only" => Ok(Self::PostOnly),
1568 "reduce_only" => Ok(Self::ReduceOnly),
1569 "not_tradable" => Ok(Self::NotTradable),
1570 "soft_reduce_only" => Ok(Self::SoftReduceOnly),
1571 _ => Err(eyre!("Invalid trading status: {trading_status}")),
1572 }
1573 }
1574}
1575
1576impl std::fmt::Display for TradingStatus {
1577 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1578 let s = match self {
1579 TradingStatus::Live => "live",
1580 TradingStatus::PostOnly => "post_only",
1581 TradingStatus::ReduceOnly => "reduce_only",
1582 TradingStatus::NotTradable => "not_tradable",
1583 TradingStatus::SoftReduceOnly => "soft_reduce_only",
1584 };
1585 write!(f, "{s}")
1586 }
1587}
1588
1589#[derive(
1590 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1591)]
1592#[archive(check_bytes)]
1593#[serde(rename_all = "snake_case")]
1596pub enum EngineStatus {
1597 Started,
1598 Active,
1600 Stopping,
1602 Syncing,
1604 LiveSyncing,
1606 Failed, }
1610
1611impl From<EngineStatus> for u8 {
1612 fn from(status: EngineStatus) -> Self {
1613 match status {
1614 EngineStatus::Started => 0,
1615 EngineStatus::Active => 1,
1616 EngineStatus::Stopping => 2,
1617 EngineStatus::Syncing => 3,
1618 EngineStatus::LiveSyncing => 4,
1619 EngineStatus::Failed => 5,
1620 }
1621 }
1622}
1623
1624impl From<u8> for EngineStatus {
1625 fn from(status: u8) -> Self {
1626 match status {
1627 0 => EngineStatus::Started,
1628 1 => EngineStatus::Active,
1629 2 => EngineStatus::Stopping,
1630 3 => EngineStatus::Syncing,
1631 4 => EngineStatus::LiveSyncing,
1632 5 => EngineStatus::Failed,
1633 _ => panic!("Invalid EngineStatus"),
1634 }
1635 }
1636}
1637
1638impl From<EngineStatus> for AtomicU8 {
1639 fn from(status: EngineStatus) -> Self {
1640 AtomicU8::new(status.into())
1641 }
1642}
1643
1644impl From<AtomicU8> for EngineStatus {
1645 fn from(status: AtomicU8) -> Self {
1646 EngineStatus::from(status.load(Ordering::Relaxed))
1647 }
1648}
1649
1650#[derive(
1651 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1652)]
1653#[archive(check_bytes)]
1654#[serde(rename_all = "snake_case")]
1657#[serde(untagged)]
1658pub enum QueryResponseData {
1659 StatusResponse(EngineStatus),
1660 Contracts(ContractsResponse),
1661 FeeRates(FeeRatesResponse),
1662 Nonces(NoncesResponse),
1663 LinkedSigner(LinkedSignerResponse),
1664 SubaccountInfo(SubaccountInfoResponse),
1665 MarketPrice(MarketPriceResponse),
1666 MarketPrices(MarketPricesResponse),
1667 Order(OrderResponse),
1668 Orders(OrdersResponse),
1669 ValidateOrder(ValidateOrderResponse),
1670 SubaccountOrders(SubaccountOrdersResponse),
1671 MarketLiquidity(MarketLiquidityResponse),
1672 AllProducts(AllProductsResponse),
1673 EdgeAllProducts(EdgeAllProductsResponse),
1674 MaxOrderSize(MaxOrderSizeResponse),
1675 MaxWithdrawable(MaxWithdrawableResponse),
1676 MaxNlpMintable(MaxNlpMintableResponse),
1677 MaxNlpBurnable(MaxNlpBurnableResponse),
1678 HealthGroups(HealthGroupsResponse),
1679 Insurance(InsuranceResponse),
1680 Symbols(SymbolsResponse),
1681 IsolatedPositions(IsolatedPositionsResponse),
1682 NlpPoolInfo(NlpPoolInfoResponse),
1683 NlpLockedBalances(NlpLockedBalancesResponse),
1684 Error(String),
1685}
1686
1687#[derive(
1688 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1689)]
1690#[archive(check_bytes)]
1691#[serde(rename_all = "snake_case")]
1694pub struct QueryResponse {
1695 pub status: Status,
1696 #[serde(skip_serializing_if = "Option::is_none")]
1697 pub data: Option<QueryResponseData>,
1698 #[serde(skip_serializing_if = "Option::is_none")]
1699 pub error_code: Option<i32>,
1700 #[serde(skip_serializing_if = "Option::is_none")]
1701 pub error: Option<String>,
1702 #[serde(skip_serializing_if = "Option::is_none")]
1703 pub request_type: Option<String>,
1704}
1705
1706#[derive(
1707 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1708)]
1709#[archive(check_bytes)]
1710pub struct ExecuteResponse {
1713 pub status: Status,
1714 #[serde(
1715 serialize_with = "serialize_option_vec_u8",
1716 deserialize_with = "deserialize_option_vec_u8"
1717 )]
1718 #[serde(skip_serializing_if = "Option::is_none")]
1719 #[serde(default)]
1720 pub signature: Option<Vec<u8>>,
1721 #[serde(skip_serializing_if = "Option::is_none")]
1722 #[serde(default)]
1723 pub id: Option<u64>,
1724 #[serde(skip_serializing_if = "Option::is_none")]
1725 pub data: Option<ExecuteResponseData>,
1726 #[serde(skip_serializing_if = "Option::is_none")]
1727 pub error_code: Option<i32>,
1728 #[serde(skip_serializing_if = "Option::is_none")]
1729 pub error: Option<String>,
1730 #[serde(skip_serializing_if = "Option::is_none")]
1731 pub request_type: Option<String>,
1732}
1733
1734#[derive(
1735 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1736)]
1737#[archive(check_bytes)]
1738#[serde(untagged)]
1739#[serde(rename_all = "snake_case")]
1740pub enum ExecuteResponseData {
1741 PlaceOrder(PlaceOrderResponse),
1742 PlaceOrders(PlaceOrdersResponse),
1743 CancelOrders(CancelOrdersResponse),
1744 CancelProductOrders(CancelOrdersResponse),
1745 MatchOrdersOtc(MatchOrdersOtcResponse),
1746 MatchOrdersOtcs(MatchOrdersOtcsResponse),
1747}
1748
1749#[derive(
1750 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1751)]
1752#[archive(check_bytes)]
1753pub struct MatchOrdersOtcResponse {
1754 #[serde(
1755 serialize_with = "serialize_bytes32",
1756 deserialize_with = "deserialize_bytes32"
1757 )]
1758 pub taker_digest: [u8; 32],
1759 #[serde(
1760 serialize_with = "serialize_vec_bytes32",
1761 deserialize_with = "deserialize_vec_bytes32"
1762 )]
1763 pub maker_digests: Vec<[u8; 32]>,
1764}
1765
1766#[derive(
1767 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1768)]
1769#[archive(check_bytes)]
1770pub struct MatchOrdersOtcsResponse {
1771 pub legs: Vec<MatchOrdersOtcResponse>,
1772}
1773
1774#[derive(
1775 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1776)]
1777#[archive(check_bytes)]
1778pub struct CancelOrdersResponse {
1779 pub cancelled_orders: Vec<OrderResponse>,
1780}
1781
1782#[derive(
1783 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1784)]
1785#[archive(check_bytes)]
1786pub struct PlaceOrderResponse {
1787 #[serde(
1788 serialize_with = "serialize_bytes32",
1789 deserialize_with = "deserialize_bytes32"
1790 )]
1791 pub digest: [u8; 32],
1792}
1793
1794#[derive(
1795 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1796)]
1797#[archive(check_bytes)]
1798pub struct PlaceOrdersItemResponse {
1799 #[serde(
1800 serialize_with = "serialize_option_bytes32",
1801 deserialize_with = "deserialize_option_bytes32"
1802 )]
1803 pub digest: Option<[u8; 32]>,
1804 pub error: Option<String>,
1805}
1806
1807pub type PlaceOrdersResponse = Vec<PlaceOrdersItemResponse>;
1808
1809#[derive(
1810 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1811)]
1812#[serde(untagged)]
1813#[archive(check_bytes)]
1814#[allow(clippy::large_enum_variant)]
1815pub enum EngineResponse {
1816 Query(QueryResponse),
1817 Execute(ExecuteResponse),
1818}
1819
1820#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug, Clone)]
1821#[archive(check_bytes)]
1822#[serde(rename_all = "snake_case")]
1823pub enum QueryV2 {
1826 Orderbook(OrderbookParams),
1827
1828 Pairs(MarketPairsParams),
1829
1830 Assets {},
1831
1832 Apr {},
1833}
1834
1835#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
1836#[archive(check_bytes)]
1837#[serde(rename_all = "snake_case")]
1838pub struct OrderbookParams {
1839 pub ticker_id: String,
1840 #[serde(deserialize_with = "str_or_u32")]
1841 pub depth: u32,
1842}
1843
1844#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
1845#[archive(check_bytes)]
1846#[serde(rename_all = "snake_case")]
1847pub struct MarketPairsParams {
1848 pub market: Option<String>,
1849}
1850
1851#[derive(
1852 Clone,
1853 Debug,
1854 Default,
1855 PartialEq,
1856 Serialize,
1857 Deserialize,
1858 Archive,
1859 RkyvSerialize,
1860 RkyvDeserialize,
1861)]
1862#[archive(check_bytes)]
1863pub struct OrderbookPriceLevel(pub f64, pub f64);
1864
1865#[derive(
1866 Clone,
1867 Debug,
1868 Default,
1869 PartialEq,
1870 Serialize,
1871 Deserialize,
1872 Archive,
1873 RkyvSerialize,
1874 RkyvDeserialize,
1875)]
1876#[archive(check_bytes)]
1877pub struct OrderbookResponse {
1880 pub product_id: u32,
1881 pub ticker_id: String,
1882 pub bids: Vec<OrderbookPriceLevel>,
1883 pub asks: Vec<OrderbookPriceLevel>,
1884 pub timestamp: u64,
1885}
1886
1887#[derive(
1888 Clone,
1889 Debug,
1890 Default,
1891 Eq,
1892 PartialEq,
1893 Serialize,
1894 Deserialize,
1895 Archive,
1896 RkyvSerialize,
1897 RkyvDeserialize,
1898)]
1899#[archive(check_bytes)]
1900pub struct MarketPair {
1903 pub product_id: u32,
1904 pub ticker_id: String,
1905 pub base: String,
1906 pub quote: String,
1907}
1908
1909pub type MarketPairsResponse = Vec<MarketPair>;
1910
1911#[derive(
1912 Clone, Debug, Default, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1913)]
1914#[archive(check_bytes)]
1915pub struct MarketApr {
1916 pub name: String,
1917 pub symbol: String,
1918 pub product_id: u32,
1919 pub deposit_apr: f64,
1920 pub borrow_apr: f64,
1921 pub tvl: f64,
1922}
1923
1924pub type MarketsAprResponse = Vec<MarketApr>;
1925
1926#[derive(
1927 Clone,
1928 Debug,
1929 Default,
1930 PartialEq,
1931 Serialize,
1932 Deserialize,
1933 Archive,
1934 RkyvSerialize,
1935 RkyvDeserialize,
1936)]
1937#[archive(check_bytes)]
1938pub struct Asset {
1941 pub product_id: u32,
1942 pub ticker_id: Option<String>,
1943 pub market_type: Option<String>,
1944 pub name: String,
1945 pub symbol: String,
1946 pub maker_fee: Option<f64>,
1947 pub taker_fee: Option<f64>,
1948 pub can_withdraw: bool,
1949 pub can_deposit: bool,
1950}
1951
1952pub type AssetsResponse = Vec<Asset>;