newton-chainio 0.5.2

newton prover chainio
//! Policy Data

use crate::error::ChainIoError;
use alloy::{primitives::Address, providers::WalletProvider, rpc::types::TransactionReceipt};
use eigensdk::common::get_signer;
use newton_core::{
    common::{address::get_policy_data_factory_address, chain::get_chain_id},
    newton_policy_data_factory::NewtonPolicyDataFactory,
};

use tracing::info;

/// PolicyDataController struct
#[derive(Debug)]
pub struct PolicyDataController {
    rpc_url: String,
    signer: String,
}

impl PolicyDataController {
    /// new instance
    pub fn new(signer: String, rpc_url: String) -> Self {
        PolicyDataController { signer, rpc_url }
    }

    /// Deploy a new policy data contract
    pub async fn deploy_policy_data(
        &self,
        policy_data_location: String,
        secrets_schema_cid: String,
        expire_after: u32,
        metadata_cid: String,
    ) -> 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_data_factory_addr = get_policy_data_factory_address(chain_id).await.unwrap();
        let policy_data_factory = NewtonPolicyDataFactory::new(policy_data_factory_addr, wallet);

        info!(
            "Deploying policy data: location: {}, expire_after: {}",
            policy_data_location, expire_after
        );

        let deploy_policy_data_call = policy_data_factory.deployPolicyData(
            policy_data_location,
            secrets_schema_cid,
            expire_after,
            metadata_cid,
            wallet_address,
        );

        let deploy_policy_data_result = deploy_policy_data_call.send().await;

        match deploy_policy_data_result {
            Ok(deploy_policy_data) => {
                let receipt_result = deploy_policy_data.get_receipt().await;

                match receipt_result {
                    Ok(receipt) => {
                        // Search through all logs to find the PolicyDataDeployed event
                        let mut policy_data_address = None;
                        for log in receipt.inner.logs() {
                            if let Ok(policy_data_deployed) =
                                log.log_decode::<NewtonPolicyDataFactory::PolicyDataDeployed>()
                            {
                                let data = policy_data_deployed.data();
                                policy_data_address = Some(data.policyData);
                                break;
                            }
                        }

                        if let Some(addr) = policy_data_address {
                            info!("Policy data deployed with address: {}", addr);
                            Ok((receipt, addr))
                        } else {
                            Err(ChainIoError::PolicyDataDeployedEventNotFound)
                        }
                    }

                    Err(e) => Err(ChainIoError::AlloyProviderError(e)),
                }
            }
            Err(e) => Err(ChainIoError::ContractError(e)),
        }
    }
}