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