Skip to main content

newton_testing_utils/
lib.rs

1//! testing utils for newton prover rs
2
3use alloy::{
4    primitives::{Address, Bytes, B256, U256},
5    providers::Provider,
6    sol,
7    sol_types::SolCall,
8};
9use eigen_common::get_provider;
10use newton_prover_core::{
11    common::{
12        address::{get_newton_prover_task_manager, get_test_newton_policy_data_address},
13        chain::get_chain_id,
14        policy::{get_policy_address_for_policy_client, get_policy_id_for_policy_client},
15        task_id,
16    },
17    newton_policy::NewtonPolicy,
18    newton_policy_data::NewtonPolicyData,
19    newton_prover_task_manager::{INewtonPolicy, INewtonProverTaskManager, NewtonMessage, NewtonProverTaskManager},
20};
21
22use crate::{
23    anvil::FIRST_ADDRESS,
24    policy::{TEST_POLICY_DATA, TEST_POLICY_REGO, TEST_POLICY_WASM_ARGS},
25};
26
27/// Anvil testing utils
28pub mod anvil;
29
30/// Demo testing utils
31pub mod demo;
32
33/// Policy mocks
34pub mod policy;
35
36/// Get the sample operator metadata uri
37pub fn get_sample_operator_metadata_uri() -> String {
38    "https://ipfs.newt.foundation/ipfs/bafkreihsu65fec7vx7zbg76f5zfvdwanhd33lil4s5vsb4yvffbeocw7di".to_string()
39}
40
41/// Get the test policy task data with proper attestation
42pub async fn get_test_policy_task_data(rpc_url: &str, policy_client_address: Address) -> NewtonMessage::PolicyTaskData {
43    use alloy::{primitives::keccak256, signers::k256::ecdsa::SigningKey, sol_types::SolValue};
44
45    let policy_address = get_policy_address_for_policy_client(rpc_url, policy_client_address)
46        .await
47        .unwrap();
48    let policy_id = get_policy_id_for_policy_client(rpc_url, policy_client_address)
49        .await
50        .unwrap();
51    let policy_data_address = get_test_newton_policy_data_address(get_chain_id(rpc_url).await)
52        .await
53        .unwrap();
54    let provider = get_provider(rpc_url);
55    let policy_data_contract = NewtonPolicyData::new(policy_data_address, &provider);
56    let expire_after = policy_data_contract.getExpireAfter().call().await.unwrap();
57    let expire_block = provider.get_block_number().await.unwrap() as u32 + expire_after;
58
59    // Get policy data location from the contract
60    let policy_data_location = policy_data_contract.getWasmCid().call().await.unwrap();
61
62    let policy = Bytes::from(TEST_POLICY_REGO.as_bytes());
63
64    // Create policy data bytes (in a real scenario this would come from WASM execution)
65    let policy_data_bytes = Bytes::from(TEST_POLICY_DATA.as_bytes());
66
67    // Create attestation signature for the policy data
68    // Use a deterministic private key for testing (this should match a registered attester)
69    let test_private_key = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; // anvil account 0
70    let signing_key = SigningKey::from_slice(&alloy::hex::decode(test_private_key).unwrap()).unwrap();
71
72    // Create the same message hash that the contract expects
73    let message_hash = keccak256(
74        (
75            policy_id,
76            policy_data_bytes.clone(),
77            policy_data_address,
78            expire_block,
79            policy_data_location,
80        )
81            .abi_encode(),
82    );
83
84    // Sign the message hash
85    let signature = signing_key.sign_recoverable(message_hash.as_ref()).unwrap();
86    let attestation = Bytes::from(signature.0.to_vec());
87
88    let policy_data = NewtonMessage::PolicyData {
89        wasmArgs: TEST_POLICY_WASM_ARGS.as_bytes().into(),
90        data: policy_data_bytes,
91        attestation,
92        policyDataAddress: policy_data_address,
93        expireBlock: expire_block,
94    };
95
96    NewtonMessage::PolicyTaskData {
97        policyId: policy_id,
98        policyAddress: policy_address,
99        policy,
100        policyData: vec![policy_data],
101    }
102}
103
104/// Get the test prover task
105pub async fn get_test_prover_task(rpc_url: &str, policy_client_address: Address) -> INewtonProverTaskManager::Task {
106    let intent = get_test_intent(rpc_url).await;
107    let policy_task_data = get_test_policy_task_data(rpc_url, policy_client_address).await;
108
109    let task_created_block = get_provider(rpc_url).get_block_number().await.unwrap() as u32;
110
111    let policy_config = NewtonPolicy::new(policy_task_data.policyAddress, get_provider(rpc_url))
112        .getPolicyConfig(policy_task_data.policyId)
113        .call()
114        .await
115        .unwrap();
116    let policy_config = INewtonPolicy::PolicyConfig {
117        policyParams: policy_config.policyParams,
118        expireAfter: policy_config.expireAfter,
119    };
120
121    // Task is now minimal - policyTaskData and policyConfig are in TaskResponse
122    let mut task = INewtonProverTaskManager::Task {
123        policyClient: policy_client_address,
124        taskId: B256::default(),
125        intent,
126        intentSignature: Bytes::default(),
127        wasmArgs: policy::TEST_POLICY_WASM_ARGS.as_bytes().into(),
128        taskCreatedBlock: task_created_block,
129        quorumNumbers: Bytes::from([0]), // quorum number 0
130        quorumThresholdPercentage: 0,
131        initializationTimestamp: U256::ZERO,
132    };
133    let task_id = task_id(None);
134    task.taskId = task_id;
135    task
136}
137
138sol! {
139    // MockToken token buy contract
140    contract MockToken {
141        function mint(address account, uint256 amount) public {}
142        function buy(address token, uint256 amount) public {}
143    }
144}
145
146/// Get the test intent
147pub async fn get_test_intent(rpc_url: &str) -> NewtonMessage::Intent {
148    let chain_id = get_chain_id(rpc_url).await;
149
150    let buy_call = MockToken::buyCall {
151        token: match chain_id {
152            31337 => "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
153            11155111 => "0x29f2D40B0605204364af54EC677bD022dA425d03".parse().unwrap(),
154            _ => "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
155        },
156        amount: U256::from(200000000000u64),
157    };
158    let calldata = buy_call.abi_encode();
159
160    NewtonMessage::Intent {
161        from: FIRST_ADDRESS,
162        to: "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf".parse().unwrap(),
163        value: U256::from(10000000000000000u64),
164        data: calldata.into(),
165        chainId: U256::from(chain_id),
166        functionSignature: "function buy(address token, uint256 amount)".as_bytes().to_vec().into(),
167    }
168}