newton-testing-utils 0.1.38

newton provero testing utils
Documentation
//! testing utils for newton prover rs

use alloy::{
    primitives::{Address, Bytes, B256, U256},
    providers::Provider,
    sol,
    sol_types::SolCall,
};
use eigen_common::get_provider;
use newton_prover_core::{
    common::{
        address::{get_newton_prover_task_manager, get_test_newton_policy_data_address},
        chain::get_chain_id,
        policy::{get_policy_address_for_policy_client, get_policy_id_for_policy_client},
        task_id,
    },
    newton_policy::NewtonPolicy,
    newton_policy_data::NewtonPolicyData,
    newton_prover_task_manager::{INewtonPolicy, INewtonProverTaskManager, NewtonMessage, NewtonProverTaskManager},
};

use crate::{
    anvil::FIRST_ADDRESS,
    policy::{TEST_POLICY_DATA, TEST_POLICY_REGO, TEST_POLICY_WASM_ARGS},
};

/// Anvil testing utils
pub mod anvil;

/// Demo testing utils
pub mod demo;

/// Policy mocks
pub mod policy;

/// Get the sample operator metadata uri
pub fn get_sample_operator_metadata_uri() -> String {
    "https://ipfs.newt.foundation/ipfs/bafkreihsu65fec7vx7zbg76f5zfvdwanhd33lil4s5vsb4yvffbeocw7di".to_string()
}

/// Get the test policy task data with proper attestation
pub async fn get_test_policy_task_data(rpc_url: &str, policy_client_address: Address) -> NewtonMessage::PolicyTaskData {
    use alloy::{primitives::keccak256, signers::k256::ecdsa::SigningKey, sol_types::SolValue};

    let policy_address = get_policy_address_for_policy_client(rpc_url, policy_client_address)
        .await
        .unwrap();
    let policy_id = get_policy_id_for_policy_client(rpc_url, policy_client_address)
        .await
        .unwrap();
    let policy_data_address = get_test_newton_policy_data_address(get_chain_id(rpc_url).await)
        .await
        .unwrap();
    let provider = get_provider(rpc_url);
    let policy_data_contract = NewtonPolicyData::new(policy_data_address, &provider);
    let expire_after = policy_data_contract.getExpireAfter().call().await.unwrap();
    let expire_block = provider.get_block_number().await.unwrap() as u32 + expire_after;

    // Get policy data location from the contract
    let policy_data_location = policy_data_contract.getWasmCid().call().await.unwrap();

    let policy = Bytes::from(TEST_POLICY_REGO.as_bytes());

    // Create policy data bytes (in a real scenario this would come from WASM execution)
    let policy_data_bytes = Bytes::from(TEST_POLICY_DATA.as_bytes());

    // Create attestation signature for the policy data
    // Use a deterministic private key for testing (this should match a registered attester)
    let test_private_key = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; // anvil account 0
    let signing_key = SigningKey::from_slice(&alloy::hex::decode(test_private_key).unwrap()).unwrap();

    // Create the same message hash that the contract expects
    let message_hash = keccak256(
        (
            policy_id,
            policy_data_bytes.clone(),
            policy_data_address,
            expire_block,
            policy_data_location,
        )
            .abi_encode(),
    );

    // Sign the message hash
    let signature = signing_key.sign_recoverable(message_hash.as_ref()).unwrap();
    let attestation = Bytes::from(signature.0.to_vec());

    let policy_data = NewtonMessage::PolicyData {
        wasmArgs: TEST_POLICY_WASM_ARGS.as_bytes().into(),
        data: policy_data_bytes,
        attestation,
        policyDataAddress: policy_data_address,
        expireBlock: expire_block,
    };

    NewtonMessage::PolicyTaskData {
        policyId: policy_id,
        policyAddress: policy_address,
        policy,
        policyData: vec![policy_data],
    }
}

/// Get the test prover task
pub async fn get_test_prover_task(rpc_url: &str, policy_client_address: Address) -> INewtonProverTaskManager::Task {
    let intent = get_test_intent(rpc_url).await;
    let policy_task_data = get_test_policy_task_data(rpc_url, policy_client_address).await;

    let task_created_block = get_provider(rpc_url).get_block_number().await.unwrap() as u32;

    let policy_config = NewtonPolicy::new(policy_task_data.policyAddress, get_provider(rpc_url))
        .getPolicyConfig(policy_task_data.policyId)
        .call()
        .await
        .unwrap();
    let policy_config = INewtonPolicy::PolicyConfig {
        policyParams: policy_config.policyParams,
        expireAfter: policy_config.expireAfter,
    };

    // Task is now minimal - policyTaskData and policyConfig are in TaskResponse
    let mut task = INewtonProverTaskManager::Task {
        policyClient: policy_client_address,
        taskId: B256::default(),
        intent,
        intentSignature: Bytes::default(),
        wasmArgs: policy::TEST_POLICY_WASM_ARGS.as_bytes().into(),
        taskCreatedBlock: task_created_block,
        quorumNumbers: Bytes::from([0]), // quorum number 0
        quorumThresholdPercentage: 0,
        initializationTimestamp: U256::ZERO,
    };
    let task_id = task_id(None);
    task.taskId = task_id;
    task
}

sol! {
    // MockToken token buy contract
    contract MockToken {
        function mint(address account, uint256 amount) public {}
        function buy(address token, uint256 amount) public {}
    }
}

/// Get the test intent
pub async fn get_test_intent(rpc_url: &str) -> NewtonMessage::Intent {
    let chain_id = get_chain_id(rpc_url).await;

    let buy_call = MockToken::buyCall {
        token: match chain_id {
            31337 => "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
            11155111 => "0x29f2D40B0605204364af54EC677bD022dA425d03".parse().unwrap(),
            _ => "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
        },
        amount: U256::from(200000000000u64),
    };
    let calldata = buy_call.abi_encode();

    NewtonMessage::Intent {
        from: FIRST_ADDRESS,
        to: "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
        value: U256::from(10000000000000000u64),
        data: calldata.into(),
        chainId: U256::from(chain_id),
        functionSignature: "function buy(address token, uint256 amount)".as_bytes().to_vec().into(),
    }
}