use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u64)]
pub enum ChainId {
BnbMainnet = 56,
BnbTestnet = 97,
}
impl ChainId {
pub fn as_u64(&self) -> u64 {
*self as u64
}
}
impl TryFrom<u64> for ChainId {
type Error = crate::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
56 => Ok(ChainId::BnbMainnet),
97 => Ok(ChainId::BnbTestnet),
_ => Err(crate::Error::InvalidChainId(value)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Side {
Buy = 0,
Sell = 1,
}
impl Serialize for Side {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_u8(*self as u8)
}
}
impl<'de> Deserialize<'de> for Side {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct SideVisitor;
impl<'de> serde::de::Visitor<'de> for SideVisitor {
type Value = Side;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("0, 1, \"BUY\", or \"SELL\"")
}
fn visit_u64<E: serde::de::Error>(self, value: u64) -> Result<Side, E> {
match value {
0 => Ok(Side::Buy),
1 => Ok(Side::Sell),
_ => Err(E::invalid_value(serde::de::Unexpected::Unsigned(value), &self)),
}
}
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Side, E> {
match value {
"BUY" | "Buy" | "buy" => Ok(Side::Buy),
"SELL" | "Sell" | "sell" => Ok(Side::Sell),
_ => Err(E::invalid_value(serde::de::Unexpected::Str(value), &self)),
}
}
}
deserializer.deserialize_any(SideVisitor)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum SignatureType {
Eoa = 0,
PolyProxy = 1,
PolyGnosisSafe = 2,
}
impl Serialize for SignatureType {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_u8(*self as u8)
}
}
impl<'de> Deserialize<'de> for SignatureType {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct SignatureTypeVisitor;
impl<'de> serde::de::Visitor<'de> for SignatureTypeVisitor {
type Value = SignatureType;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("0, 1, 2, or a string like \"EOA\"")
}
fn visit_u64<E: serde::de::Error>(self, value: u64) -> Result<SignatureType, E> {
match value {
0 => Ok(SignatureType::Eoa),
1 => Ok(SignatureType::PolyProxy),
2 => Ok(SignatureType::PolyGnosisSafe),
_ => Err(E::invalid_value(serde::de::Unexpected::Unsigned(value), &self)),
}
}
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<SignatureType, E> {
match value {
"EOA" | "eoa" => Ok(SignatureType::Eoa),
"POLY_PROXY" => Ok(SignatureType::PolyProxy),
"POLY_GNOSIS_SAFE" => Ok(SignatureType::PolyGnosisSafe),
_ => Err(E::invalid_value(serde::de::Unexpected::Str(value), &self)),
}
}
}
deserializer.deserialize_any(SignatureTypeVisitor)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MarketType {
pub is_neg_risk: bool,
pub is_yield_bearing: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Order {
pub salt: String,
pub maker: String,
pub signer: String,
pub taker: String,
pub token_id: String,
pub maker_amount: String,
pub taker_amount: String,
pub expiration: String,
pub nonce: String,
pub fee_rate_bps: String,
pub side: Side,
pub signature_type: SignatureType,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignedOrder {
#[serde(flatten)]
pub order: Order,
#[serde(skip_serializing_if = "Option::is_none")]
pub hash: Option<String>,
pub signature: String,
}
#[derive(Debug, Clone)]
pub struct BuildOrderInput {
pub side: Side,
pub token_id: String,
pub maker_amount: String,
pub taker_amount: String,
pub fee_rate_bps: u64,
pub signer: Option<String>,
pub nonce: Option<String>,
pub salt: Option<String>,
pub maker: Option<String>,
pub taker: Option<String>,
pub signature_type: Option<SignatureType>,
pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OrderStrategy {
Market,
Limit,
}
impl OrderStrategy {
pub fn as_str(&self) -> &'static str {
match self {
OrderStrategy::Market => "MARKET",
OrderStrategy::Limit => "LIMIT",
}
}
}
#[derive(Debug, Clone)]
pub struct LimitOrderData {
pub side: Side,
pub price_per_share_wei: rust_decimal::Decimal,
pub quantity_wei: rust_decimal::Decimal,
}
#[derive(Debug, Clone)]
pub struct LimitOrderAmounts {
pub last_price: rust_decimal::Decimal,
pub price_per_share: rust_decimal::Decimal,
pub maker_amount: rust_decimal::Decimal,
pub taker_amount: rust_decimal::Decimal,
}
pub type DepthLevel = (f64, f64);
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Book {
pub market_id: u64,
pub update_timestamp_ms: u64,
pub asks: Vec<DepthLevel>,
pub bids: Vec<DepthLevel>,
}
#[derive(Debug, Clone)]
pub struct CancelOrdersOptions {
pub is_yield_bearing: bool,
pub is_neg_risk: bool,
pub with_validation: bool,
}
impl Default for CancelOrdersOptions {
fn default() -> Self {
Self {
is_yield_bearing: false,
is_neg_risk: false,
with_validation: true,
}
}
}
#[derive(Debug, Clone)]
pub struct RedeemPositionsOptions {
pub condition_id: String,
pub index_set: u8, pub is_neg_risk: bool,
pub is_yield_bearing: bool,
pub amount: Option<rust_decimal::Decimal>,
}
#[derive(Debug, Clone)]
pub struct MergePositionsOptions {
pub condition_id: String,
pub amount: rust_decimal::Decimal,
pub is_neg_risk: bool,
pub is_yield_bearing: bool,
}
#[derive(Debug, Clone)]
pub struct SplitPositionsOptions {
pub condition_id: String,
pub amount: rust_decimal::Decimal,
pub is_neg_risk: bool,
pub is_yield_bearing: bool,
}