use alloy::providers::Provider;
use alloy_ens::ProviderEnsExt as _;
use alloy_primitives::Address;
use crate::{error::Result, record_key::evm_record_key};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum VerificationStatus {
Verified,
EnsRecordMissing,
}
impl VerificationStatus {
#[must_use]
pub const fn is_verified(self) -> bool {
matches!(self, Self::Verified)
}
}
impl core::fmt::Display for VerificationStatus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Verified => f.write_str("verified"),
Self::EnsRecordMissing => f.write_str("ENS record missing"),
}
}
}
pub async fn verify<P: Provider>(
provider: &P,
ens_name: &str,
chain_id: u64,
registry: Address,
agent_id: u64,
) -> Result<VerificationStatus> {
let key = evm_record_key(chain_id, registry, agent_id)?;
match provider.lookup_txt(ens_name, &key).await {
Ok(value) if !value.is_empty() => Ok(VerificationStatus::Verified),
Ok(_) | Err(alloy_ens::EnsError::ResolveTxtRecord(_)) => {
Ok(VerificationStatus::EnsRecordMissing)
}
Err(e) => Err(e.into()),
}
}
#[cfg(feature = "erc8004")]
pub async fn verify_agent<P: Provider>(
provider: &P,
network: erc8004::Network,
agent_id: u64,
ens_name: &str,
) -> Result<VerificationStatus> {
let chain_id = network.chain_id();
let registry = network.addresses().identity;
verify(provider, ens_name, chain_id, registry, agent_id).await
}