use crate::error::ChainIoError;
use alloy::{
primitives::{Address, FixedBytes},
providers::WalletProvider,
rpc::types::TransactionReceipt,
};
use eigensdk::common::get_signer;
use newton_core::{
common::{address::get_policy_factory_address, chain::get_chain_id},
newton_policy_factory::NewtonPolicyFactory,
};
use tracing::info;
#[derive(Debug)]
pub struct PolicyController {
rpc_url: String,
signer: String,
}
impl PolicyController {
pub fn new(signer: String, rpc_url: String) -> Self {
PolicyController { signer, rpc_url }
}
pub async fn deploy_policy(
&self,
policy_cid: String,
schema_cid: String,
entrypoint: String,
policy_data: Vec<Address>,
metadata_cid: String,
policy_code_hash: FixedBytes<32>,
) -> Result<(TransactionReceipt, Address), ChainIoError> {
let wallet = get_signer(&self.signer, &self.rpc_url);
let wallet_address = wallet.default_signer_address();
let chain_id = get_chain_id(&self.rpc_url).await;
let policy_factory_addr = get_policy_factory_address(chain_id).await.unwrap();
let policy_factory = NewtonPolicyFactory::new(policy_factory_addr, wallet);
info!(
"[deploy_policy] entrypoint: {}, policyCid: {}, schemaCid: {}, policy_data: {}",
entrypoint,
policy_cid,
schema_cid,
policy_data
.iter()
.map(|addr| addr.to_string())
.collect::<Vec<String>>()
.join(", ")
);
let deploy_policy_call = policy_factory.deployPolicy(
entrypoint,
policy_cid,
schema_cid,
policy_data,
metadata_cid,
wallet_address,
policy_code_hash,
);
let deploy_policy_result = deploy_policy_call.send().await;
match deploy_policy_result {
Ok(deploy_policy) => {
let receipt_result = deploy_policy.get_receipt().await;
match receipt_result {
Ok(receipt) => {
let mut policy_address = None;
for log in receipt.inner.logs() {
if let Ok(policy_deployed) = log.log_decode::<NewtonPolicyFactory::PolicyDeployed>() {
let data = policy_deployed.data();
policy_address = Some(data.policy);
break;
}
}
if let Some(addr) = policy_address {
info!("Policy deployed with address: {}", addr);
Ok((receipt, addr))
} else {
Err(ChainIoError::PolicyDeployedEventNotFound)
}
}
Err(e) => Err(ChainIoError::AlloyProviderError(e)),
}
}
Err(e) => Err(ChainIoError::ContractError(e)),
}
}
}