Skip to main content

acta_maker_sdk/types/
ids.rs

1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5define_bytes32_newtype!(OrderId);
6
7define_numeric_newtype!(
8    /// Strike price, 1e9 fixed-point per one unit of the underlying
9    /// ([`PRICE_SCALE`](crate::PRICE_SCALE)), independent of mint decimals.
10    Strike,
11    u64
12);
13define_numeric_newtype!(
14    /// Gross premium per one unit of the underlying, 1e9 fixed-point
15    /// ([`PRICE_SCALE`](crate::PRICE_SCALE)), independent of mint decimals.
16    Price,
17    u64
18);
19define_numeric_newtype!(
20    /// Order size in the underlying mint's atomic units.
21    Quantity,
22    u64
23);
24
25impl Price {
26    /// Apply a protocol fee in basis points using the contract's rounding rule.
27    #[must_use]
28    pub fn after_fee_bps(self, bps: u16) -> Self {
29        let fee = u128::from(self.0) * u128::from(bps) / 10_000;
30        Self::new(
31            self.0
32                .saturating_sub(u64::try_from(fee).unwrap_or(u64::MAX)),
33        )
34    }
35}
36
37define_numeric_newtype!(Nonce, u64);
38define_numeric_newtype!(RfqVersion, u64);
39define_numeric_newtype!(OrderVersion, u64);
40
41impl OrderVersion {
42    /// Order exists and has been accepted/locked by the taker.
43    pub const ACCEPTED: Self = Self::new(1);
44    /// The signed transaction has been submitted for execution.
45    pub const SUBMITTED: Self = Self::new(2);
46    /// A locally final failure or expiry. A later chain confirmation may supersede failure.
47    pub const FAILED: Self = Self::new(3);
48    /// An authoritative on-chain confirmation.
49    pub const CONFIRMED: Self = Self::new(4);
50    /// No authoritative order exists for the requested id.
51    pub const NOT_FOUND: Self = Self::new(0);
52}
53define_numeric_newtype!(Slot, u64);
54define_numeric_newtype!(ChainId, u64);
55define_numeric_newtype!(DurationSeconds, u64);
56define_numeric_newtype!(Volume, u64);
57define_numeric_newtype!(Balance, u64);
58
59define_numeric_newtype!(QuoteCount, u32);
60define_numeric_newtype!(TradeCount, u32);
61define_numeric_newtype!(TimeoutSeconds, u32);
62
63#[derive(
64    Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
65)]
66pub struct Decimals(pub u8);
67
68impl Decimals {
69    #[must_use]
70    pub const fn new(value: u8) -> Self {
71        Self(value)
72    }
73
74    #[must_use]
75    pub const fn value(self) -> u8 {
76        self.0
77    }
78}
79
80impl Display for Decimals {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        write!(f, "{}", self.0)
83    }
84}
85
86impl From<u8> for Decimals {
87    fn from(value: u8) -> Self {
88        Self(value)
89    }
90}
91
92impl From<Decimals> for u8 {
93    fn from(value: Decimals) -> Self {
94        value.0
95    }
96}
97
98#[cfg(test)]
99mod tests {
100    use super::OrderVersion;
101
102    #[test]
103    fn order_version_ranks_match_wire_lifecycle_precedence() {
104        assert_eq!(OrderVersion::NOT_FOUND.value(), 0);
105        assert!(OrderVersion::ACCEPTED < OrderVersion::SUBMITTED);
106        assert!(OrderVersion::SUBMITTED < OrderVersion::FAILED);
107        assert!(OrderVersion::FAILED < OrderVersion::CONFIRMED);
108    }
109}
110
111define_string_newtype!(MarketId);
112define_string_newtype!(UserId);
113
114#[derive(
115    Debug,
116    Clone,
117    Copy,
118    PartialEq,
119    Eq,
120    Hash,
121    Serialize,
122    Deserialize,
123    strum::IntoStaticStr,
124    strum::EnumString,
125)]
126#[serde(rename_all = "snake_case")]
127#[strum(serialize_all = "snake_case")]
128#[repr(u8)]
129pub enum PositionType {
130    CoveredCall = 0,
131    CashSecuredPut = 1,
132}
133
134impl From<PositionType> for u8 {
135    fn from(position_type: PositionType) -> Self {
136        position_type as Self
137    }
138}
139
140#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
141#[error("invalid position type value: {0}")]
142pub struct PositionTypeParseError(pub u8);
143
144impl TryFrom<u8> for PositionType {
145    type Error = PositionTypeParseError;
146
147    fn try_from(value: u8) -> Result<Self, Self::Error> {
148        match value {
149            0 => Ok(Self::CoveredCall),
150            1 => Ok(Self::CashSecuredPut),
151            _ => Err(PositionTypeParseError(value)),
152        }
153    }
154}
155
156impl Display for PositionType {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        f.write_str(self.into())
159    }
160}