use alloy::{
primitives::{Address, FixedBytes, U256},
providers::Provider,
};
use crate::{
contracts::ReputationRegistry,
error::Result,
types::{Feedback, ReputationSummary},
};
#[derive(Debug)]
pub struct Reputation<P> {
address: Address,
provider: P,
}
impl<P: Provider> Reputation<P> {
pub(crate) const fn new(provider: P, address: Address) -> Self {
Self { address, provider }
}
#[allow(clippy::too_many_arguments)]
pub async fn give_feedback(
&self,
agent_id: U256,
value: i128,
value_decimals: u8,
tag1: &str,
tag2: &str,
endpoint: &str,
feedback_uri: &str,
feedback_hash: FixedBytes<32>,
) -> Result<()> {
let contract = ReputationRegistry::new(self.address, &self.provider);
contract
.giveFeedback(
agent_id,
value,
value_decimals,
tag1.to_owned(),
tag2.to_owned(),
endpoint.to_owned(),
feedback_uri.to_owned(),
feedback_hash,
)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn revoke_feedback(&self, agent_id: U256, feedback_index: u64) -> Result<()> {
let contract = ReputationRegistry::new(self.address, &self.provider);
contract
.revokeFeedback(agent_id, feedback_index)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn append_response(
&self,
agent_id: U256,
client_address: Address,
feedback_index: u64,
response_uri: &str,
response_hash: FixedBytes<32>,
) -> Result<()> {
let contract = ReputationRegistry::new(self.address, &self.provider);
contract
.appendResponse(
agent_id,
client_address,
feedback_index,
response_uri.to_owned(),
response_hash,
)
.send()
.await?
.get_receipt()
.await?;
Ok(())
}
pub async fn read_feedback(
&self,
agent_id: U256,
client_address: Address,
feedback_index: u64,
) -> Result<Feedback> {
let contract = ReputationRegistry::new(self.address, &self.provider);
let r = contract
.readFeedback(agent_id, client_address, feedback_index)
.call()
.await?;
Ok(Feedback {
value: r.value,
value_decimals: r.valueDecimals,
tag1: r.tag1,
tag2: r.tag2,
is_revoked: r.isRevoked,
})
}
pub async fn read_all_feedback(
&self,
agent_id: U256,
client_addresses: Vec<Address>,
tag1: &str,
tag2: &str,
include_revoked: bool,
) -> Result<ReputationRegistry::readAllFeedbackReturn> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract
.readAllFeedback(
agent_id,
client_addresses,
tag1.to_owned(),
tag2.to_owned(),
include_revoked,
)
.call()
.await?)
}
pub async fn get_summary(
&self,
agent_id: U256,
client_addresses: Vec<Address>,
tag1: &str,
tag2: &str,
) -> Result<ReputationSummary> {
let contract = ReputationRegistry::new(self.address, &self.provider);
let r = contract
.getSummary(agent_id, client_addresses, tag1.to_owned(), tag2.to_owned())
.call()
.await?;
Ok(ReputationSummary {
count: r.count,
summary_value: r.summaryValue,
summary_value_decimals: r.summaryValueDecimals,
})
}
pub async fn get_clients(&self, agent_id: U256) -> Result<Vec<Address>> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract.getClients(agent_id).call().await?)
}
pub async fn get_last_index(&self, agent_id: U256, client_address: Address) -> Result<u64> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract
.getLastIndex(agent_id, client_address)
.call()
.await?)
}
pub async fn get_response_count(
&self,
agent_id: U256,
client_address: Address,
feedback_index: u64,
responders: Vec<Address>,
) -> Result<u64> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract
.getResponseCount(agent_id, client_address, feedback_index, responders)
.call()
.await?)
}
pub async fn get_identity_registry(&self) -> Result<Address> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract.getIdentityRegistry().call().await?)
}
pub async fn get_version(&self) -> Result<String> {
let contract = ReputationRegistry::new(self.address, &self.provider);
Ok(contract.getVersion().call().await?)
}
}