Skip to main content

perpl_sdk/types/
mod.rs

1mod event;
2mod extension;
3mod order;
4mod request;
5mod trade;
6
7use std::{fmt::Display, str::FromStr};
8
9use alloy::primitives::Address;
10use chrono::{DateTime, Utc};
11pub use event::*;
12pub use extension::*;
13pub use order::{OrderSide, OrderType};
14pub use request::{OrderRequest, RequestType};
15pub use trade::*;
16
17/// ID of perpetual contract.
18pub type PerpetualId = u32;
19
20/// Highest perpetual contract ID the exchange supports
21/// (`C._MAX_CONTRACT_ID`), so the ID space is `0..=MAX_PERPETUAL_ID`.
22pub const MAX_PERPETUAL_ID: PerpetualId = 1020;
23
24/// ID of exchange account.
25pub type AccountId = u32;
26
27/// Fee tier of an exchange account, indexing a [`crate::state::FeeSchedule`].
28/// Tier 0 is the base rate.
29pub type FeeTier = u8;
30
31/// Builder code attributed to an order. Zero means no builder.
32pub type BuilderId = u8;
33
34/// Account address or ID.
35#[derive(Clone, Copy, Debug)]
36pub enum AccountAddressOrID {
37    Address(Address),
38    ID(AccountId),
39}
40
41/// Exchange internal ID of the order.
42/// Unique only within particular perpetual contract at the
43/// exact point in time.
44/// Note: The exchange uses 0 as NULL_ORDER_ID sentinel, so valid order IDs are
45/// always non-zero.
46pub type OrderId = std::num::NonZeroU16;
47
48/// Order request ID.
49pub type RequestId = u64;
50
51/// Instant in chain history the state/event is up to date with.
52#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
53pub struct StateInstant {
54    block_number: u64,
55    block_timestamp: u64,
56}
57
58impl StateInstant {
59    pub fn new(block_number: u64, block_timestamp: u64) -> Self {
60        Self { block_number, block_timestamp }
61    }
62
63    pub fn block_number(&self) -> u64 { self.block_number }
64
65    pub fn block_timestamp(&self) -> u64 { self.block_timestamp }
66
67    pub fn next(&self) -> Self {
68        Self { block_number: self.block_number + 1, block_timestamp: self.block_timestamp }
69    }
70}
71
72impl Display for StateInstant {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        let ts = DateTime::<Utc>::from_timestamp(self.block_timestamp as i64, 0)
75            .unwrap()
76            .format("%Y-%m-%d %H:%M:%S");
77        if self.block_number > 0 {
78            write!(f, "#{} @ {}", self.block_number, ts)
79        } else {
80            write!(f, "{}", ts)
81        }
82    }
83}
84
85impl FromStr for AccountAddressOrID {
86    type Err = crate::error::DexError;
87
88    fn from_str(s: &str) -> Result<Self, Self::Err> {
89        if let Ok(address) = Address::from_str(s) {
90            return Ok(AccountAddressOrID::Address(address));
91        }
92        if let Ok(id) = AccountId::from_str(s) {
93            return Ok(AccountAddressOrID::ID(id));
94        }
95        Err(crate::error::DexError::InvalidArgument(format!(
96            "invalid account address or ID: {}",
97            s
98        )))
99    }
100}
101
102impl TryFrom<String> for AccountAddressOrID {
103    type Error = crate::error::DexError;
104
105    fn try_from(value: String) -> Result<Self, Self::Error> { AccountAddressOrID::from_str(&value) }
106}