1use alloy_primitives::{Address, U256};
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)]
212#[allow(clippy::upper_case_acronyms)]
213pub enum OrderType {
214 GTC,
215 FOK,
216 GTD,
217}
218
219impl OrderType {
220 pub fn as_str(&self) -> &'static str {
221 match self {
222 OrderType::GTC => "GTC",
223 OrderType::FOK => "FOK",
224 OrderType::GTD => "GTD",
225 }
226 }
227}
228
229#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
231pub enum OrderStatus {
232 #[serde(rename = "LIVE")]
233 Live,
234 #[serde(rename = "CANCELLED")]
235 Cancelled,
236 #[serde(rename = "FILLED")]
237 Filled,
238 #[serde(rename = "PARTIAL")]
239 Partial,
240 #[serde(rename = "EXPIRED")]
241 Expired,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct MarketSnapshot {
247 pub token_id: String,
248 pub market_id: String,
249 pub timestamp: DateTime<Utc>,
250 pub bid: Option<Decimal>,
251 pub ask: Option<Decimal>,
252 pub mid: Option<Decimal>,
253 pub spread: Option<Decimal>,
254 pub last_price: Option<Decimal>,
255 pub volume_24h: Option<Decimal>,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct BookLevel {
264 #[serde(with = "rust_decimal::serde::str")]
265 pub price: Decimal,
266 #[serde(with = "rust_decimal::serde::str")]
267 pub size: Decimal,
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq)]
281pub struct FastBookLevel {
282 pub price: Price, pub size: Qty, }
285
286impl FastBookLevel {
287 pub fn new(price: Price, size: Qty) -> Self {
289 Self { price, size }
290 }
291
292 pub fn to_book_level(self) -> BookLevel {
295 BookLevel {
296 price: price_to_decimal(self.price),
297 size: qty_to_decimal(self.size),
298 }
299 }
300
301 pub fn from_book_level(level: &BookLevel) -> std::result::Result<Self, &'static str> {
304 let price = decimal_to_price(level.price)?;
305 let size = decimal_to_qty(level.size)?;
306 Ok(Self::new(price, size))
307 }
308
309 pub fn notional(self) -> i64 {
316 let price_i64 = self.price as i64;
318 (price_i64 * self.size) / SCALE_FACTOR
320 }
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct OrderBook {
326 pub token_id: String,
328 pub timestamp: DateTime<Utc>,
330 pub bids: Vec<BookLevel>,
332 pub asks: Vec<BookLevel>,
334 pub sequence: u64,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize)]
343pub struct OrderDelta {
344 pub token_id: String,
345 pub timestamp: DateTime<Utc>,
346 pub side: Side,
347 pub price: Decimal,
348 pub size: Decimal, pub sequence: u64,
350}
351
352#[derive(Debug, Clone, Copy, PartialEq, Eq)]
363pub struct FastOrderDelta {
364 pub token_id_hash: u64, pub timestamp: DateTime<Utc>,
366 pub side: Side,
367 pub price: Price, pub size: Qty, pub sequence: u64,
370}
371
372impl FastOrderDelta {
373 pub fn from_order_delta(
379 delta: &OrderDelta,
380 tick_size: Option<Decimal>,
381 ) -> std::result::Result<Self, &'static str> {
382 if let Some(tick_size) = tick_size {
384 if !is_price_tick_aligned(delta.price, tick_size) {
385 return Err("Price not aligned to tick size");
386 }
387 }
388
389 let price = decimal_to_price(delta.price)?;
391 let size = decimal_to_qty(delta.size)?;
392
393 let token_id_hash = {
396 use std::collections::hash_map::DefaultHasher;
397 use std::hash::{Hash, Hasher};
398 let mut hasher = DefaultHasher::new();
399 delta.token_id.hash(&mut hasher);
400 hasher.finish()
401 };
402
403 Ok(Self {
404 token_id_hash,
405 timestamp: delta.timestamp,
406 side: delta.side,
407 price,
408 size,
409 sequence: delta.sequence,
410 })
411 }
412
413 pub fn to_order_delta(self, token_id: String) -> OrderDelta {
416 OrderDelta {
417 token_id,
418 timestamp: self.timestamp,
419 side: self.side,
420 price: price_to_decimal(self.price),
421 size: qty_to_decimal(self.size),
422 sequence: self.sequence,
423 }
424 }
425
426 pub fn is_removal(self) -> bool {
428 self.size == 0
429 }
430}
431
432#[derive(Debug, Clone, Serialize, Deserialize)]
434pub struct FillEvent {
435 pub id: String,
436 pub order_id: String,
437 pub token_id: String,
438 pub side: Side,
439 pub price: Decimal,
440 pub size: Decimal,
441 pub timestamp: DateTime<Utc>,
442 pub maker_address: Address,
443 pub taker_address: Address,
444 pub fee: Decimal,
445}
446
447#[derive(Debug, Clone)]
449pub struct OrderRequest {
450 pub token_id: String,
451 pub side: Side,
452 pub price: Decimal,
453 pub size: Decimal,
454 pub order_type: OrderType,
455 pub expiration: Option<DateTime<Utc>>,
456 pub client_id: Option<String>,
457}
458
459#[derive(Debug, Clone)]
461pub struct MarketOrderRequest {
462 pub token_id: String,
463 pub side: Side,
464 pub amount: Decimal, pub slippage_tolerance: Option<Decimal>,
466 pub client_id: Option<String>,
467}
468
469#[derive(Debug, Clone, Serialize, Deserialize)]
471pub struct Order {
472 pub id: String,
473 pub token_id: String,
474 pub side: Side,
475 pub price: Decimal,
476 pub original_size: Decimal,
477 pub filled_size: Decimal,
478 pub remaining_size: Decimal,
479 pub status: OrderStatus,
480 pub order_type: OrderType,
481 pub created_at: DateTime<Utc>,
482 pub updated_at: DateTime<Utc>,
483 pub expiration: Option<DateTime<Utc>>,
484 pub client_id: Option<String>,
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize, Default)]
489pub struct ApiCredentials {
490 #[serde(rename = "apiKey")]
491 pub api_key: String,
492 pub secret: String,
493 pub passphrase: String,
494}
495
496#[derive(Debug, Clone)]
498pub struct OrderOptions {
499 pub tick_size: Option<Decimal>,
500 pub neg_risk: Option<bool>,
501 pub fee_rate_bps: Option<u32>,
502}
503
504#[derive(Debug, Clone)]
506pub struct ExtraOrderArgs {
507 pub fee_rate_bps: u32,
508 pub nonce: U256,
509 pub taker: String,
510}
511
512impl Default for ExtraOrderArgs {
513 fn default() -> Self {
514 Self {
515 fee_rate_bps: 0,
516 nonce: U256::ZERO,
517 taker: "0x0000000000000000000000000000000000000000".to_string(),
518 }
519 }
520}
521
522#[derive(Debug, Clone)]
524pub struct MarketOrderArgs {
525 pub token_id: String,
526 pub amount: Decimal,
527}
528
529#[derive(Debug, Clone, Serialize, Deserialize)]
531#[serde(rename_all = "camelCase")]
532pub struct SignedOrderRequest {
533 pub salt: u64,
534 pub maker: String,
535 pub signer: String,
536 pub taker: String,
537 pub token_id: String,
538 pub maker_amount: String,
539 pub taker_amount: String,
540 pub expiration: String,
541 pub nonce: String,
542 pub fee_rate_bps: String,
543 pub side: String,
544 pub signature_type: u8,
545 pub signature: String,
546}
547
548#[derive(Debug, Serialize)]
550#[serde(rename_all = "camelCase")]
551pub struct PostOrder {
552 pub order: SignedOrderRequest,
553 pub owner: String,
554 pub order_type: OrderType,
555}
556
557impl PostOrder {
558 pub fn new(order: SignedOrderRequest, owner: String, order_type: OrderType) -> Self {
559 Self {
560 order,
561 owner,
562 order_type,
563 }
564 }
565}
566
567#[derive(Debug, Clone, Serialize, Deserialize)]
569pub struct Market {
570 pub condition_id: String,
571 pub tokens: [Token; 2],
572 pub rewards: Rewards,
573 pub min_incentive_size: Option<String>,
574 pub max_incentive_spread: Option<String>,
575 pub active: bool,
576 pub closed: bool,
577 pub question_id: String,
578 #[serde(with = "rust_decimal::serde::str")]
579 pub minimum_order_size: Decimal,
580 #[serde(with = "rust_decimal::serde::str")]
581 pub minimum_tick_size: Decimal,
582 pub description: String,
583 pub category: Option<String>,
584 pub end_date_iso: Option<String>,
585 pub game_start_time: Option<String>,
586 pub question: String,
587 pub market_slug: String,
588 #[serde(with = "rust_decimal::serde::str")]
589 pub seconds_delay: Decimal,
590 pub icon: String,
591 pub fpmm: String,
592 #[serde(default)]
594 pub enable_order_book: bool,
595 #[serde(default)]
596 pub archived: bool,
597 #[serde(default)]
598 pub accepting_orders: bool,
599 #[serde(default)]
600 pub accepting_order_timestamp: Option<String>,
601 #[serde(with = "rust_decimal::serde::str", default)]
602 pub maker_base_fee: Decimal,
603 #[serde(with = "rust_decimal::serde::str", default)]
604 pub taker_base_fee: Decimal,
605 #[serde(default)]
606 pub notifications_enabled: bool,
607 #[serde(default)]
608 pub neg_risk: bool,
609 #[serde(default)]
610 pub neg_risk_market_id: String,
611 #[serde(default)]
612 pub neg_risk_request_id: String,
613 #[serde(default)]
614 pub image: String,
615 #[serde(default)]
616 pub is_50_50_outcome: bool,
617}
618
619#[derive(Debug, Clone, Serialize, Deserialize)]
621pub struct Token {
622 pub token_id: String,
623 pub outcome: String,
624 #[serde(with = "rust_decimal::serde::str", default)]
625 pub price: Decimal,
626 #[serde(default)]
627 pub winner: bool,
628}
629
630#[derive(Debug, Clone, Serialize, Deserialize)]
632pub struct ClientConfig {
633 pub base_url: String,
635 pub chain_id: u64,
637 pub private_key: Option<String>,
639 pub api_credentials: Option<ApiCredentials>,
641 pub max_slippage: Option<Decimal>,
643 pub fee_rate: Option<Decimal>,
645 pub timeout: Option<std::time::Duration>,
647 pub max_connections: Option<usize>,
649}
650
651impl Default for ClientConfig {
652 fn default() -> Self {
653 Self {
654 base_url: "https://clob.polymarket.com".to_string(),
655 chain_id: 137, private_key: None,
657 api_credentials: None,
658 timeout: Some(std::time::Duration::from_secs(30)),
659 max_connections: Some(100),
660 max_slippage: None,
661 fee_rate: None,
662 }
663 }
664}
665
666#[derive(Debug, Clone, Serialize, Deserialize)]
668pub struct WssAuth {
669 pub address: String,
671 pub signature: String,
673 pub timestamp: u64,
675 pub nonce: String,
677}
678
679#[derive(Debug, Clone, Serialize, Deserialize)]
681pub struct WssSubscription {
682 pub auth: WssAuth,
684 pub markets: Option<Vec<String>>,
686 pub asset_ids: Option<Vec<String>>,
688 #[serde(rename = "type")]
690 pub channel_type: String,
691}
692
693#[derive(Debug, Clone, Serialize, Deserialize)]
695#[serde(tag = "type")]
696pub enum StreamMessage {
697 #[serde(rename = "book_update")]
698 BookUpdate { data: OrderDelta },
699 #[serde(rename = "trade")]
700 Trade { data: FillEvent },
701 #[serde(rename = "order_update")]
702 OrderUpdate { data: Order },
703 #[serde(rename = "heartbeat")]
704 Heartbeat { timestamp: DateTime<Utc> },
705 #[serde(rename = "user_order_update")]
707 UserOrderUpdate { data: Order },
708 #[serde(rename = "user_trade")]
709 UserTrade { data: FillEvent },
710 #[serde(rename = "market_book_update")]
712 MarketBookUpdate { data: OrderDelta },
713 #[serde(rename = "market_trade")]
714 MarketTrade { data: FillEvent },
715}
716
717#[derive(Debug, Clone, Serialize, Deserialize)]
719pub struct Subscription {
720 pub token_ids: Vec<String>,
721 pub channels: Vec<String>,
722}
723
724#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
726pub enum WssChannelType {
727 #[serde(rename = "USER")]
728 User,
729 #[serde(rename = "MARKET")]
730 Market,
731}
732
733impl WssChannelType {
734 pub fn as_str(&self) -> &'static str {
735 match self {
736 WssChannelType::User => "USER",
737 WssChannelType::Market => "MARKET",
738 }
739 }
740}
741
742#[derive(Debug, Clone, Serialize, Deserialize)]
744pub struct Quote {
745 pub token_id: String,
746 pub side: Side,
747 #[serde(with = "rust_decimal::serde::str")]
748 pub price: Decimal,
749 pub timestamp: DateTime<Utc>,
750}
751
752#[derive(Debug, Clone, Serialize, Deserialize)]
754pub struct Balance {
755 pub token_id: String,
756 pub available: Decimal,
757 pub locked: Decimal,
758 pub total: Decimal,
759}
760
761#[derive(Debug, Clone)]
763pub struct Metrics {
764 pub orders_per_second: f64,
765 pub avg_latency_ms: f64,
766 pub error_rate: f64,
767 pub uptime_pct: f64,
768}
769
770pub type TokenId = String;
772pub type OrderId = String;
773pub type MarketId = String;
774pub type ClientId = String;
775
776#[derive(Debug, Clone)]
778pub struct OpenOrderParams {
779 pub id: Option<String>,
780 pub asset_id: Option<String>,
781 pub market: Option<String>,
782}
783
784impl OpenOrderParams {
785 pub fn to_query_params(&self) -> Vec<(&str, &String)> {
786 let mut params = Vec::with_capacity(3);
787
788 if let Some(x) = &self.id {
789 params.push(("id", x));
790 }
791
792 if let Some(x) = &self.asset_id {
793 params.push(("asset_id", x));
794 }
795
796 if let Some(x) = &self.market {
797 params.push(("market", x));
798 }
799 params
800 }
801}
802
803#[derive(Debug, Clone)]
805pub struct TradeParams {
806 pub id: Option<String>,
807 pub maker_address: Option<String>,
808 pub market: Option<String>,
809 pub asset_id: Option<String>,
810 pub before: Option<u64>,
811 pub after: Option<u64>,
812}
813
814impl TradeParams {
815 pub fn to_query_params(&self) -> Vec<(&str, String)> {
816 let mut params = Vec::with_capacity(6);
817
818 if let Some(x) = &self.id {
819 params.push(("id", x.clone()));
820 }
821
822 if let Some(x) = &self.asset_id {
823 params.push(("asset_id", x.clone()));
824 }
825
826 if let Some(x) = &self.market {
827 params.push(("market", x.clone()));
828 }
829
830 if let Some(x) = &self.maker_address {
831 params.push(("maker_address", x.clone()));
832 }
833
834 if let Some(x) = &self.before {
835 params.push(("before", x.to_string()));
836 }
837
838 if let Some(x) = &self.after {
839 params.push(("after", x.to_string()));
840 }
841
842 params
843 }
844}
845
846#[derive(Debug, Clone, Serialize, Deserialize)]
848pub struct OpenOrder {
849 pub associate_trades: Vec<String>,
850 pub id: String,
851 pub status: String,
852 pub market: String,
853 #[serde(with = "rust_decimal::serde::str")]
854 pub original_size: Decimal,
855 pub outcome: String,
856 pub maker_address: String,
857 pub owner: String,
858 #[serde(with = "rust_decimal::serde::str")]
859 pub price: Decimal,
860 pub side: Side,
861 #[serde(with = "rust_decimal::serde::str")]
862 pub size_matched: Decimal,
863 pub asset_id: String,
864 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
865 pub expiration: u64,
866 #[serde(rename = "type")]
867 pub order_type: OrderType,
868 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
869 pub created_at: u64,
870}
871
872#[derive(Debug, Clone, Serialize, Deserialize)]
874pub struct BalanceAllowance {
875 pub asset_id: String,
876 #[serde(with = "rust_decimal::serde::str")]
877 pub balance: Decimal,
878 #[serde(with = "rust_decimal::serde::str")]
879 pub allowance: Decimal,
880}
881
882#[derive(Default)]
884pub struct BalanceAllowanceParams {
885 pub asset_type: Option<AssetType>,
886 pub token_id: Option<String>,
887 pub signature_type: Option<u8>,
888}
889
890impl BalanceAllowanceParams {
891 pub fn to_query_params(&self) -> Vec<(&str, String)> {
892 let mut params = Vec::with_capacity(3);
893
894 if let Some(x) = &self.asset_type {
895 params.push(("asset_type", x.to_string()));
896 }
897
898 if let Some(x) = &self.token_id {
899 params.push(("token_id", x.to_string()));
900 }
901
902 if let Some(x) = &self.signature_type {
903 params.push(("signature_type", x.to_string()));
904 }
905 params
906 }
907
908 pub fn set_signature_type(&mut self, s: u8) {
909 self.signature_type = Some(s);
910 }
911}
912
913#[allow(clippy::upper_case_acronyms)]
915pub enum AssetType {
916 COLLATERAL,
917 CONDITIONAL,
918}
919
920impl std::fmt::Display for AssetType {
921 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
922 match self {
923 AssetType::COLLATERAL => write!(f, "COLLATERAL"),
924 AssetType::CONDITIONAL => write!(f, "CONDITIONAL"),
925 }
926 }
927}
928
929#[derive(Debug, Clone, Serialize, Deserialize)]
931pub struct NotificationParams {
932 pub signature: String,
933 pub timestamp: u64,
934}
935
936#[derive(Debug, Clone, Serialize, Deserialize)]
938pub struct BatchMidpointRequest {
939 pub token_ids: Vec<String>,
940}
941
942#[derive(Debug, Clone, Serialize, Deserialize)]
944pub struct BatchMidpointResponse {
945 pub midpoints: std::collections::HashMap<String, Option<Decimal>>,
946}
947
948#[derive(Debug, Clone, Serialize, Deserialize)]
950pub struct BatchPriceRequest {
951 pub token_ids: Vec<String>,
952}
953
954#[derive(Debug, Clone, Serialize, Deserialize)]
956pub struct TokenPrice {
957 pub token_id: String,
958 #[serde(skip_serializing_if = "Option::is_none")]
959 pub bid: Option<Decimal>,
960 #[serde(skip_serializing_if = "Option::is_none")]
961 pub ask: Option<Decimal>,
962 #[serde(skip_serializing_if = "Option::is_none")]
963 pub mid: Option<Decimal>,
964}
965
966#[derive(Debug, Clone, Serialize, Deserialize)]
968pub struct BatchPriceResponse {
969 pub prices: Vec<TokenPrice>,
970}
971
972#[derive(Debug, Deserialize)]
974pub struct ApiKeysResponse {
975 #[serde(rename = "apiKeys")]
976 pub api_keys: Vec<String>,
977}
978
979#[derive(Debug, Deserialize)]
980pub struct MidpointResponse {
981 #[serde(with = "rust_decimal::serde::str")]
982 pub mid: Decimal,
983}
984
985#[derive(Debug, Deserialize)]
986pub struct PriceResponse {
987 #[serde(with = "rust_decimal::serde::str")]
988 pub price: Decimal,
989}
990
991#[derive(Debug, Deserialize)]
992pub struct SpreadResponse {
993 #[serde(with = "rust_decimal::serde::str")]
994 pub spread: Decimal,
995}
996
997#[derive(Debug, Deserialize)]
998pub struct TickSizeResponse {
999 #[serde(with = "rust_decimal::serde::str")]
1000 pub minimum_tick_size: Decimal,
1001}
1002
1003#[derive(Debug, Deserialize)]
1004pub struct NegRiskResponse {
1005 pub neg_risk: bool,
1006}
1007
1008#[derive(Debug, Serialize, Deserialize)]
1009pub struct BookParams {
1010 pub token_id: String,
1011 pub side: Side,
1012}
1013
1014#[derive(Debug, Deserialize)]
1015pub struct OrderBookSummary {
1016 pub market: String,
1017 pub asset_id: String,
1018 pub hash: String,
1019 #[serde(deserialize_with = "crate::decode::deserializers::number_from_string")]
1020 pub timestamp: u64,
1021 pub bids: Vec<OrderSummary>,
1022 pub asks: Vec<OrderSummary>,
1023}
1024
1025#[derive(Debug, Deserialize)]
1026pub struct OrderSummary {
1027 #[serde(with = "rust_decimal::serde::str")]
1028 pub price: Decimal,
1029 #[serde(with = "rust_decimal::serde::str")]
1030 pub size: Decimal,
1031}
1032
1033#[derive(Debug, Serialize, Deserialize)]
1034pub struct MarketsResponse {
1035 #[serde(with = "rust_decimal::serde::str")]
1036 pub limit: Decimal,
1037 #[serde(with = "rust_decimal::serde::str")]
1038 pub count: Decimal,
1039 pub next_cursor: Option<String>,
1040 pub data: Vec<Market>,
1041}
1042
1043#[derive(Debug, Serialize, Deserialize)]
1044pub struct SimplifiedMarketsResponse {
1045 #[serde(with = "rust_decimal::serde::str")]
1046 pub limit: Decimal,
1047 #[serde(with = "rust_decimal::serde::str")]
1048 pub count: Decimal,
1049 pub next_cursor: Option<String>,
1050 pub data: Vec<SimplifiedMarket>,
1051}
1052
1053#[derive(Debug, Serialize, Deserialize)]
1055pub struct SimplifiedMarket {
1056 pub condition_id: String,
1057 pub tokens: [Token; 2],
1058 pub rewards: Rewards,
1059 pub min_incentive_size: Option<String>,
1060 pub max_incentive_spread: Option<String>,
1061 pub active: bool,
1062 pub closed: bool,
1063}
1064
1065#[derive(Debug, Clone, Serialize, Deserialize)]
1067pub struct Rewards {
1068 pub rates: Option<serde_json::Value>,
1069 pub min_size: Decimal,
1071 pub max_spread: Decimal,
1072 #[serde(default)]
1073 pub event_start_date: Option<String>,
1074 #[serde(default)]
1075 pub event_end_date: Option<String>,
1076 #[serde(skip_serializing_if = "Option::is_none", default)]
1077 pub in_game_multiplier: Option<Decimal>,
1078 #[serde(skip_serializing_if = "Option::is_none", default)]
1079 pub reward_epoch: Option<Decimal>,
1080}
1081
1082pub type ClientResult<T> = anyhow::Result<T>;
1084
1085pub type Result<T> = std::result::Result<T, crate::errors::PolyfillError>;
1087
1088pub type ApiCreds = ApiCredentials;
1090pub type CreateOrderOptions = OrderOptions;
1091pub type OrderArgs = OrderRequest;