use alloy_primitives::{Address, Bytes, U256, address};
use serde::{Deserialize, Serialize};
use x402_types::timestamp::UnixTimestamp;
use crate::chain::ChecksummedAddress;
pub const PERMIT2_ADDRESS: Address = address!("0x000000000022D473030F116dDEE9F6B43aC78BA3");
pub const EXACT_PERMIT2_PROXY_ADDRESS: Address =
address!("0x402085c248EeA27D92E8b30b2C58ed07f9E20001");
pub const UPTO_PERMIT2_PROXY_ADDRESS: Address =
address!("0x4020633461b2895a48930ff97ee8fcde8e520002");
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Permit2Authorization<TWitness> {
pub deadline: UnixTimestamp,
pub from: ChecksummedAddress,
#[serde(with = "crate::decimal_u256")]
pub nonce: U256,
pub permitted: Permit2AuthorizationPermitted,
pub spender: ChecksummedAddress,
pub witness: TWitness,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Permit2AuthorizationPermitted {
#[serde(with = "crate::decimal_u256")]
pub amount: U256,
pub token: ChecksummedAddress,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UptoPermit2Witness {
pub extra: Bytes,
pub to: ChecksummedAddress,
pub valid_after: UnixTimestamp,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExactPermit2Witness {
pub to: ChecksummedAddress,
pub valid_after: UnixTimestamp,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Permit2Payload<TWitness> {
pub permit_2_authorization: Permit2Authorization<TWitness>,
pub signature: Bytes,
}
pub type ExactPermit2Payload = Permit2Payload<ExactPermit2Witness>;
pub type UptoPermit2Payload = Permit2Payload<UptoPermit2Witness>;