1use alloy_primitives::Address;
7use chrono::{DateTime, Utc};
8use rust_decimal::prelude::ToPrimitive;
9use rust_decimal::Decimal;
10use serde::{Deserialize, Serialize};
11
12pub type Price = u32;
43
44pub type Qty = i64;
56
57pub const SCALE_FACTOR: i64 = 10_000;
63
64pub const MAX_PRICE_TICKS: Price = Price::MAX;
67
68pub const MIN_PRICE_TICKS: Price = 1;
70
71pub const MAX_QTY: Qty = Qty::MAX / 2; pub fn decimal_to_price(decimal: Decimal) -> std::result::Result<Price, &'static str> {
93 let scaled = decimal * Decimal::from(SCALE_FACTOR);
95
96 let rounded = scaled.round();
98
99 let as_u64 = rounded.to_u64().ok_or("Price too large or negative")?;
101
102 if as_u64 < MIN_PRICE_TICKS as u64 {
104 return Ok(MIN_PRICE_TICKS); }
106 if as_u64 > MAX_PRICE_TICKS as u64 {
107 return Err("Price exceeds maximum");
108 }
109
110 Ok(as_u64 as Price)
111}
112
113pub fn price_to_decimal(ticks: Price) -> Decimal {
122 Decimal::from(ticks) / Decimal::from(SCALE_FACTOR)
123}
124
125pub fn decimal_to_qty(decimal: Decimal) -> std::result::Result<Qty, &'static str> {
134 let scaled = decimal * Decimal::from(SCALE_FACTOR);
135 let rounded = scaled.round();
136
137 let as_i64 = rounded.to_i64().ok_or("Quantity too large")?;
138
139 if as_i64.abs() > MAX_QTY {
140 return Err("Quantity exceeds maximum");
141 }
142
143 Ok(as_i64)
144}
145
146pub fn qty_to_decimal(units: Qty) -> Decimal {
152 Decimal::from(units) / Decimal::from(SCALE_FACTOR)
153}
154
155pub fn is_price_tick_aligned(decimal: Decimal, tick_size_decimal: Decimal) -> bool {
165 let tick_size_ticks = match decimal_to_price(tick_size_decimal) {
167 Ok(ticks) => ticks,
168 Err(_) => return false,
169 };
170
171 let price_ticks = match decimal_to_price(decimal) {
173 Ok(ticks) => ticks,
174 Err(_) => return false,
175 };
176
177 if tick_size_ticks == 0 {
180 return true;
181 }
182
183 price_ticks % tick_size_ticks == 0
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
188#[allow(clippy::upper_case_acronyms)]
189pub enum Side {
190 BUY = 0,
191 SELL = 1,
192}
193
194impl Side {
195 pub fn as_str(&self) -> &'static str {
196 match self {
197 Side::BUY => "BUY",
198 Side::SELL => "SELL",
199 }
200 }
201
202 pub fn opposite(&self) -> Self {
203 match self {
204 Side::BUY => Side::SELL,
205 Side::SELL => Side::BUY,
206 }
207 }
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
212#[allow(clippy::upper_case_acronyms)]
213pub enum OrderType {
214 #[default]
215 GTC,
216 FOK,
217 GTD,
218 FAK,
219}
220
221impl OrderType {
222 pub fn as_str(&self) -> &'static str {
223 match self {
224 OrderType::GTC => "GTC",
225 OrderType::FOK => "FOK",
226 OrderType::GTD => "GTD",
227 OrderType::FAK => "FAK",
228 }
229 }
230}
231
232#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
234pub enum OrderStatus {
235 #[serde(rename = "LIVE")]
236 Live,
237 #[serde(rename = "CANCELLED")]
238 Cancelled,
239 #[serde(rename = "FILLED")]
240 Filled,
241 #[serde(rename = "PARTIAL")]
242 Partial,
243 #[serde(rename = "EXPIRED")]
244 Expired,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct MarketSnapshot {
250 pub token_id: String,
251 pub market_id: String,
252 pub timestamp: DateTime<Utc>,
253 pub bid: Option<Decimal>,
254 pub ask: Option<Decimal>,
255 pub mid: Option<Decimal>,
256 pub spread: Option<Decimal>,
257 pub last_price: Option<Decimal>,
258 pub volume_24h: Option<Decimal>,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct BookLevel {
267 #[serde(with = "rust_decimal::serde::str")]
268 pub price: Decimal,
269 #[serde(with = "rust_decimal::serde::str")]
270 pub size: Decimal,
271}
272
273#[derive(Debug, Clone, Copy, PartialEq, Eq)]
284pub struct FastBookLevel {
285 pub price: Price, pub size: Qty, }
288
289impl FastBookLevel {
290 pub fn new(price: Price, size: Qty) -> Self {
292 Self { price, size }
293 }
294
295 pub fn to_book_level(self) -> BookLevel {
298 BookLevel {
299 price: price_to_decimal(self.price),
300 size: qty_to_decimal(self.size),
301 }
302 }
303
304 pub fn from_book_level(level: &BookLevel) -> std::result::Result<Self, &'static str> {
307 let price = decimal_to_price(level.price)?;
308 let size = decimal_to_qty(level.size)?;
309 Ok(Self::new(price, size))
310 }
311
312 pub fn notional(self) -> i64 {
319 let price_i64 = self.price as i64;
321 (price_i64 * self.size) / SCALE_FACTOR
323 }
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct OrderBook {
329 pub token_id: String,
331 pub timestamp: DateTime<Utc>,
333 pub bids: Vec<BookLevel>,
335 pub asks: Vec<BookLevel>,
337 pub sequence: u64,
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct OrderDelta {
347 pub token_id: String,
348 pub timestamp: DateTime<Utc>,
349 pub side: Side,
350 pub price: Decimal,
351 pub size: Decimal, pub sequence: u64,
353}
354
355#[derive(Debug, Clone, Copy, PartialEq, Eq)]
366pub struct FastOrderDelta {
367 pub token_id_hash: u64, pub timestamp: DateTime<Utc>,
369 pub side: Side,
370 pub price: Price, pub size: Qty, pub sequence: u64,
373}
374
375impl FastOrderDelta {
376 pub fn from_order_delta(
382 delta: &OrderDelta,
383 tick_size: Option<Decimal>,
384 ) -> std::result::Result<Self, &'static str> {
385 if let Some(tick_size) = tick_size {
387 if !is_price_tick_aligned(delta.price, tick_size) {
388 return Err("Price not aligned to tick size");
389 }
390 }
391
392 let price = decimal_to_price(delta.price)?;
394 let size = decimal_to_qty(delta.size)?;
395
396 let token_id_hash = {
399 use std::collections::hash_map::DefaultHasher;
400 use std::hash::{Hash, Hasher};
401 let mut hasher = DefaultHasher::new();
402 delta.token_id.hash(&mut hasher);
403 hasher.finish()
404 };
405
406 Ok(Self {
407 token_id_hash,
408 timestamp: delta.timestamp,
409 side: delta.side,
410 price,
411 size,
412 sequence: delta.sequence,
413 })
414 }
415
416 pub fn to_order_delta(self, token_id: String) -> OrderDelta {
419 OrderDelta {
420 token_id,
421 timestamp: self.timestamp,
422 side: self.side,
423 price: price_to_decimal(self.price),
424 size: qty_to_decimal(self.size),
425 sequence: self.sequence,
426 }
427 }
428
429 pub fn is_removal(self) -> bool {
431 self.size == 0
432 }
433}
434
435#[derive(Debug, Clone, Serialize, Deserialize)]
437pub struct FillEvent {
438 pub id: String,
439 pub order_id: String,
440 pub token_id: String,
441 pub side: Side,
442 pub price: Decimal,
443 pub size: Decimal,
444 pub timestamp: DateTime<Utc>,
445 pub maker_address: Address,
446 pub taker_address: Address,
447 pub fee: Decimal,
448}
449
450#[derive(Debug, Clone)]
452pub struct OrderRequest {
453 pub token_id: String,
454 pub side: Side,
455 pub price: Decimal,
456 pub size: Decimal,
457 pub order_type: OrderType,
458 pub expiration: Option<DateTime<Utc>>,
459 pub client_id: Option<String>,
460}
461
462#[derive(Debug, Clone)]
464pub struct MarketOrderRequest {
465 pub token_id: String,
466 pub side: Side,
467 pub amount: Decimal, pub slippage_tolerance: Option<Decimal>,
469 pub client_id: Option<String>,
470}
471
472#[derive(Debug, Clone, Serialize, Deserialize)]
474pub struct Order {
475 pub id: String,
476 pub token_id: String,
477 pub side: Side,
478 pub price: Decimal,
479 pub original_size: Decimal,
480 pub filled_size: Decimal,
481 pub remaining_size: Decimal,
482 pub status: OrderStatus,
483 pub order_type: OrderType,
484 pub created_at: DateTime<Utc>,
485 pub updated_at: DateTime<Utc>,
486 pub expiration: Option<DateTime<Utc>>,
487 pub client_id: Option<String>,
488}
489
490#[derive(Debug, Clone, Serialize, Deserialize, Default)]
492pub struct ApiCredentials {
493 #[serde(rename = "apiKey")]
494 pub api_key: String,
495 pub secret: String,
496 pub passphrase: String,
497}
498
499#[derive(Debug, Clone, PartialEq)]
501pub struct OrderArgs {
502 pub token_id: String,
503 pub price: Decimal,
504 pub size: Decimal,
505 pub side: Side,
506 pub expiration: Option<u64>,
507 pub builder_code: Option<String>,
508 pub metadata: Option<String>,
509}
510
511impl OrderArgs {
512 pub fn new(token_id: &str, price: Decimal, size: Decimal, side: Side) -> Self {
513 Self {
514 token_id: token_id.to_string(),
515 price,
516 size,
517 side,
518 expiration: None,
519 builder_code: None,
520 metadata: None,
521 }
522 }
523}
524
525impl Default for OrderArgs {
526 fn default() -> Self {
527 Self {
528 token_id: String::new(),
529 price: Decimal::ZERO,
530 size: Decimal::ZERO,
531 side: Side::BUY,
532 expiration: None,
533 builder_code: None,
534 metadata: None,
535 }
536 }
537}
538
539#[derive(Debug, Clone, PartialEq)]
541pub struct MarketOrderArgs {
542 pub token_id: String,
543 pub amount: Decimal,
544 pub side: Side,
545 pub order_type: OrderType,
546 pub price_limit: Option<Decimal>,
547 pub user_usdc_balance: Option<Decimal>,
548 pub builder_code: Option<String>,
549 pub metadata: Option<String>,
550}
551
552impl MarketOrderArgs {
553 pub fn new(token_id: &str, amount: Decimal, side: Side, order_type: OrderType) -> Self {
554 Self {
555 token_id: token_id.to_string(),
556 amount,
557 side,
558 order_type,
559 price_limit: None,
560 user_usdc_balance: None,
561 builder_code: None,
562 metadata: None,
563 }
564 }
565}
566
567#[derive(Debug, Clone, Copy, Default, PartialEq)]
569pub struct CreateOrderOptions {
570 pub tick_size: Option<Decimal>,
571 pub neg_risk: Option<bool>,
572}
573
574#[derive(Debug, Clone, Copy, PartialEq, Eq)]
576pub struct PostOrderOptions {
577 pub order_type: OrderType,
578 pub post_only: bool,
579 pub defer_exec: bool,
580}
581
582impl Default for PostOrderOptions {
583 fn default() -> Self {
584 Self {
585 order_type: OrderType::GTC,
586 post_only: false,
587 defer_exec: false,
588 }
589 }
590}
591
592#[derive(Debug, Clone, Serialize, Deserialize)]
594#[serde(rename_all = "camelCase")]
595pub struct SignedOrderRequest {
596 pub salt: u64,
597 pub maker: String,
598 pub signer: String,
599 pub token_id: String,
600 pub maker_amount: String,
601 pub taker_amount: String,
602 pub expiration: String,
603 pub side: String,
604 pub signature_type: u8,
605 pub timestamp: String,
606 pub metadata: String,
607 pub builder: String,
608 pub signature: String,
609}
610
611#[derive(Debug, Serialize)]
613#[serde(rename_all = "camelCase")]
614pub struct PostOrder {
615 pub order: SignedOrderRequest,
616 pub owner: String,
617 pub order_type: OrderType,
618 pub post_only: bool,
619 pub defer_exec: bool,
620}
621
622impl PostOrder {
623 pub fn new(order: SignedOrderRequest, owner: String, options: PostOrderOptions) -> Self {
624 Self {
625 order,
626 owner,
627 order_type: options.order_type,
628 post_only: options.post_only,
629 defer_exec: options.defer_exec,
630 }
631 }
632}
633
634#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
636#[serde(rename_all = "camelCase")]
637pub struct PostOrderResponse {
638 pub success: bool,
639 #[serde(rename = "orderID")]
640 pub order_id: String,
641 pub status: String,
642 pub making_amount: String,
643 pub taking_amount: String,
644 #[serde(default)]
645 pub transactions_hashes: Vec<String>,
646 #[serde(default)]
647 pub trade_ids: Vec<String>,
648 #[serde(default)]
649 pub error_msg: String,
650}
651
652#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
654#[serde(rename_all = "camelCase")]
655pub struct CancelOrdersResponse {
656 #[serde(default)]
657 pub canceled: Vec<String>,
658 #[serde(default, alias = "not_canceled")]
659 pub not_canceled: std::collections::HashMap<String, String>,
660}
661
662#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
664pub struct ClobTokenInfo {
665 pub t: String,
666 pub o: String,
667}
668
669#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
671pub struct ClobFeeDetails {
672 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
673 pub r: Decimal,
674 pub e: u32,
675 #[serde(default)]
676 pub to: bool,
677}
678
679#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
681pub struct ClobMarketInfo {
682 #[serde(default)]
683 pub c: Option<String>,
684 #[serde(default)]
685 pub gst: Option<String>,
686 #[serde(default)]
687 pub r: serde_json::Value,
688 #[serde(default)]
689 pub t: Vec<ClobTokenInfo>,
690 #[serde(
691 default,
692 deserialize_with = "crate::decode::deserializers::decimal_from_string_or_zero"
693 )]
694 pub mos: Decimal,
695 #[serde(
696 default,
697 deserialize_with = "crate::decode::deserializers::decimal_from_string_or_zero"
698 )]
699 pub mts: Decimal,
700 #[serde(
701 default,
702 deserialize_with = "crate::decode::deserializers::decimal_from_string_or_zero"
703 )]
704 pub mbf: Decimal,
705 #[serde(
706 default,
707 deserialize_with = "crate::decode::deserializers::decimal_from_string_or_zero"
708 )]
709 pub tbf: Decimal,
710 #[serde(default)]
711 pub rfqe: bool,
712 #[serde(default)]
713 pub itode: bool,
714 #[serde(default)]
715 pub ibce: bool,
716 #[serde(default)]
717 pub nr: Option<bool>,
718 #[serde(default)]
719 pub fd: Option<ClobFeeDetails>,
720 #[serde(
721 default,
722 deserialize_with = "crate::decode::deserializers::optional_number_from_string"
723 )]
724 pub oas: Option<u64>,
725}
726
727#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
729#[serde(rename_all = "camelCase")]
730pub struct BuilderFeeRateResponse {
731 #[serde(alias = "builder_maker_fee_rate_bps")]
732 pub builder_maker_fee_rate_bps: u32,
733 #[serde(alias = "builder_taker_fee_rate_bps")]
734 pub builder_taker_fee_rate_bps: u32,
735}
736
737#[derive(Debug, Clone, Serialize, Deserialize)]
739pub struct Market {
740 pub condition_id: String,
741 pub tokens: [Token; 2],
742 pub rewards: Rewards,
743 pub min_incentive_size: Option<String>,
744 pub max_incentive_spread: Option<String>,
745 pub active: bool,
746 pub closed: bool,
747 pub question_id: String,
748 pub minimum_order_size: Decimal,
749 pub minimum_tick_size: Decimal,
750 pub description: String,
751 pub category: Option<String>,
752 pub end_date_iso: Option<String>,
753 pub game_start_time: Option<String>,
754 pub question: String,
755 pub market_slug: String,
756 pub seconds_delay: Decimal,
757 pub icon: String,
758 pub fpmm: String,
759 #[serde(default)]
761 pub enable_order_book: bool,
762 #[serde(default)]
763 pub archived: bool,
764 #[serde(default)]
765 pub accepting_orders: bool,
766 #[serde(default)]
767 pub accepting_order_timestamp: Option<String>,
768 #[serde(default)]
769 pub maker_base_fee: Decimal,
770 #[serde(default)]
771 pub taker_base_fee: Decimal,
772 #[serde(default)]
773 pub notifications_enabled: bool,
774 #[serde(default)]
775 pub neg_risk: bool,
776 #[serde(default)]
777 pub neg_risk_market_id: String,
778 #[serde(default)]
779 pub neg_risk_request_id: String,
780 #[serde(default)]
781 pub image: String,
782 #[serde(default)]
783 pub is_50_50_outcome: bool,
784}
785
786#[derive(Debug, Clone, Serialize, Deserialize)]
788pub struct Token {
789 pub token_id: String,
790 pub outcome: String,
791 pub price: Decimal,
792 #[serde(default)]
793 pub winner: bool,
794}
795
796#[derive(Debug, Clone, Serialize, Deserialize)]
798pub struct ClientConfig {
799 pub base_url: String,
801 pub chain: u64,
803 pub private_key: Option<String>,
805 pub api_credentials: Option<ApiCredentials>,
807 pub builder_code: Option<String>,
809 pub signature_type: Option<u8>,
811 pub funder: Option<String>,
814 pub timeout: Option<std::time::Duration>,
816 pub max_connections: Option<usize>,
818}
819
820impl Default for ClientConfig {
821 fn default() -> Self {
822 Self {
823 base_url: "https://clob.polymarket.com".to_string(),
824 chain: 137, private_key: None,
826 api_credentials: None,
827 builder_code: None,
828 signature_type: None,
829 funder: None,
830 timeout: Some(std::time::Duration::from_secs(30)),
831 max_connections: Some(100),
832 }
833 }
834}
835
836pub type WssAuth = ApiCredentials;
841
842#[derive(Debug, Clone, Serialize, Deserialize)]
844pub struct WssSubscription {
845 #[serde(rename = "type")]
847 pub channel_type: String,
848 #[serde(skip_serializing_if = "Option::is_none")]
850 pub operation: Option<String>,
851 #[serde(default)]
853 pub markets: Vec<String>,
854 #[serde(rename = "assets_ids", default)]
857 pub asset_ids: Vec<String>,
858 #[serde(skip_serializing_if = "Option::is_none")]
860 pub initial_dump: Option<bool>,
861 #[serde(skip_serializing_if = "Option::is_none")]
863 pub custom_feature_enabled: Option<bool>,
864 #[serde(skip_serializing_if = "Option::is_none")]
866 pub auth: Option<WssAuth>,
867}
868
869#[derive(Debug, Clone, Serialize, Deserialize)]
871#[serde(tag = "event_type")]
872pub enum StreamMessage {
873 #[serde(rename = "book")]
875 Book(BookUpdate),
876 #[serde(rename = "price_change")]
878 PriceChange(PriceChange),
879 #[serde(rename = "tick_size_change")]
881 TickSizeChange(TickSizeChange),
882 #[serde(rename = "last_trade_price")]
884 LastTradePrice(LastTradePrice),
885 #[serde(rename = "best_bid_ask")]
887 BestBidAsk(BestBidAsk),
888 #[serde(rename = "new_market")]
890 NewMarket(NewMarket),
891 #[serde(rename = "market_resolved")]
893 MarketResolved(MarketResolved),
894 #[serde(rename = "trade")]
896 Trade(TradeMessage),
897 #[serde(rename = "order")]
899 Order(OrderMessage),
900 #[serde(other)]
902 Unknown,
903}
904
905#[derive(Debug, Clone, Serialize, Deserialize)]
907pub struct BookUpdate {
908 pub asset_id: String,
909 pub market: String,
910 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
911 pub timestamp: u64,
912 #[serde(
913 default,
914 deserialize_with = "crate::decode::deserializers::vec_from_null"
915 )]
916 pub bids: Vec<OrderSummary>,
917 #[serde(
918 default,
919 deserialize_with = "crate::decode::deserializers::vec_from_null"
920 )]
921 pub asks: Vec<OrderSummary>,
922 #[serde(default)]
923 pub hash: Option<String>,
924}
925
926#[derive(Debug, Clone, Serialize, Deserialize)]
928pub struct PriceChange {
929 pub market: String,
930 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
931 pub timestamp: u64,
932 #[serde(
933 default,
934 deserialize_with = "crate::decode::deserializers::vec_from_null"
935 )]
936 pub price_changes: Vec<PriceChangeEntry>,
937}
938
939#[derive(Debug, Clone, Serialize, Deserialize)]
940pub struct PriceChangeEntry {
941 pub asset_id: String,
942 pub price: Decimal,
943 #[serde(
944 default,
945 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
946 )]
947 pub size: Option<Decimal>,
948 pub side: Side,
949 #[serde(default)]
950 pub hash: Option<String>,
951 #[serde(
952 default,
953 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
954 )]
955 pub best_bid: Option<Decimal>,
956 #[serde(
957 default,
958 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
959 )]
960 pub best_ask: Option<Decimal>,
961}
962
963#[derive(Debug, Clone, Serialize, Deserialize)]
965pub struct TickSizeChange {
966 pub asset_id: String,
967 pub market: String,
968 pub old_tick_size: Decimal,
969 pub new_tick_size: Decimal,
970 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
971 pub timestamp: u64,
972}
973
974#[derive(Debug, Clone, Serialize, Deserialize)]
976pub struct LastTradePrice {
977 pub asset_id: String,
978 pub market: String,
979 pub price: Decimal,
980 #[serde(default)]
981 pub side: Option<Side>,
982 #[serde(
983 default,
984 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
985 )]
986 pub size: Option<Decimal>,
987 #[serde(
988 default,
989 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
990 )]
991 pub fee_rate_bps: Option<Decimal>,
992 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
993 pub timestamp: u64,
994}
995
996#[derive(Debug, Clone, Serialize, Deserialize)]
998pub struct BestBidAsk {
999 pub market: String,
1000 pub asset_id: String,
1001 pub best_bid: Decimal,
1002 pub best_ask: Decimal,
1003 pub spread: Decimal,
1004 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1005 pub timestamp: u64,
1006}
1007
1008#[derive(Debug, Clone, Serialize, Deserialize)]
1010pub struct NewMarket {
1011 pub id: String,
1012 pub question: String,
1013 pub market: String,
1014 pub slug: String,
1015 pub description: String,
1016 #[serde(rename = "assets_ids", alias = "asset_ids")]
1017 pub asset_ids: Vec<String>,
1018 #[serde(
1019 default,
1020 deserialize_with = "crate::decode::deserializers::vec_from_null"
1021 )]
1022 pub outcomes: Vec<String>,
1023 #[serde(default)]
1024 pub event_message: Option<EventMessage>,
1025 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1026 pub timestamp: u64,
1027}
1028
1029#[derive(Debug, Clone, Serialize, Deserialize)]
1031pub struct MarketResolved {
1032 pub id: String,
1033 #[serde(default)]
1034 pub question: Option<String>,
1035 pub market: String,
1036 #[serde(default)]
1037 pub slug: Option<String>,
1038 #[serde(default)]
1039 pub description: Option<String>,
1040 #[serde(rename = "assets_ids", alias = "asset_ids")]
1041 pub asset_ids: Vec<String>,
1042 #[serde(
1043 default,
1044 deserialize_with = "crate::decode::deserializers::vec_from_null"
1045 )]
1046 pub outcomes: Vec<String>,
1047 pub winning_asset_id: String,
1048 pub winning_outcome: String,
1049 #[serde(default)]
1050 pub event_message: Option<EventMessage>,
1051 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1052 pub timestamp: u64,
1053}
1054
1055#[derive(Debug, Clone, Serialize, Deserialize)]
1057pub struct EventMessage {
1058 pub id: String,
1059 pub ticker: String,
1060 pub slug: String,
1061 pub title: String,
1062 pub description: String,
1063}
1064
1065#[derive(Debug, Clone, Serialize, Deserialize)]
1067pub struct TradeMessage {
1068 pub id: String,
1069 pub market: String,
1070 pub asset_id: String,
1071 pub side: Side,
1072 pub size: Decimal,
1073 pub price: Decimal,
1074 #[serde(default)]
1075 pub status: Option<String>,
1076 #[serde(rename = "type", default)]
1077 pub msg_type: Option<String>,
1078 #[serde(
1079 default,
1080 deserialize_with = "crate::decode::deserializers::optional_number_from_string"
1081 )]
1082 pub last_update: Option<u64>,
1083 #[serde(
1084 default,
1085 alias = "match_time",
1086 deserialize_with = "crate::decode::deserializers::optional_number_from_string"
1087 )]
1088 pub matchtime: Option<u64>,
1089 #[serde(
1090 default,
1091 deserialize_with = "crate::decode::deserializers::optional_number_from_string"
1092 )]
1093 pub timestamp: Option<u64>,
1094}
1095
1096#[derive(Debug, Clone, Serialize, Deserialize)]
1098pub struct OrderMessage {
1099 pub id: String,
1100 pub market: String,
1101 pub asset_id: String,
1102 pub side: Side,
1103 pub price: Decimal,
1104 #[serde(rename = "type", default)]
1105 pub msg_type: Option<String>,
1106 #[serde(
1107 default,
1108 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
1109 )]
1110 pub original_size: Option<Decimal>,
1111 #[serde(
1112 default,
1113 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string"
1114 )]
1115 pub size_matched: Option<Decimal>,
1116 #[serde(
1117 default,
1118 deserialize_with = "crate::decode::deserializers::optional_number_from_string"
1119 )]
1120 pub timestamp: Option<u64>,
1121 #[serde(default)]
1122 pub associate_trades: Option<Vec<String>>,
1123 #[serde(default)]
1124 pub status: Option<String>,
1125}
1126
1127#[derive(Debug, Clone, Serialize, Deserialize)]
1129pub struct Subscription {
1130 pub token_ids: Vec<String>,
1131 pub channels: Vec<String>,
1132}
1133
1134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
1136pub enum WssChannelType {
1137 #[serde(rename = "USER")]
1138 User,
1139 #[serde(rename = "MARKET")]
1140 Market,
1141}
1142
1143impl WssChannelType {
1144 pub fn as_str(&self) -> &'static str {
1145 match self {
1146 WssChannelType::User => "USER",
1147 WssChannelType::Market => "MARKET",
1148 }
1149 }
1150}
1151
1152#[derive(Debug, Clone, Serialize, Deserialize)]
1154pub struct Quote {
1155 pub token_id: String,
1156 pub side: Side,
1157 #[serde(with = "rust_decimal::serde::str")]
1158 pub price: Decimal,
1159 pub timestamp: DateTime<Utc>,
1160}
1161
1162#[derive(Debug, Clone, Serialize, Deserialize)]
1164pub struct Balance {
1165 pub token_id: String,
1166 pub available: Decimal,
1167 pub locked: Decimal,
1168 pub total: Decimal,
1169}
1170
1171#[derive(Debug, Clone)]
1173pub struct Metrics {
1174 pub orders_per_second: f64,
1175 pub avg_latency_ms: f64,
1176 pub error_rate: f64,
1177 pub uptime_pct: f64,
1178}
1179
1180pub type TokenId = String;
1182pub type OrderId = String;
1183pub type MarketId = String;
1184pub type ClientId = String;
1185
1186#[derive(Debug, Clone)]
1188pub struct OpenOrderParams {
1189 pub id: Option<String>,
1190 pub asset_id: Option<String>,
1191 pub market: Option<String>,
1192}
1193
1194impl OpenOrderParams {
1195 pub fn to_query_params(&self) -> Vec<(&str, &String)> {
1196 let mut params = Vec::with_capacity(3);
1197
1198 if let Some(x) = &self.id {
1199 params.push(("id", x));
1200 }
1201
1202 if let Some(x) = &self.asset_id {
1203 params.push(("asset_id", x));
1204 }
1205
1206 if let Some(x) = &self.market {
1207 params.push(("market", x));
1208 }
1209 params
1210 }
1211}
1212
1213#[derive(Debug, Clone)]
1215pub struct TradeParams {
1216 pub id: Option<String>,
1217 pub maker_address: Option<String>,
1218 pub market: Option<String>,
1219 pub asset_id: Option<String>,
1220 pub before: Option<u64>,
1221 pub after: Option<u64>,
1222}
1223
1224impl TradeParams {
1225 pub fn to_query_params(&self) -> Vec<(&str, String)> {
1226 let mut params = Vec::with_capacity(6);
1227
1228 if let Some(x) = &self.id {
1229 params.push(("id", x.clone()));
1230 }
1231
1232 if let Some(x) = &self.asset_id {
1233 params.push(("asset_id", x.clone()));
1234 }
1235
1236 if let Some(x) = &self.market {
1237 params.push(("market", x.clone()));
1238 }
1239
1240 if let Some(x) = &self.maker_address {
1241 params.push(("maker_address", x.clone()));
1242 }
1243
1244 if let Some(x) = &self.before {
1245 params.push(("before", x.to_string()));
1246 }
1247
1248 if let Some(x) = &self.after {
1249 params.push(("after", x.to_string()));
1250 }
1251
1252 params
1253 }
1254}
1255
1256#[derive(Debug, Clone, Serialize, Deserialize)]
1258pub struct OpenOrder {
1259 pub associate_trades: Vec<String>,
1260 pub id: String,
1261 pub status: String,
1262 pub market: String,
1263 #[serde(with = "rust_decimal::serde::str")]
1264 pub original_size: Decimal,
1265 pub outcome: String,
1266 pub maker_address: String,
1267 pub owner: String,
1268 #[serde(with = "rust_decimal::serde::str")]
1269 pub price: Decimal,
1270 pub side: Side,
1271 #[serde(with = "rust_decimal::serde::str")]
1272 pub size_matched: Decimal,
1273 pub asset_id: String,
1274 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1275 pub expiration: u64,
1276 #[serde(rename = "type", alias = "order_type", alias = "orderType", default)]
1277 pub order_type: OrderType,
1278 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1279 pub created_at: u64,
1280}
1281
1282#[derive(Debug, Clone, Serialize, Deserialize)]
1284pub struct BalanceAllowance {
1285 pub asset_id: String,
1286 #[serde(with = "rust_decimal::serde::str")]
1287 pub balance: Decimal,
1288 #[serde(with = "rust_decimal::serde::str")]
1289 pub allowance: Decimal,
1290}
1291
1292#[derive(Default)]
1294pub struct BalanceAllowanceParams {
1295 pub asset_type: Option<AssetType>,
1296 pub token_id: Option<String>,
1297 pub signature_type: Option<u8>,
1298}
1299
1300impl BalanceAllowanceParams {
1301 pub fn to_query_params(&self) -> Vec<(&str, String)> {
1302 let mut params = Vec::with_capacity(3);
1303
1304 if let Some(x) = &self.asset_type {
1305 params.push(("asset_type", x.to_string()));
1306 }
1307
1308 if let Some(x) = &self.token_id {
1309 params.push(("token_id", x.to_string()));
1310 }
1311
1312 if let Some(x) = &self.signature_type {
1313 params.push(("signature_type", x.to_string()));
1314 }
1315 params
1316 }
1317
1318 pub fn set_signature_type(&mut self, s: u8) {
1319 self.signature_type = Some(s);
1320 }
1321}
1322
1323#[allow(clippy::upper_case_acronyms)]
1325pub enum AssetType {
1326 COLLATERAL,
1327 CONDITIONAL,
1328}
1329
1330impl std::fmt::Display for AssetType {
1331 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1332 match self {
1333 AssetType::COLLATERAL => write!(f, "COLLATERAL"),
1334 AssetType::CONDITIONAL => write!(f, "CONDITIONAL"),
1335 }
1336 }
1337}
1338
1339#[derive(Debug, Clone, Serialize, Deserialize)]
1341pub struct NotificationParams {
1342 pub signature: String,
1343 pub timestamp: u64,
1344}
1345
1346#[derive(Debug, Clone, Serialize, Deserialize)]
1348pub struct BatchMidpointRequest {
1349 pub token_ids: Vec<String>,
1350}
1351
1352#[derive(Debug, Clone, Serialize, Deserialize)]
1354pub struct BatchMidpointResponse {
1355 pub midpoints: std::collections::HashMap<String, Option<Decimal>>,
1356}
1357
1358#[derive(Debug, Clone, Serialize, Deserialize)]
1360pub struct BatchPriceRequest {
1361 pub token_ids: Vec<String>,
1362}
1363
1364#[derive(Debug, Clone, Serialize, Deserialize)]
1366pub struct TokenPrice {
1367 pub token_id: String,
1368 #[serde(skip_serializing_if = "Option::is_none")]
1369 pub bid: Option<Decimal>,
1370 #[serde(skip_serializing_if = "Option::is_none")]
1371 pub ask: Option<Decimal>,
1372 #[serde(skip_serializing_if = "Option::is_none")]
1373 pub mid: Option<Decimal>,
1374}
1375
1376#[derive(Debug, Clone, Serialize, Deserialize)]
1378pub struct BatchPriceResponse {
1379 pub prices: Vec<TokenPrice>,
1380}
1381
1382#[derive(Debug, Deserialize)]
1384pub struct ApiKeysResponse {
1385 #[serde(rename = "apiKeys")]
1386 pub api_keys: Vec<String>,
1387}
1388
1389#[derive(Debug, Deserialize)]
1390pub struct MidpointResponse {
1391 #[serde(with = "rust_decimal::serde::str")]
1392 pub mid: Decimal,
1393}
1394
1395#[derive(Debug, Deserialize)]
1396pub struct PriceResponse {
1397 #[serde(with = "rust_decimal::serde::str")]
1398 pub price: Decimal,
1399}
1400
1401#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1410pub enum PricesHistoryInterval {
1411 OneMinute,
1412 OneHour,
1413 SixHours,
1414 OneDay,
1415 OneWeek,
1416}
1417
1418impl PricesHistoryInterval {
1419 pub const fn as_str(self) -> &'static str {
1420 match self {
1421 Self::OneMinute => "1m",
1422 Self::OneHour => "1h",
1423 Self::SixHours => "6h",
1424 Self::OneDay => "1d",
1425 Self::OneWeek => "1w",
1426 }
1427 }
1428}
1429
1430#[derive(Debug, Clone, Serialize, Deserialize)]
1435pub struct PricesHistoryResponse {
1436 pub history: Vec<serde_json::Value>,
1437}
1438
1439#[derive(Debug, Deserialize)]
1440pub struct SpreadResponse {
1441 #[serde(with = "rust_decimal::serde::str")]
1442 pub spread: Decimal,
1443}
1444
1445#[derive(Debug, Deserialize)]
1446pub struct TickSizeResponse {
1447 #[serde(with = "rust_decimal::serde::str")]
1448 pub minimum_tick_size: Decimal,
1449}
1450
1451#[derive(Debug, Deserialize)]
1452pub struct NegRiskResponse {
1453 pub neg_risk: bool,
1454}
1455
1456#[derive(Debug, Serialize, Deserialize)]
1457pub struct BookParams {
1458 pub token_id: String,
1459 pub side: Side,
1460}
1461
1462#[derive(Debug, Deserialize)]
1463pub struct OrderBookSummary {
1464 pub market: String,
1465 pub asset_id: String,
1466 #[serde(default)]
1467 pub hash: Option<String>,
1468 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1469 pub timestamp: u64,
1470 #[serde(
1471 default,
1472 deserialize_with = "crate::decode::deserializers::vec_from_null"
1473 )]
1474 pub bids: Vec<OrderSummary>,
1475 #[serde(
1476 default,
1477 deserialize_with = "crate::decode::deserializers::vec_from_null"
1478 )]
1479 pub asks: Vec<OrderSummary>,
1480 pub min_order_size: Decimal,
1481 pub neg_risk: bool,
1482 pub tick_size: Decimal,
1483 #[serde(
1484 default,
1485 deserialize_with = "crate::decode::deserializers::optional_decimal_from_string_default_on_error"
1486 )]
1487 pub last_trade_price: Option<Decimal>,
1488}
1489
1490#[derive(Debug, Clone, Serialize, Deserialize)]
1491pub struct OrderSummary {
1492 #[serde(with = "rust_decimal::serde::str")]
1493 pub price: Decimal,
1494 #[serde(with = "rust_decimal::serde::str")]
1495 pub size: Decimal,
1496}
1497
1498#[derive(Debug, Serialize, Deserialize)]
1499pub struct MarketsResponse {
1500 pub limit: usize,
1501 pub count: usize,
1502 pub next_cursor: Option<String>,
1503 pub data: Vec<Market>,
1504}
1505
1506#[derive(Debug, Serialize, Deserialize)]
1507pub struct SimplifiedMarketsResponse {
1508 pub limit: usize,
1509 pub count: usize,
1510 pub next_cursor: Option<String>,
1511 pub data: Vec<SimplifiedMarket>,
1512}
1513
1514#[derive(Debug, Serialize, Deserialize)]
1516pub struct SimplifiedMarket {
1517 pub condition_id: String,
1518 pub tokens: [Token; 2],
1519 pub rewards: Rewards,
1520 pub min_incentive_size: Option<String>,
1521 pub max_incentive_spread: Option<String>,
1522 pub active: bool,
1523 pub closed: bool,
1524}
1525
1526#[derive(Debug, Clone, Serialize, Deserialize)]
1528pub struct Rewards {
1529 pub rates: Option<serde_json::Value>,
1530 pub min_size: Decimal,
1532 pub max_spread: Decimal,
1533 #[serde(default)]
1534 pub event_start_date: Option<String>,
1535 #[serde(default)]
1536 pub event_end_date: Option<String>,
1537 #[serde(skip_serializing_if = "Option::is_none", default)]
1538 pub in_game_multiplier: Option<Decimal>,
1539 #[serde(skip_serializing_if = "Option::is_none", default)]
1540 pub reward_epoch: Option<Decimal>,
1541}
1542
1543#[derive(Debug, Clone, Serialize, Deserialize)]
1549pub struct FeeRateResponse {
1550 #[serde(alias = "fee_rate_bps")]
1551 pub base_fee: u32,
1552}
1553
1554#[derive(Debug, Clone, Serialize)]
1556#[serde(rename_all = "camelCase")]
1557pub struct RfqCreateRequest {
1558 pub asset_in: String,
1559 pub asset_out: String,
1560 pub amount_in: String,
1561 pub amount_out: String,
1562 pub user_type: u8,
1563}
1564
1565#[derive(Debug, Clone, Serialize, Deserialize)]
1566#[serde(rename_all = "camelCase")]
1567pub struct RfqCreateRequestResponse {
1568 pub request_id: String,
1569 pub expiry: u64,
1570}
1571
1572#[derive(Debug, Clone, Serialize)]
1574#[serde(rename_all = "camelCase")]
1575pub struct RfqCancelRequest {
1576 pub request_id: String,
1577}
1578
1579#[derive(Debug, Clone, Default)]
1581pub struct RfqRequestsParams {
1582 pub offset: Option<String>,
1583 pub limit: Option<u32>,
1584 pub state: Option<String>,
1585 pub request_ids: Vec<String>,
1586 pub markets: Vec<String>,
1587 pub size_min: Option<Decimal>,
1588 pub size_max: Option<Decimal>,
1589 pub size_usdc_min: Option<Decimal>,
1590 pub size_usdc_max: Option<Decimal>,
1591 pub price_min: Option<Decimal>,
1592 pub price_max: Option<Decimal>,
1593 pub sort_by: Option<String>,
1594 pub sort_dir: Option<String>,
1595}
1596
1597impl RfqRequestsParams {
1598 pub fn to_query_params(&self) -> Vec<(String, String)> {
1599 let mut params = Vec::new();
1600
1601 if let Some(x) = &self.offset {
1602 params.push(("offset".to_string(), x.clone()));
1603 }
1604 if let Some(x) = self.limit {
1605 params.push(("limit".to_string(), x.to_string()));
1606 }
1607 if let Some(x) = &self.state {
1608 params.push(("state".to_string(), x.clone()));
1609 }
1610 for x in &self.request_ids {
1611 params.push(("requestIds[]".to_string(), x.clone()));
1612 }
1613 for x in &self.markets {
1614 params.push(("markets[]".to_string(), x.clone()));
1615 }
1616
1617 if let Some(x) = self.size_min {
1618 params.push(("sizeMin".to_string(), x.to_string()));
1619 }
1620 if let Some(x) = self.size_max {
1621 params.push(("sizeMax".to_string(), x.to_string()));
1622 }
1623 if let Some(x) = self.size_usdc_min {
1624 params.push(("sizeUsdcMin".to_string(), x.to_string()));
1625 }
1626 if let Some(x) = self.size_usdc_max {
1627 params.push(("sizeUsdcMax".to_string(), x.to_string()));
1628 }
1629 if let Some(x) = self.price_min {
1630 params.push(("priceMin".to_string(), x.to_string()));
1631 }
1632 if let Some(x) = self.price_max {
1633 params.push(("priceMax".to_string(), x.to_string()));
1634 }
1635
1636 if let Some(x) = &self.sort_by {
1637 params.push(("sortBy".to_string(), x.clone()));
1638 }
1639 if let Some(x) = &self.sort_dir {
1640 params.push(("sortDir".to_string(), x.clone()));
1641 }
1642
1643 params
1644 }
1645}
1646
1647#[derive(Debug, Clone, Serialize, Deserialize)]
1649#[serde(rename_all = "camelCase")]
1650pub struct RfqRequestData {
1651 pub request_id: String,
1652 pub user_address: String,
1653 pub proxy_address: String,
1654 pub condition: String,
1655 pub token: String,
1656 pub complement: String,
1657 pub side: Side,
1658 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1659 pub size_in: Decimal,
1660 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1661 pub size_out: Decimal,
1662 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1663 pub price: Decimal,
1664 pub state: String,
1665 pub expiry: u64,
1666}
1667
1668#[derive(Debug, Clone, Serialize)]
1670#[serde(rename_all = "camelCase")]
1671pub struct RfqCreateQuote {
1672 pub request_id: String,
1673 pub asset_in: String,
1674 pub asset_out: String,
1675 pub amount_in: String,
1676 pub amount_out: String,
1677 pub user_type: u8,
1678}
1679
1680#[derive(Debug, Clone, Serialize, Deserialize)]
1681#[serde(rename_all = "camelCase")]
1682pub struct RfqCreateQuoteResponse {
1683 pub quote_id: String,
1684}
1685
1686#[derive(Debug, Clone, Serialize)]
1688#[serde(rename_all = "camelCase")]
1689pub struct RfqCancelQuote {
1690 pub quote_id: String,
1691}
1692
1693#[derive(Debug, Clone, Default)]
1695pub struct RfqQuotesParams {
1696 pub offset: Option<String>,
1697 pub limit: Option<u32>,
1698 pub state: Option<String>,
1699 pub quote_ids: Vec<String>,
1700 pub request_ids: Vec<String>,
1701 pub markets: Vec<String>,
1702 pub size_min: Option<Decimal>,
1703 pub size_max: Option<Decimal>,
1704 pub size_usdc_min: Option<Decimal>,
1705 pub size_usdc_max: Option<Decimal>,
1706 pub price_min: Option<Decimal>,
1707 pub price_max: Option<Decimal>,
1708 pub sort_by: Option<String>,
1709 pub sort_dir: Option<String>,
1710}
1711
1712impl RfqQuotesParams {
1713 pub fn to_query_params(&self) -> Vec<(String, String)> {
1714 let mut params = Vec::new();
1715
1716 if let Some(x) = &self.offset {
1717 params.push(("offset".to_string(), x.clone()));
1718 }
1719 if let Some(x) = self.limit {
1720 params.push(("limit".to_string(), x.to_string()));
1721 }
1722 if let Some(x) = &self.state {
1723 params.push(("state".to_string(), x.clone()));
1724 }
1725 for x in &self.quote_ids {
1726 params.push(("quoteIds[]".to_string(), x.clone()));
1727 }
1728 for x in &self.request_ids {
1729 params.push(("requestIds[]".to_string(), x.clone()));
1730 }
1731 for x in &self.markets {
1732 params.push(("markets[]".to_string(), x.clone()));
1733 }
1734
1735 if let Some(x) = self.size_min {
1736 params.push(("sizeMin".to_string(), x.to_string()));
1737 }
1738 if let Some(x) = self.size_max {
1739 params.push(("sizeMax".to_string(), x.to_string()));
1740 }
1741 if let Some(x) = self.size_usdc_min {
1742 params.push(("sizeUsdcMin".to_string(), x.to_string()));
1743 }
1744 if let Some(x) = self.size_usdc_max {
1745 params.push(("sizeUsdcMax".to_string(), x.to_string()));
1746 }
1747 if let Some(x) = self.price_min {
1748 params.push(("priceMin".to_string(), x.to_string()));
1749 }
1750 if let Some(x) = self.price_max {
1751 params.push(("priceMax".to_string(), x.to_string()));
1752 }
1753
1754 if let Some(x) = &self.sort_by {
1755 params.push(("sortBy".to_string(), x.clone()));
1756 }
1757 if let Some(x) = &self.sort_dir {
1758 params.push(("sortDir".to_string(), x.clone()));
1759 }
1760
1761 params
1762 }
1763}
1764
1765#[derive(Debug, Clone, Serialize, Deserialize)]
1767#[serde(rename_all = "camelCase")]
1768pub struct RfqQuoteData {
1769 pub quote_id: String,
1770 pub request_id: String,
1771 pub user_address: String,
1772 pub proxy_address: String,
1773 pub condition: String,
1774 pub token: String,
1775 pub complement: String,
1776 pub side: Side,
1777 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1778 pub size_in: Decimal,
1779 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1780 pub size_out: Decimal,
1781 #[serde(deserialize_with = "crate::decode::deserializers::decimal_from_string")]
1782 pub price: Decimal,
1783 pub match_type: String,
1784 pub state: String,
1785}
1786
1787#[derive(Debug, Clone, Serialize, Deserialize)]
1789pub struct RfqListResponse<T> {
1790 pub data: Vec<T>,
1791 pub next_cursor: Option<String>,
1792 pub limit: u32,
1793 pub count: u32,
1794}
1795
1796#[derive(Debug, Clone, Serialize)]
1798#[serde(rename_all = "camelCase")]
1799pub struct RfqOrderExecutionRequest {
1800 pub request_id: String,
1801 pub quote_id: String,
1802 pub maker: String,
1803 pub signer: String,
1804 pub taker: String,
1805 pub expiration: u64,
1806 pub nonce: String,
1807 pub fee_rate_bps: String,
1808 pub side: String,
1809 pub token_id: String,
1810 pub maker_amount: String,
1811 pub taker_amount: String,
1812 pub signature_type: u8,
1813 pub signature: String,
1814 pub salt: u64,
1815 pub owner: String,
1816}
1817
1818#[derive(Debug, Clone, Serialize, Deserialize)]
1819#[serde(rename_all = "camelCase")]
1820pub struct RfqApproveOrderResponse {
1821 pub trade_ids: Vec<String>,
1822}
1823
1824pub type ClientResult<T> = anyhow::Result<T>;
1826
1827pub type Result<T> = std::result::Result<T, crate::errors::PolyfillError>;
1829
1830pub type ApiCreds = ApiCredentials;