use alloy_contract::private::{Network, Provider};
use alloy_dyn_abi::TypedData;
use alloy_signer::{Signature, Signer};
use alloy_sol_types::private::Address;
use alloy_sol_types::{Eip712Domain, sol};
sol!(
#[sol(rpc)]
interface EIP712Contract {
function eip712Domain()
public
view
virtual
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
}
);
#[derive(thiserror::Error, Debug)]
pub enum EIP712Error {
#[allow(clippy::upper_case_acronyms)]
#[error("ABI encode error: {0}")]
ABI(#[from] alloy_dyn_abi::Error),
#[error("Signer error: {0}")]
Signer(#[from] alloy_signer::Error),
}
pub struct EIP712;
impl EIP712 {
pub async fn query_domain<N: Network, P: Provider<N>>(
provider: P,
token: Address,
) -> alloy_contract::Result<Eip712Domain> {
let eip712 = EIP712Contract::new(token, provider);
let domain = eip712.eip712Domain().call().await?;
Ok(Eip712Domain {
chain_id: Some(domain.chainId),
name: Some(domain.name.into()),
verifying_contract: Some(domain.verifyingContract),
version: Some(domain.version.into()),
salt: None,
})
}
pub async fn sign<S: Signer>(data: TypedData, signer: S) -> Result<Signature, EIP712Error> {
let hash = data.eip712_signing_hash()?;
let sig = signer.sign_hash(&hash).await?;
Ok(sig)
}
}