1use std::collections::HashMap;
2use std::sync::atomic::{AtomicU8, Ordering};
3use crate::bindings::querier::{
5 BookInfo, HealthInfo, LegacyRisk, PerpBalance, PerpProduct, ProductInfo, SpotBalance,
6 SubaccountInfo,
7};
8use crate::bindings::spot_engine;
9use crate::eip712_structs::{
10 BurnLp, BurnVlp, Cancellation, CancellationProducts, IsolatedOrder, LinkSigner,
11 LiquidateSubaccount, MintLp, MintVlp, Order, TransferQuote, WithdrawCollateral,
12};
13use crate::math::f64_to_x18;
14use crate::product::Product;
15use crate::serialize_utils::{
16 deserialize_bytes20, deserialize_bytes32, deserialize_i128, deserialize_nested_vec_i128,
17 deserialize_option_bytes32, deserialize_option_vec_u8, deserialize_u64,
18 deserialize_vec_bytes20, deserialize_vec_i128, deserialize_vec_u8,
19 serialize_bytes20, serialize_bytes32, serialize_i128, serialize_nested_vec_i128,
20 serialize_option_bytes32, serialize_option_vec_u8, serialize_u64, serialize_vec_bytes20, serialize_vec_i128, serialize_vec_u8, str_or_u32, WrappedI128,
21};
22use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
23use serde::{Deserialize, Serialize};
24#[derive(
27 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
28)]
29#[serde(rename_all = "snake_case")]
30#[archive(check_bytes)]
31pub enum Direction {
32 Long,
33 Short,
34}
35
36#[derive(Clone, Debug, Serialize, Deserialize)]
37pub struct ProductDelta {
38 pub product_id: u32,
39 #[serde(
40 serialize_with = "serialize_bytes32",
41 deserialize_with = "deserialize_bytes32"
42 )]
43 pub subaccount: [u8; 32],
44 #[serde(
45 serialize_with = "serialize_i128",
46 deserialize_with = "deserialize_i128"
47 )]
48 pub amount_delta: i128,
49 #[serde(
50 serialize_with = "serialize_i128",
51 deserialize_with = "deserialize_i128"
52 )]
53 pub v_quote_delta: i128,
54}
55
56#[derive(Clone, Debug, Serialize, Deserialize)]
57#[serde(rename_all = "snake_case")]
58pub enum Txn {
59 MintLp(spot_engine::MintLpCall),
60 BurnLp(spot_engine::BurnLpCall),
61 ApplyDelta(ProductDelta),
62}
63
64#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug, Clone)]
65#[archive(check_bytes)]
66#[serde(rename_all = "snake_case")]
67#[serde(tag = "type")]
68pub enum Query {
71 Status {},
72
73 Contracts {},
74
75 Nonces {
76 #[serde(
77 serialize_with = "serialize_bytes20",
78 deserialize_with = "deserialize_bytes20"
79 )]
80 address: [u8; 20],
81 },
82
83 LinkedSigner {
84 #[serde(
85 serialize_with = "serialize_bytes32",
86 deserialize_with = "deserialize_bytes32"
87 )]
88 subaccount: [u8; 32],
89 },
90
91 SubaccountInfo {
92 #[serde(
93 serialize_with = "serialize_bytes32",
94 deserialize_with = "deserialize_bytes32"
95 )]
96 subaccount: [u8; 32],
97 txns: 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 },
184
185 MaxWithdrawable {
186 #[serde(
187 serialize_with = "serialize_bytes32",
188 deserialize_with = "deserialize_bytes32"
189 )]
190 sender: [u8; 32],
191 #[serde(deserialize_with = "str_or_u32")]
192 product_id: u32,
193 spot_leverage: Option<String>,
194 },
195
196 MaxLpMintable {
197 #[serde(
198 serialize_with = "serialize_bytes32",
199 deserialize_with = "deserialize_bytes32"
200 )]
201 sender: [u8; 32],
202 #[serde(deserialize_with = "str_or_u32")]
203 product_id: u32,
204 spot_leverage: Option<String>,
205 },
206
207 MaxVlpMintable {
208 #[serde(
209 serialize_with = "serialize_bytes32",
210 deserialize_with = "deserialize_bytes32"
211 )]
212 sender: [u8; 32],
213 spot_leverage: Option<String>,
214 },
215
216 IsolatedPositions {
217 #[serde(
218 serialize_with = "serialize_bytes32",
219 deserialize_with = "deserialize_bytes32"
220 )]
221 subaccount: [u8; 32],
222 },
223
224 HealthGroups {},
225
226 Insurance {},
227
228 Versions {},
229
230 Symbols {
231 product_ids: Option<Vec<u32>>,
232 product_type: Option<String>,
233 },
234
235 MinDepositRates {},
236}
237
238#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
239#[archive(check_bytes)]
240#[serde(rename_all = "snake_case")]
241pub struct PlaceOrder {
242 pub order: Order,
243 #[serde(
244 serialize_with = "serialize_vec_u8",
245 deserialize_with = "deserialize_vec_u8"
246 )]
247 pub signature: Vec<u8>,
248 pub product_id: u32,
249 #[serde(
250 serialize_with = "serialize_option_bytes32",
251 deserialize_with = "deserialize_option_bytes32"
252 )]
253 #[serde(default)]
254 pub digest: Option<[u8; 32]>,
255 #[serde(skip_serializing_if = "Option::is_none")]
257 #[serde(default)]
258 pub id: Option<u64>,
259 pub spot_leverage: Option<bool>,
260}
261
262#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
263#[archive(check_bytes)]
264#[serde(rename_all = "snake_case")]
265pub struct PlaceIsolatedOrder {
266 pub isolated_order: IsolatedOrder,
267 #[serde(
268 serialize_with = "serialize_vec_u8",
269 deserialize_with = "deserialize_vec_u8"
270 )]
271 pub signature: Vec<u8>,
272 pub product_id: u32,
273 #[serde(
274 serialize_with = "serialize_option_bytes32",
275 deserialize_with = "deserialize_option_bytes32"
276 )]
277 #[serde(default)]
279 pub digest: Option<[u8; 32]>,
280 #[serde(skip_serializing_if = "Option::is_none")]
282 #[serde(default)]
283 pub id: Option<u64>,
284 pub borrow_margin: Option<bool>,
285}
286
287impl PlaceIsolatedOrder {
288 pub fn to_place_order(&self) -> PlaceOrder {
289 PlaceOrder {
290 order: self.isolated_order.to_order(),
291 signature: self.signature.clone(),
292 product_id: self.product_id,
293 digest: self.digest,
294 id: self.id,
295 spot_leverage: None,
296 }
297 }
298}
299
300#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
301#[archive(check_bytes)]
302#[serde(rename_all = "camelCase")]
303pub struct Artifact {
304 pub bytecode: String,
305 pub deployed_bytecode: String,
306}
307
308#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
309#[archive(check_bytes)]
310#[serde(rename_all = "snake_case")]
311pub enum Execute {
314 LiquidateSubaccount {
315 tx: LiquidateSubaccount,
316 #[serde(
317 serialize_with = "serialize_vec_u8",
318 deserialize_with = "deserialize_vec_u8"
319 )]
320 signature: Vec<u8>,
321 },
322 WithdrawCollateral {
323 tx: WithdrawCollateral,
324 #[serde(
325 serialize_with = "serialize_vec_u8",
326 deserialize_with = "deserialize_vec_u8"
327 )]
328 signature: Vec<u8>,
329 spot_leverage: Option<bool>,
330 sequencer_risk_check: Option<bool>,
331 },
332 MintLp {
333 tx: MintLp,
334 #[serde(
335 serialize_with = "serialize_vec_u8",
336 deserialize_with = "deserialize_vec_u8"
337 )]
338 signature: Vec<u8>,
339 spot_leverage: Option<bool>,
340 },
341 BurnLp {
342 tx: BurnLp,
343 #[serde(
344 serialize_with = "serialize_vec_u8",
345 deserialize_with = "deserialize_vec_u8"
346 )]
347 signature: Vec<u8>,
348 },
349 PlaceOrder(PlaceOrder),
350 PlaceIsolatedOrder(PlaceIsolatedOrder),
351 CancelOrders {
352 tx: Cancellation,
353 #[serde(
354 serialize_with = "serialize_vec_u8",
355 deserialize_with = "deserialize_vec_u8"
356 )]
357 signature: Vec<u8>,
358 },
359 CancelProductOrders {
360 tx: CancellationProducts,
361 #[serde(
362 serialize_with = "serialize_vec_u8",
363 deserialize_with = "deserialize_vec_u8"
364 )]
365 signature: Vec<u8>,
366 #[serde(
367 serialize_with = "serialize_option_bytes32",
368 deserialize_with = "deserialize_option_bytes32"
369 )]
370 #[serde(default)]
371 digest: Option<[u8; 32]>,
372 },
373 LinkSigner {
374 tx: LinkSigner,
375 #[serde(
376 serialize_with = "serialize_vec_u8",
377 deserialize_with = "deserialize_vec_u8"
378 )]
379 signature: Vec<u8>,
380 },
381 CancelAndPlace {
382 cancel_tx: Cancellation,
383 #[serde(
384 serialize_with = "serialize_vec_u8",
385 deserialize_with = "deserialize_vec_u8"
386 )]
387 cancel_signature: Vec<u8>,
388 place_order: PlaceOrder,
389 },
390 SubmitPrivateBatch {
391 orders: Vec<[PlaceOrder; 2]>,
392 },
393
394 TransferQuote {
395 tx: TransferQuote,
396 #[serde(
397 serialize_with = "serialize_vec_u8",
398 deserialize_with = "deserialize_vec_u8"
399 )]
400 signature: Vec<u8>,
401 },
402
403 MintVlp {
404 tx: MintVlp,
405 #[serde(
406 serialize_with = "serialize_vec_u8",
407 deserialize_with = "deserialize_vec_u8"
408 )]
409 signature: Vec<u8>,
410 spot_leverage: Option<bool>,
411 },
412 BurnVlp {
413 tx: BurnVlp,
414 #[serde(
415 serialize_with = "serialize_vec_u8",
416 deserialize_with = "deserialize_vec_u8"
417 )]
418 signature: Vec<u8>,
419 },
420}
421
422#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug)]
423#[serde(untagged)]
424#[archive(check_bytes)]
425pub enum EngineMessage {
426 Query(Query),
427 Execute(Execute),
428}
429
430#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug)]
431#[archive(check_bytes)]
432pub struct LabeledEngineMessage {
433 pub chain_id: u64,
434 pub msg: EngineMessage,
435}
436
437#[derive(
438 Archive,
439 RkyvDeserialize,
440 RkyvSerialize,
441 Serialize,
442 Deserialize,
443 Clone,
444 Debug,
445 Default,
446 Eq,
447 PartialEq,
448)]
449#[archive(check_bytes)]
450pub struct Config {
451 #[serde(
452 serialize_with = "serialize_bytes20",
453 deserialize_with = "deserialize_bytes20"
454 )]
455 pub token: [u8; 20],
456 #[serde(
457 serialize_with = "serialize_i128",
458 deserialize_with = "deserialize_i128"
459 )]
460 pub interest_inflection_util_x18: i128,
461 #[serde(
462 serialize_with = "serialize_i128",
463 deserialize_with = "deserialize_i128"
464 )]
465 pub interest_floor_x18: i128,
466 #[serde(
467 serialize_with = "serialize_i128",
468 deserialize_with = "deserialize_i128"
469 )]
470 pub interest_small_cap_x18: i128,
471 #[serde(
472 serialize_with = "serialize_i128",
473 deserialize_with = "deserialize_i128"
474 )]
475 pub interest_large_cap_x18: i128,
476}
477
478impl From<crate::bindings::querier::Config> for Config {
479 fn from(config: crate::bindings::querier::Config) -> Self {
480 Config {
481 token: config.token.into(),
482 interest_inflection_util_x18: config.interest_inflection_util_x18,
483 interest_floor_x18: config.interest_floor_x18,
484 interest_small_cap_x18: config.interest_small_cap_x18,
485 interest_large_cap_x18: config.interest_large_cap_x18,
486 }
487 }
488}
489
490#[derive(
491 Archive,
492 RkyvDeserialize,
493 RkyvSerialize,
494 Serialize,
495 Deserialize,
496 Clone,
497 Debug,
498 Default,
499 Eq,
500 PartialEq,
501)]
502#[archive(check_bytes)]
503pub struct SpotProduct {
504 pub product_id: u32,
505 #[serde(
506 serialize_with = "serialize_i128",
507 deserialize_with = "deserialize_i128"
508 )]
509 pub oracle_price_x18: i128,
510 pub risk: LegacyRisk,
511 pub config: Config,
512 pub state: crate::bindings::spot_engine::State,
513 pub lp_state: crate::bindings::spot_engine::LpState,
514 pub book_info: BookInfo,
515}
516
517impl From<crate::bindings::querier::SpotProduct> for SpotProduct {
518 fn from(spot_product: crate::bindings::querier::SpotProduct) -> Self {
519 SpotProduct {
520 product_id: spot_product.product_id,
521 oracle_price_x18: spot_product.oracle_price_x18,
522 risk: spot_product.risk,
523 config: Config::from(spot_product.config),
524 state: spot_product.state,
525 lp_state: spot_product.lp_state,
526 book_info: spot_product.book_info,
527 }
528 }
529}
530
531#[derive(
532 Archive,
533 RkyvDeserialize,
534 RkyvSerialize,
535 Serialize,
536 Deserialize,
537 Clone,
538 Debug,
539 Default,
540 Eq,
541 PartialEq,
542)]
543#[archive(check_bytes)]
544pub struct AllProductsResponse {
545 pub spot_products: ::std::vec::Vec<SpotProduct>,
546 pub perp_products: ::std::vec::Vec<PerpProduct>,
547}
548
549impl From<ProductInfo> for AllProductsResponse {
550 fn from(product_info: ProductInfo) -> Self {
551 AllProductsResponse {
552 spot_products: product_info
553 .spot_products
554 .into_iter()
555 .map(SpotProduct::from)
556 .collect(),
557 perp_products: product_info.perp_products,
558 }
559 }
560}
561#[derive(
562 Archive,
563 RkyvDeserialize,
564 RkyvSerialize,
565 Serialize,
566 Deserialize,
567 Clone,
568 Debug,
569 Default,
570 Eq,
571 PartialEq,
572)]
573#[archive(check_bytes)]
574pub struct EdgeAllProductsResponse {
575 pub edge_all_products: HashMap<u64, AllProductsResponse>,
576}
577
578#[derive(
579 Archive,
580 RkyvDeserialize,
581 RkyvSerialize,
582 Serialize,
583 Deserialize,
584 Clone,
585 Debug,
586 Default,
587 Eq,
588 PartialEq,
589)]
590#[archive(check_bytes)]
591pub struct SubaccountInfoResponse {
592 #[serde(
593 serialize_with = "serialize_bytes32",
594 deserialize_with = "deserialize_bytes32"
595 )]
596 pub subaccount: [u8; 32],
597 pub exists: bool,
598 pub healths: ::std::vec::Vec<HealthInfo>,
599 #[serde(
600 serialize_with = "serialize_nested_vec_i128",
601 deserialize_with = "deserialize_nested_vec_i128"
602 )]
603 pub health_contributions: Vec<Vec<i128>>,
604 pub spot_count: u32,
605 pub perp_count: u32,
606 pub spot_balances: ::std::vec::Vec<SpotBalance>,
607 pub perp_balances: ::std::vec::Vec<PerpBalance>,
608 pub spot_products: ::std::vec::Vec<SpotProduct>,
609 pub perp_products: ::std::vec::Vec<PerpProduct>,
610}
611
612impl From<SubaccountInfo> for SubaccountInfoResponse {
613 fn from(subaccount_info: SubaccountInfo) -> Self {
614 SubaccountInfoResponse {
615 subaccount: subaccount_info.subaccount,
616 exists: subaccount_info.exists,
617 healths: subaccount_info.healths,
618 health_contributions: subaccount_info.health_contributions,
619 spot_count: subaccount_info.spot_count,
620 perp_count: subaccount_info.perp_count,
621 spot_balances: subaccount_info.spot_balances,
622 perp_balances: subaccount_info.perp_balances,
623 spot_products: subaccount_info
624 .spot_products
625 .into_iter()
626 .map(SpotProduct::from)
627 .collect(),
628 perp_products: subaccount_info.perp_products,
629 }
630 }
631}
632
633#[derive(
634 Clone,
635 Debug,
636 Default,
637 Eq,
638 PartialEq,
639 Serialize,
640 Deserialize,
641 Archive,
642 RkyvSerialize,
643 RkyvDeserialize,
644)]
645#[archive(check_bytes)]
646pub struct ContractsResponse {
647 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
648 pub chain_id: u64,
651 #[serde(
652 serialize_with = "serialize_bytes20",
653 deserialize_with = "deserialize_bytes20"
654 )]
655 pub endpoint_addr: [u8; 20],
656 #[serde(
657 serialize_with = "serialize_vec_bytes20",
658 deserialize_with = "deserialize_vec_bytes20"
659 )]
660 pub book_addrs: Vec<[u8; 20]>,
661}
662
663#[derive(
664 Clone,
665 Debug,
666 Default,
667 Eq,
668 PartialEq,
669 Serialize,
670 Deserialize,
671 Archive,
672 RkyvSerialize,
673 RkyvDeserialize,
674)]
675#[archive(check_bytes)]
676pub struct NoncesResponse {
677 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
678 pub tx_nonce: u64,
679 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
680 pub order_nonce: u64,
681}
682
683#[derive(
684 Clone,
685 Debug,
686 Default,
687 Eq,
688 PartialEq,
689 Serialize,
690 Deserialize,
691 Archive,
692 RkyvSerialize,
693 RkyvDeserialize,
694)]
695#[archive(check_bytes)]
696pub struct LinkedSignerResponse {
697 #[serde(
698 serialize_with = "serialize_bytes20",
699 deserialize_with = "deserialize_bytes20"
700 )]
701 pub linked_signer: [u8; 20],
702}
703
704#[derive(
705 Clone,
706 Debug,
707 Default,
708 Eq,
709 PartialEq,
710 Serialize,
711 Deserialize,
712 Archive,
713 RkyvSerialize,
714 RkyvDeserialize,
715)]
716#[archive(check_bytes)]
717pub struct MarketPriceResponse {
720 pub product_id: u32,
721 #[serde(
722 serialize_with = "serialize_i128",
723 deserialize_with = "deserialize_i128"
724 )]
725 pub bid_x18: i128,
727 #[serde(
728 serialize_with = "serialize_i128",
729 deserialize_with = "deserialize_i128"
730 )]
731 pub ask_x18: i128,
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 MarketPricesResponse {
751 pub market_prices: Vec<MarketPriceResponse>,
752}
753
754#[derive(
755 Clone,
756 Debug,
757 Default,
758 Eq,
759 PartialEq,
760 Serialize,
761 Deserialize,
762 Archive,
763 RkyvSerialize,
764 RkyvDeserialize,
765)]
766#[archive(check_bytes)]
767pub struct OrderResponse {
770 pub product_id: u32,
771 #[serde(
773 serialize_with = "serialize_bytes32",
774 deserialize_with = "deserialize_bytes32"
775 )]
776 pub sender: [u8; 32],
777 #[serde(
778 serialize_with = "serialize_i128",
779 deserialize_with = "deserialize_i128"
780 )]
781 pub price_x18: i128,
783 #[serde(
784 serialize_with = "serialize_i128",
785 deserialize_with = "deserialize_i128"
786 )]
787 pub amount: i128,
789 pub expiration: String,
790 pub order_type: String,
791 pub nonce: String,
792 #[serde(
793 serialize_with = "serialize_i128",
794 deserialize_with = "deserialize_i128"
795 )]
796 pub unfilled_amount: i128,
798 #[serde(
799 serialize_with = "serialize_bytes32",
800 deserialize_with = "deserialize_bytes32"
801 )]
802 pub digest: [u8; 32],
803 pub placed_at: u64,
804
805 #[serde(skip_serializing_if = "Option::is_none")]
806 pub margin: Option<WrappedI128>,
807}
808
809#[derive(
810 Clone,
811 Debug,
812 Default,
813 Eq,
814 PartialEq,
815 Serialize,
816 Deserialize,
817 Archive,
818 RkyvSerialize,
819 RkyvDeserialize,
820)]
821#[archive(check_bytes)]
822pub struct ValidateOrderResponse {
825 pub product_id: u32,
826 #[serde(
827 serialize_with = "serialize_vec_u8",
828 deserialize_with = "deserialize_vec_u8"
829 )]
830 pub order: Vec<u8>,
831 pub valid: bool,
832}
833
834#[derive(
835 Clone,
836 Debug,
837 Default,
838 Eq,
839 PartialEq,
840 Serialize,
841 Deserialize,
842 Archive,
843 RkyvSerialize,
844 RkyvDeserialize,
845)]
846#[archive(check_bytes)]
847pub struct FeeRatesResponse {
850 #[serde(
851 serialize_with = "serialize_vec_i128",
852 deserialize_with = "deserialize_vec_i128"
853 )]
854 pub taker_fee_rates_x18: Vec<i128>,
855 #[serde(
856 serialize_with = "serialize_vec_i128",
857 deserialize_with = "deserialize_vec_i128"
858 )]
859 pub maker_fee_rates_x18: Vec<i128>,
860 #[serde(
861 serialize_with = "serialize_i128",
862 deserialize_with = "deserialize_i128"
863 )]
864 pub liquidation_sequencer_fee: i128,
865 #[serde(
866 serialize_with = "serialize_i128",
867 deserialize_with = "deserialize_i128"
868 )]
869 pub health_check_sequencer_fee: i128,
870 #[serde(
871 serialize_with = "serialize_i128",
872 deserialize_with = "deserialize_i128"
873 )]
874 pub taker_sequencer_fee: i128,
875 #[serde(
876 serialize_with = "serialize_vec_i128",
877 deserialize_with = "deserialize_vec_i128"
878 )]
879 pub withdraw_sequencer_fees: Vec<i128>,
880}
881
882#[derive(
883 Clone,
884 Debug,
885 Default,
886 Eq,
887 PartialEq,
888 Serialize,
889 Deserialize,
890 Archive,
891 RkyvSerialize,
892 RkyvDeserialize,
893)]
894#[archive(check_bytes)]
895pub struct SubaccountOrdersResponse {
898 #[serde(
899 serialize_with = "serialize_bytes32",
900 deserialize_with = "deserialize_bytes32"
901 )]
902 pub sender: [u8; 32],
903 pub product_id: u32,
904 pub orders: Vec<OrderResponse>,
905}
906
907#[derive(
908 Clone,
909 Debug,
910 Default,
911 Eq,
912 PartialEq,
913 Serialize,
914 Deserialize,
915 Archive,
916 RkyvSerialize,
917 RkyvDeserialize,
918)]
919#[archive(check_bytes)]
920pub struct ProductOrdersResponse {
923 pub product_id: u32,
924 pub orders: Vec<OrderResponse>,
925}
926
927#[derive(
928 Clone,
929 Debug,
930 Default,
931 Eq,
932 PartialEq,
933 Serialize,
934 Deserialize,
935 Archive,
936 RkyvSerialize,
937 RkyvDeserialize,
938)]
939#[archive(check_bytes)]
940pub struct OrdersResponse {
943 #[serde(
944 serialize_with = "serialize_bytes32",
945 deserialize_with = "deserialize_bytes32"
946 )]
947 pub sender: [u8; 32],
948 pub product_orders: Vec<ProductOrdersResponse>,
949}
950
951#[derive(
952 Clone,
953 Debug,
954 Default,
955 Eq,
956 PartialEq,
957 Serialize,
958 Deserialize,
959 Archive,
960 RkyvSerialize,
961 RkyvDeserialize,
962)]
963#[archive(check_bytes)]
964pub struct MaxOrderSizeResponse {
967 #[serde(
969 serialize_with = "serialize_i128",
970 deserialize_with = "deserialize_i128"
971 )]
972 pub max_order_size: i128,
973}
974
975#[derive(
976 Clone,
977 Debug,
978 Default,
979 Eq,
980 PartialEq,
981 Serialize,
982 Deserialize,
983 Archive,
984 RkyvSerialize,
985 RkyvDeserialize,
986)]
987#[archive(check_bytes)]
988pub struct MaxWithdrawableResponse {
991 #[serde(
993 serialize_with = "serialize_i128",
994 deserialize_with = "deserialize_i128"
995 )]
996 pub max_withdrawable: i128,
997}
998
999#[derive(
1000 Clone,
1001 Debug,
1002 Default,
1003 Eq,
1004 PartialEq,
1005 Serialize,
1006 Deserialize,
1007 Archive,
1008 RkyvSerialize,
1009 RkyvDeserialize,
1010)]
1011#[archive(check_bytes)]
1012pub struct MaxLpMintableResponse {
1015 #[serde(
1017 serialize_with = "serialize_i128",
1018 deserialize_with = "deserialize_i128"
1019 )]
1020 pub max_base_amount: i128,
1021 #[serde(
1022 serialize_with = "serialize_i128",
1023 deserialize_with = "deserialize_i128"
1024 )]
1025 pub max_quote_amount: i128,
1026}
1027
1028#[derive(
1029 Clone,
1030 Debug,
1031 Default,
1032 Eq,
1033 PartialEq,
1034 Serialize,
1035 Deserialize,
1036 Archive,
1037 RkyvSerialize,
1038 RkyvDeserialize,
1039)]
1040#[archive(check_bytes)]
1041pub struct MaxVlpMintableResponse {
1044 #[serde(
1046 serialize_with = "serialize_i128",
1047 deserialize_with = "deserialize_i128"
1048 )]
1049 pub max_quote_amount: i128,
1050}
1051
1052#[derive(
1053 Clone,
1054 Debug,
1055 Default,
1056 Eq,
1057 PartialEq,
1058 Serialize,
1059 Deserialize,
1060 Archive,
1061 RkyvSerialize,
1062 RkyvDeserialize,
1063)]
1064#[archive(check_bytes)]
1065pub struct HealthGroupsResponse {
1068 pub health_groups: Vec<(u32, u32)>,
1070}
1071
1072#[derive(
1073 Clone,
1074 Debug,
1075 Default,
1076 Eq,
1077 PartialEq,
1078 Serialize,
1079 Deserialize,
1080 Archive,
1081 RkyvSerialize,
1082 RkyvDeserialize,
1083)]
1084#[archive(check_bytes)]
1085pub struct InsuranceResponse {
1088 #[serde(
1090 serialize_with = "serialize_i128",
1091 deserialize_with = "deserialize_i128"
1092 )]
1093 pub insurance: i128,
1094}
1095
1096#[derive(
1097 Clone,
1098 Debug,
1099 Default,
1100 Eq,
1101 PartialEq,
1102 Serialize,
1103 Deserialize,
1104 Archive,
1105 RkyvSerialize,
1106 RkyvDeserialize,
1107)]
1108#[archive(check_bytes)]
1109pub struct SymbolsResponse {
1110 pub symbols: HashMap<String, SymbolsResponseData>,
1111}
1112
1113#[derive(
1114 Clone,
1115 Debug,
1116 Default,
1117 Eq,
1118 PartialEq,
1119 Serialize,
1120 Deserialize,
1121 Archive,
1122 RkyvSerialize,
1123 RkyvDeserialize,
1124)]
1125#[archive(check_bytes)]
1126pub struct SymbolsResponseData {
1127 #[serde(rename = "type")]
1128 pub product_type: String,
1129 pub product_id: u32,
1130 pub symbol: String,
1131 #[serde(
1132 serialize_with = "serialize_i128",
1133 deserialize_with = "deserialize_i128"
1134 )]
1135 pub price_increment_x18: i128,
1136 #[serde(
1137 serialize_with = "serialize_i128",
1138 deserialize_with = "deserialize_i128"
1139 )]
1140 pub size_increment: i128,
1141 #[serde(
1142 serialize_with = "serialize_i128",
1143 deserialize_with = "deserialize_i128"
1144 )]
1145 pub min_size: i128,
1146 #[serde(
1147 serialize_with = "serialize_i128",
1148 deserialize_with = "deserialize_i128"
1149 )]
1150 pub min_depth_x18: i128,
1151 #[serde(
1152 serialize_with = "serialize_i128",
1153 deserialize_with = "deserialize_i128"
1154 )]
1155 pub max_spread_rate_x18: i128,
1156 #[serde(
1157 serialize_with = "serialize_i128",
1158 deserialize_with = "deserialize_i128"
1159 )]
1160 pub maker_fee_rate_x18: i128,
1161 #[serde(
1162 serialize_with = "serialize_i128",
1163 deserialize_with = "deserialize_i128"
1164 )]
1165 pub taker_fee_rate_x18: i128,
1166 #[serde(
1167 serialize_with = "serialize_i128",
1168 deserialize_with = "deserialize_i128"
1169 )]
1170 pub long_weight_initial_x18: i128,
1171 #[serde(
1172 serialize_with = "serialize_i128",
1173 deserialize_with = "deserialize_i128"
1174 )]
1175 pub long_weight_maintenance_x18: i128,
1176 pub max_open_interest_x18: Option<WrappedI128>,
1177}
1178
1179impl SymbolsResponseData {
1180 pub fn placeholder() -> Self {
1181 Self {
1182 product_type: "placeholder".to_string(),
1183 ..Self::default()
1184 }
1185 }
1186}
1187
1188impl From<&Product> for SymbolsResponseData {
1189 fn from(product: &Product) -> Self {
1190 let product_type = match product {
1191 Product::Spot { .. } => "spot",
1192 Product::Perp { .. } => "perp",
1193 }
1194 .to_string();
1195 let max_open_interest = product.max_open_interest().and_then(|oi| {
1196 if oi == 0.0 {
1197 None
1198 } else {
1199 Some(WrappedI128(f64_to_x18(oi)))
1200 }
1201 });
1202
1203 match product {
1204 Product::Spot {
1205 symbol,
1206 long_weight_initial,
1207 long_weight_maintenance,
1208 size_increment,
1209 price_increment,
1210 min_size,
1211 product_id,
1212 ..
1213 }
1214 | Product::Perp {
1215 symbol,
1216 long_weight_initial,
1217 long_weight_maintenance,
1218 size_increment,
1219 price_increment,
1220 min_size,
1221 product_id,
1222 ..
1223 } => SymbolsResponseData {
1224 product_type,
1225 product_id: *product_id,
1226 symbol: symbol.clone(),
1227 price_increment_x18: f64_to_x18(*price_increment),
1228 min_size: f64_to_x18(*min_size),
1229 size_increment: f64_to_x18(*size_increment),
1230 long_weight_initial_x18: f64_to_x18(*long_weight_initial),
1231 long_weight_maintenance_x18: f64_to_x18(*long_weight_maintenance),
1232 max_open_interest_x18: max_open_interest,
1233 ..Self::default()
1234 },
1235 }
1236 }
1237}
1238
1239#[derive(
1240 Clone,
1241 Debug,
1242 Default,
1243 Eq,
1244 PartialEq,
1245 Serialize,
1246 Deserialize,
1247 Archive,
1248 RkyvSerialize,
1249 RkyvDeserialize,
1250)]
1251#[archive(check_bytes)]
1252pub struct MinDepositRate {
1253 #[serde(
1254 serialize_with = "serialize_i128",
1255 deserialize_with = "deserialize_i128"
1256 )]
1257 pub min_deposit_rate_x18: i128,
1258 pub product_id: u32,
1259}
1260
1261#[derive(
1262 Clone,
1263 Debug,
1264 Default,
1265 Eq,
1266 PartialEq,
1267 Serialize,
1268 Deserialize,
1269 Archive,
1270 RkyvSerialize,
1271 RkyvDeserialize,
1272)]
1273#[archive(check_bytes)]
1274pub struct MinDepositRatesResponse {
1275 pub min_deposit_rates: HashMap<String, MinDepositRate>,
1277}
1278
1279#[derive(
1280 Clone,
1281 Debug,
1282 Default,
1283 Eq,
1284 PartialEq,
1285 Serialize,
1286 Deserialize,
1287 Archive,
1288 RkyvSerialize,
1289 RkyvDeserialize,
1290)]
1291#[archive(check_bytes)]
1292pub struct IsolatedPosition {
1293 #[serde(
1294 serialize_with = "serialize_bytes32",
1295 deserialize_with = "deserialize_bytes32"
1296 )]
1297 pub subaccount: [u8; 32],
1298 pub quote_balance: SpotBalance,
1299 pub base_balance: PerpBalance,
1300 pub quote_product: SpotProduct,
1301 pub base_product: PerpProduct,
1302 #[serde(
1303 serialize_with = "serialize_vec_i128",
1304 deserialize_with = "deserialize_vec_i128"
1305 )]
1306 pub quote_healths: Vec<i128>,
1307 #[serde(
1308 serialize_with = "serialize_vec_i128",
1309 deserialize_with = "deserialize_vec_i128"
1310 )]
1311 pub base_healths: Vec<i128>,
1312 pub healths: Vec<HealthInfo>,
1313}
1314
1315#[derive(
1316 Clone,
1317 Debug,
1318 Default,
1319 Eq,
1320 PartialEq,
1321 Serialize,
1322 Deserialize,
1323 Archive,
1324 RkyvSerialize,
1325 RkyvDeserialize,
1326)]
1327#[archive(check_bytes)]
1328pub struct IsolatedPositionsResponse {
1329 pub isolated_positions: Vec<IsolatedPosition>,
1330}
1331
1332#[derive(
1333 Clone,
1334 Debug,
1335 Default,
1336 Eq,
1337 PartialEq,
1338 Serialize,
1339 Deserialize,
1340 Archive,
1341 RkyvSerialize,
1342 RkyvDeserialize,
1343)]
1344#[archive(check_bytes)]
1345pub struct PriceLevel(
1348 #[serde(
1349 serialize_with = "serialize_i128",
1350 deserialize_with = "deserialize_i128"
1351 )]
1352 pub i128,
1354 #[serde(
1355 serialize_with = "serialize_i128",
1356 deserialize_with = "deserialize_i128"
1357 )]
1358 pub i128,
1360);
1361
1362#[derive(
1363 Clone,
1364 Debug,
1365 Default,
1366 Eq,
1367 PartialEq,
1368 Serialize,
1369 Deserialize,
1370 Archive,
1371 RkyvSerialize,
1372 RkyvDeserialize,
1373)]
1374#[archive(check_bytes)]
1375pub struct MarketLiquidityResponse {
1378 pub bids: Vec<PriceLevel>,
1379 pub asks: Vec<PriceLevel>,
1380 pub product_id: u32,
1381 #[serde(serialize_with = "serialize_u64", deserialize_with = "deserialize_u64")]
1382 pub timestamp: u64,
1383}
1384
1385#[derive(
1386 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1387)]
1388#[archive(check_bytes)]
1389#[serde(rename_all = "snake_case")]
1392pub enum Status {
1393 Success,
1394 Failure,
1395}
1396
1397#[derive(
1398 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1399)]
1400#[archive(check_bytes)]
1401#[serde(rename_all = "snake_case")]
1404pub enum EngineStatus {
1405 Started,
1406 Active,
1408 Stopping,
1410 Syncing,
1412 LiveSyncing,
1414 Failed, }
1418
1419impl From<EngineStatus> for u8 {
1420 fn from(status: EngineStatus) -> Self {
1421 match status {
1422 EngineStatus::Started => 0,
1423 EngineStatus::Active => 1,
1424 EngineStatus::Stopping => 2,
1425 EngineStatus::Syncing => 3,
1426 EngineStatus::LiveSyncing => 4,
1427 EngineStatus::Failed => 5,
1428 }
1429 }
1430}
1431
1432impl From<u8> for EngineStatus {
1433 fn from(status: u8) -> Self {
1434 match status {
1435 0 => EngineStatus::Started,
1436 1 => EngineStatus::Active,
1437 2 => EngineStatus::Stopping,
1438 3 => EngineStatus::Syncing,
1439 4 => EngineStatus::LiveSyncing,
1440 5 => EngineStatus::Failed,
1441 _ => panic!("Invalid EngineStatus"),
1442 }
1443 }
1444}
1445
1446impl From<EngineStatus> for AtomicU8 {
1447 fn from(status: EngineStatus) -> Self {
1448 AtomicU8::new(status.into())
1449 }
1450}
1451
1452impl From<AtomicU8> for EngineStatus {
1453 fn from(status: AtomicU8) -> Self {
1454 EngineStatus::from(status.load(Ordering::Relaxed))
1455 }
1456}
1457
1458#[derive(
1459 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1460)]
1461#[archive(check_bytes)]
1462#[serde(rename_all = "snake_case")]
1465#[serde(untagged)]
1466pub enum QueryResponseData {
1467 StatusResponse(EngineStatus),
1468 Contracts(ContractsResponse),
1469 FeeRates(FeeRatesResponse),
1470 Nonces(NoncesResponse),
1471 LinkedSigner(LinkedSignerResponse),
1472 SubaccountInfo(SubaccountInfoResponse),
1473 MarketPrice(MarketPriceResponse),
1474 MarketPrices(MarketPricesResponse),
1475 Order(OrderResponse),
1476 Orders(OrdersResponse),
1477 ValidateOrder(ValidateOrderResponse),
1478 SubaccountOrders(SubaccountOrdersResponse),
1479 MarketLiquidity(MarketLiquidityResponse),
1480 AllProducts(AllProductsResponse),
1481 EdgeAllProducts(EdgeAllProductsResponse),
1482 MaxOrderSize(MaxOrderSizeResponse),
1483 MaxWithdrawable(MaxWithdrawableResponse),
1484 MaxLpMintable(MaxLpMintableResponse),
1485 MaxVlpMintable(MaxVlpMintableResponse),
1486 HealthGroups(HealthGroupsResponse),
1487 Insurance(InsuranceResponse),
1488 Symbols(SymbolsResponse),
1489 MinDepositRates(MinDepositRatesResponse),
1490 IsolatedPositions(IsolatedPositionsResponse),
1491 Error(String),
1492}
1493
1494#[derive(
1495 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1496)]
1497#[archive(check_bytes)]
1498#[serde(rename_all = "snake_case")]
1501pub struct QueryResponse {
1502 pub status: Status,
1503 #[serde(skip_serializing_if = "Option::is_none")]
1504 pub data: Option<QueryResponseData>,
1505 #[serde(skip_serializing_if = "Option::is_none")]
1506 pub error_code: Option<i32>,
1507 #[serde(skip_serializing_if = "Option::is_none")]
1508 pub error: Option<String>,
1509 #[serde(skip_serializing_if = "Option::is_none")]
1510 pub request_type: Option<String>,
1511}
1512
1513#[derive(
1514 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1515)]
1516#[archive(check_bytes)]
1517pub struct ExecuteResponse {
1520 pub status: Status,
1521 #[serde(
1522 serialize_with = "serialize_option_vec_u8",
1523 deserialize_with = "deserialize_option_vec_u8"
1524 )]
1525 #[serde(skip_serializing_if = "Option::is_none")]
1526 #[serde(default)]
1527 pub signature: Option<Vec<u8>>,
1528 #[serde(skip_serializing_if = "Option::is_none")]
1529 #[serde(default)]
1530 pub id: Option<u64>,
1531 #[serde(skip_serializing_if = "Option::is_none")]
1532 pub data: Option<ExecuteResponseData>,
1533 #[serde(skip_serializing_if = "Option::is_none")]
1534 pub error_code: Option<i32>,
1535 #[serde(skip_serializing_if = "Option::is_none")]
1536 pub error: Option<String>,
1537 #[serde(skip_serializing_if = "Option::is_none")]
1538 pub request_type: Option<String>,
1539}
1540
1541#[derive(
1542 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1543)]
1544#[archive(check_bytes)]
1545#[serde(untagged)]
1546#[serde(rename_all = "snake_case")]
1547pub enum ExecuteResponseData {
1548 PlaceOrder(PlaceOrderResponse),
1549 CancelOrders(CancelOrdersResponse),
1550 CancelProductOrders(CancelOrdersResponse),
1551 PlaceIsolatedOrder(PlaceOrderResponse),
1552}
1553
1554#[derive(
1555 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1556)]
1557#[archive(check_bytes)]
1558pub struct CancelOrdersResponse {
1559 pub cancelled_orders: Vec<OrderResponse>,
1560}
1561
1562#[derive(
1563 Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1564)]
1565#[archive(check_bytes)]
1566pub struct PlaceOrderResponse {
1567 #[serde(
1568 serialize_with = "serialize_bytes32",
1569 deserialize_with = "deserialize_bytes32"
1570 )]
1571 pub digest: [u8; 32],
1572}
1573
1574#[derive(
1575 Archive, RkyvDeserialize, RkyvSerialize, Clone, Debug, Eq, PartialEq, Serialize, Deserialize,
1576)]
1577#[serde(untagged)]
1578#[archive(check_bytes)]
1579pub enum EngineResponse {
1580 Query(QueryResponse),
1581 Execute(ExecuteResponse),
1582}
1583
1584#[derive(Archive, RkyvDeserialize, RkyvSerialize, Serialize, Deserialize, Debug, Clone)]
1585#[archive(check_bytes)]
1586#[serde(rename_all = "snake_case")]
1587pub enum QueryV2 {
1590 Orderbook(OrderbookParams),
1591
1592 Pairs(MarketPairsParams),
1593
1594 Assets {},
1595
1596 Apr {},
1597}
1598
1599#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
1600#[archive(check_bytes)]
1601#[serde(rename_all = "snake_case")]
1602pub struct OrderbookParams {
1603 pub ticker_id: String,
1604 #[serde(deserialize_with = "str_or_u32")]
1605 pub depth: u32,
1606}
1607
1608#[derive(Archive, RkyvDeserialize, RkyvSerialize, Clone, Serialize, Deserialize, Debug)]
1609#[archive(check_bytes)]
1610#[serde(rename_all = "snake_case")]
1611pub struct MarketPairsParams {
1612 pub market: Option<String>,
1613}
1614
1615#[derive(
1616 Clone,
1617 Debug,
1618 Default,
1619 PartialEq,
1620 Serialize,
1621 Deserialize,
1622 Archive,
1623 RkyvSerialize,
1624 RkyvDeserialize,
1625)]
1626#[archive(check_bytes)]
1627pub struct OrderbookPriceLevel(pub f64, pub f64);
1628
1629#[derive(
1630 Clone,
1631 Debug,
1632 Default,
1633 PartialEq,
1634 Serialize,
1635 Deserialize,
1636 Archive,
1637 RkyvSerialize,
1638 RkyvDeserialize,
1639)]
1640#[archive(check_bytes)]
1641pub struct OrderbookResponse {
1644 pub ticker_id: String,
1645 pub bids: Vec<OrderbookPriceLevel>,
1646 pub asks: Vec<OrderbookPriceLevel>,
1647 pub timestamp: u64,
1648}
1649
1650#[derive(
1651 Clone,
1652 Debug,
1653 Default,
1654 Eq,
1655 PartialEq,
1656 Serialize,
1657 Deserialize,
1658 Archive,
1659 RkyvSerialize,
1660 RkyvDeserialize,
1661)]
1662#[archive(check_bytes)]
1663pub struct MarketPair {
1666 pub ticker_id: String,
1667 pub base: String,
1668 pub quote: String,
1669}
1670
1671pub type MarketPairsResponse = Vec<MarketPair>;
1672
1673#[derive(
1674 Clone, Debug, Default, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize,
1675)]
1676#[archive(check_bytes)]
1677pub struct MarketApr {
1678 pub name: String,
1679 pub symbol: String,
1680 pub product_id: u32,
1681 pub deposit_apr: f64,
1682 pub borrow_apr: f64,
1683 pub tvl: f64,
1684}
1685
1686pub type MarketsAprResponse = Vec<MarketApr>;
1687
1688#[derive(
1689 Clone,
1690 Debug,
1691 Default,
1692 PartialEq,
1693 Serialize,
1694 Deserialize,
1695 Archive,
1696 RkyvSerialize,
1697 RkyvDeserialize,
1698)]
1699#[archive(check_bytes)]
1700pub struct Asset {
1703 pub product_id: u32,
1704 pub ticker_id: Option<String>,
1705 pub market_type: Option<String>,
1706 pub name: String,
1707 pub symbol: String,
1708 pub maker_fee: Option<f64>,
1709 pub taker_fee: Option<f64>,
1710 pub can_withdraw: bool,
1711 pub can_deposit: bool,
1712}
1713
1714pub type AssetsResponse = Vec<Asset>;