use alloy_primitives::{Address, address};
use serde::{Deserialize, Serialize};
pub const VALIDATOR_ADDRESS: Address = address!("0xdAcD51A54883eb67D95FAEb2BBfdC4a9a6BD2a3B");
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum AssetTransferMethod {
Eip3009,
Permit2,
}
impl<'de> Deserialize<'de> for AssetTransferMethod {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
match raw.as_str() {
"eip3009" => Ok(Self::Eip3009),
"permit2" => Ok(Self::Permit2),
other => Err(serde::de::Error::custom(format!(
"unsupported assetTransferMethod `{other}`: r402-evm implements \
eip3009 and permit2 only (ERC-7710 is not implemented)"
))),
}
}
}
#[cfg(test)]
mod transfer_method_tests {
use super::AssetTransferMethod;
#[test]
fn serialises_as_camel_case_wire_strings() {
assert_eq!(
serde_json::to_string(&AssetTransferMethod::Eip3009).unwrap(),
"\"eip3009\""
);
assert_eq!(
serde_json::to_string(&AssetTransferMethod::Permit2).unwrap(),
"\"permit2\""
);
}
#[test]
fn deserialises_supported_methods() {
assert_eq!(
serde_json::from_str::<AssetTransferMethod>("\"eip3009\"").unwrap(),
AssetTransferMethod::Eip3009
);
assert_eq!(
serde_json::from_str::<AssetTransferMethod>("\"permit2\"").unwrap(),
AssetTransferMethod::Permit2
);
}
#[test]
fn rejects_erc7710_with_explicit_message() {
let err = serde_json::from_str::<AssetTransferMethod>("\"erc7710\"").unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("unsupported assetTransferMethod `erc7710`"),
"unexpected error: {msg}"
);
assert!(
msg.contains("ERC-7710 is not implemented"),
"unexpected error: {msg}"
);
}
#[test]
fn rejects_unknown_method() {
let err = serde_json::from_str::<AssetTransferMethod>("\"somethingElse\"").unwrap_err();
assert!(err.to_string().contains("unsupported assetTransferMethod"));
}
}