polyte_clob/
types.rs

1use std::fmt;
2
3use alloy::primitives::Address;
4use serde::{Deserialize, Serialize};
5
6/// API credentials for L2 authentication
7#[derive(Clone, Serialize, Deserialize)]
8pub struct Credentials {
9    pub key: String,
10    pub secret: String,
11    pub passphrase: String,
12}
13
14impl fmt::Debug for Credentials {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        f.debug_struct("Credentials")
17            .field("key", &"<redacted>")
18            .field("secret", &"<redacted>")
19            .field("passphrase", &"<redacted>")
20            .finish()
21    }
22}
23
24/// Order side (buy or sell)
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
26#[serde(rename_all = "UPPERCASE")]
27pub enum OrderSide {
28    Buy,
29    Sell,
30}
31
32impl fmt::Display for OrderSide {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        match self {
35            Self::Buy => write!(f, "BUY"),
36            Self::Sell => write!(f, "SELL"),
37        }
38    }
39}
40
41/// Order type/kind
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "UPPERCASE")]
44pub enum OrderKind {
45    /// Good-till-Cancelled
46    Gtc,
47    /// Fill-or-Kill
48    Fok,
49    /// Good-till-Date
50    Gtd,
51    /// Fill-and-Kill
52    Fak,
53}
54
55/// Signature type
56#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
57#[serde(rename_all = "kebab-case")]
58pub enum SignatureType {
59    #[default]
60    Eoa,
61    PolyProxy,
62    PolyGnosisSafe,
63}
64
65/// Tick size (minimum price increment)
66#[derive(Debug, Clone, Copy, PartialEq)]
67pub enum TickSize {
68    /// 0.1
69    Tenth,
70    /// 0.01
71    Hundredth,
72    /// 0.001
73    Thousandth,
74    /// 0.0001
75    TenThousandth,
76}
77
78impl TickSize {
79    pub fn as_f64(&self) -> f64 {
80        match self {
81            Self::Tenth => 0.1,
82            Self::Hundredth => 0.01,
83            Self::Thousandth => 0.001,
84            Self::TenThousandth => 0.0001,
85        }
86    }
87
88    pub fn decimals(&self) -> u32 {
89        match self {
90            Self::Tenth => 1,
91            Self::Hundredth => 2,
92            Self::Thousandth => 3,
93            Self::TenThousandth => 4,
94        }
95    }
96}
97
98impl From<&str> for TickSize {
99    fn from(s: &str) -> Self {
100        match s {
101            "0.1" => Self::Tenth,
102            "0.01" => Self::Hundredth,
103            "0.001" => Self::Thousandth,
104            "0.0001" => Self::TenThousandth,
105            _ => Self::Hundredth, // Default
106        }
107    }
108}
109
110impl From<f64> for TickSize {
111    fn from(n: f64) -> Self {
112        const EPSILON: f64 = 1e-10;
113        if (n - 0.1).abs() < EPSILON {
114            Self::Tenth
115        } else if (n - 0.01).abs() < EPSILON {
116            Self::Hundredth
117        } else if (n - 0.001).abs() < EPSILON {
118            Self::Thousandth
119        } else if (n - 0.0001).abs() < EPSILON {
120            Self::TenThousandth
121        } else {
122            Self::Hundredth // Default
123        }
124    }
125}
126
127/// Unsigned order
128#[derive(Debug, Clone, Serialize, Deserialize)]
129#[serde(rename_all(deserialize = "camelCase"))]
130pub struct Order {
131    pub salt: String,
132    pub maker: Address,
133    pub signer: Address,
134    pub taker: Address,
135    pub token_id: String,
136    pub maker_amount: String,
137    pub taker_amount: String,
138    pub expiration: String,
139    pub nonce: String,
140    pub fee_rate_bps: String,
141    pub side: OrderSide,
142    pub signature_type: SignatureType,
143}
144
145/// Signed order
146#[derive(Debug, Clone, Serialize, Deserialize)]
147#[serde(rename_all(deserialize = "camelCase"))]
148pub struct SignedOrder {
149    #[serde(flatten)]
150    pub order: Order,
151    pub signature: String,
152}