use alloy_primitives::{hex, Address, B256, U256};
use alloy_sol_types::sol;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize, Serializer};
use crate::types::Side;
use crate::v2::types::SignatureType;
#[derive(Debug, Clone)]
pub struct OrderData {
pub maker: Address,
pub signer: Option<Address>,
pub token_id: U256,
pub maker_amount: U256,
pub taker_amount: U256,
pub side: Side,
pub signature_type: Option<SignatureType>,
pub timestamp: Option<U256>,
pub metadata: Option<B256>,
pub builder: Option<B256>,
pub expiration: Option<U256>,
}
sol! {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Order {
uint256 salt;
address maker;
address signer;
uint256 tokenId;
uint256 makerAmount;
uint256 takerAmount;
uint8 side;
uint8 signatureType;
uint256 timestamp;
bytes32 metadata;
bytes32 builder;
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct SignedOrder {
#[serde(flatten)]
pub order: Order,
pub expiration: U256,
pub signature: String,
}
impl SignedOrder {
pub fn new(order: Order, expiration: U256, signature: Vec<u8>) -> Self {
Self {
order,
expiration,
signature: format!("0x{}", hex::encode(signature)),
}
}
}
fn side_from_u8(side: u8) -> &'static str {
match side {
0 => "BUY",
_ => "SELL",
}
}
impl Serialize for SignedOrder {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SignedOrder", 13)?;
let salt: u128 = self.order.salt.try_into().unwrap_or(0);
state.serialize_field("salt", &salt)?;
state.serialize_field("maker", &format!("{:?}", self.order.maker).to_lowercase())?;
state.serialize_field("signer", &format!("{:?}", self.order.signer).to_lowercase())?;
state.serialize_field("tokenId", &self.order.tokenId.to_string())?;
state.serialize_field("makerAmount", &self.order.makerAmount.to_string())?;
state.serialize_field("takerAmount", &self.order.takerAmount.to_string())?;
state.serialize_field("side", side_from_u8(self.order.side))?;
state.serialize_field("signatureType", &self.order.signatureType)?;
state.serialize_field("timestamp", &self.order.timestamp.to_string())?;
state.serialize_field(
"metadata",
&format!("{:?}", self.order.metadata).to_lowercase(),
)?;
state.serialize_field(
"builder",
&format!("{:?}", self.order.builder).to_lowercase(),
)?;
state.serialize_field("expiration", &self.expiration.to_string())?;
state.serialize_field("signature", &self.signature)?;
state.end()
}
}