use alloy::{
primitives::{Address, Bytes, U256},
providers::Provider,
};
use crate::{
contracts::IdentityRegistry,
error::{Error, Result},
};
#[derive(Debug)]
pub struct Identity<P> {
address: Address,
provider: P,
}
impl<P: Provider> Identity<P> {
pub(crate) const fn new(provider: P, address: Address) -> Self {
Self { address, provider }
}
pub async fn register(&self) -> Result<U256> {
let contract = IdentityRegistry::new(self.address, &self.provider);
let receipt = contract.register_0().send().await?.get_receipt().await?;
Self::parse_agent_id(&receipt)
}
pub async fn register_with_uri(&self, agent_uri: &str) -> Result<U256> {
let contract = IdentityRegistry::new(self.address, &self.provider);
let receipt = contract
.register_1(agent_uri.to_owned())
.send()
.await?
.get_receipt()
.await?;
Self::parse_agent_id(&receipt)
}
pub async fn register_with_metadata(
&self,
agent_uri: &str,
metadata: Vec<IdentityRegistry::MetadataEntry>,
) -> Result<U256> {
let contract = IdentityRegistry::new(self.address, &self.provider);
let receipt = contract
.register_2(agent_uri.to_owned(), metadata)
.send()
.await?
.get_receipt()
.await?;
Self::parse_agent_id(&receipt)
}
pub async fn set_agent_uri(&self, agent_id: U256, new_uri: &str) -> Result<()> {
let contract = IdentityRegistry::new(self.address, &self.provider);
contract
.setAgentURI(agent_id, new_uri.to_owned())
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn set_agent_wallet(
&self,
agent_id: U256,
new_wallet: Address,
deadline: U256,
signature: Bytes,
) -> Result<()> {
let contract = IdentityRegistry::new(self.address, &self.provider);
contract
.setAgentWallet(agent_id, new_wallet, deadline, signature)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn unset_agent_wallet(&self, agent_id: U256) -> Result<()> {
let contract = IdentityRegistry::new(self.address, &self.provider);
contract
.unsetAgentWallet(agent_id)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn set_metadata(&self, agent_id: U256, key: &str, value: Bytes) -> Result<()> {
let contract = IdentityRegistry::new(self.address, &self.provider);
contract
.setMetadata(agent_id, key.to_owned(), value)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn is_authorized_or_owner(&self, spender: Address, agent_id: U256) -> Result<bool> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract
.isAuthorizedOrOwner(spender, agent_id)
.call()
.await?)
}
pub async fn token_uri(&self, agent_id: U256) -> Result<String> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.tokenURI(agent_id).call().await?)
}
pub async fn owner_of(&self, agent_id: U256) -> Result<Address> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.ownerOf(agent_id).call().await?)
}
pub async fn get_agent_wallet(&self, agent_id: U256) -> Result<Address> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.getAgentWallet(agent_id).call().await?)
}
pub async fn get_metadata(&self, agent_id: U256, key: &str) -> Result<Bytes> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract
.getMetadata(agent_id, key.to_owned())
.call()
.await?)
}
pub async fn get_version(&self) -> Result<String> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.getVersion().call().await?)
}
pub async fn balance_of(&self, owner: Address) -> Result<U256> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.balanceOf(owner).call().await?)
}
pub async fn eip712_domain(&self) -> Result<IdentityRegistry::eip712DomainReturn> {
let contract = IdentityRegistry::new(self.address, &self.provider);
Ok(contract.eip712Domain().call().await?)
}
fn parse_agent_id(receipt: &alloy::rpc::types::TransactionReceipt) -> Result<U256> {
receipt
.inner
.logs()
.iter()
.find_map(|log| {
log.log_decode::<IdentityRegistry::Registered>()
.ok()
.map(|e| e.inner.data.agentId)
})
.ok_or(Error::Contract(alloy::contract::Error::UnknownFunction(
"register: no Registered event found".to_owned(),
)))
}
}