From 43f8e533af4e2cecc35d095827db74bc540e6aec Mon Sep 17 00:00:00 2001 From: h3rt <94856309+SecretSaturn@users.noreply.github.com> Date: Wed, 11 Sep 2024 05:03:34 +0200 Subject: [PATCH] Fix secret gateway tests & improve contract --- TNLS-Gateways/secret/src/contract.rs | 354 ++++++++++++++++++--------- config.yml | 22 +- 2 files changed, 254 insertions(+), 122 deletions(-) diff --git a/TNLS-Gateways/secret/src/contract.rs b/TNLS-Gateways/secret/src/contract.rs index 207bc38..6dc306f 100644 --- a/TNLS-Gateways/secret/src/contract.rs +++ b/TNLS-Gateways/secret/src/contract.rs @@ -1,23 +1,26 @@ +use crate::{ + msg::{ + ExecuteMsg, InputResponse, InstantiateMsg, MigrateMsg, PostExecutionMsg, PreExecutionMsg, + PublicKeyResponse, QueryMsg, ResponseStatus::Success, SecretMsg, + }, + state::{ + KeyPair, ResultInfo, State, Task, TaskInfo, CONFIG, CREATOR, MY_ADDRESS, RESULT_MAP, + TASK_MAP, + }, + PrivContractHandleMsg, +}; +use base64::{engine::general_purpose::STANDARD, Engine}; use cosmwasm_std::{ - from_binary, entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, - StdResult, + entry_point, from_binary, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, + StdError, StdResult, }; +use hex::ToHex; use secret_toolkit::{ crypto::secp256k1::{PrivateKey, PublicKey}, crypto::{sha_256, ContractPrng}, utils::{pad_handle_result, pad_query_result, HandleCallback}, }; -use base64::{engine::general_purpose, Engine}; -use hex::ToHex; use sha3::{Digest, Keccak256}; -use crate::{ - msg::{ - ExecuteMsg, InputResponse, InstantiateMsg, PostExecutionMsg, PreExecutionMsg, - PublicKeyResponse, QueryMsg, ResponseStatus::Success, SecretMsg, MigrateMsg - }, - state::{KeyPair, State, Task, TaskInfo, ResultInfo, CONFIG, CREATOR, MY_ADDRESS, TASK_MAP, RESULT_MAP}, - PrivContractHandleMsg, -}; /// pad handle responses and log attributes to blocks of 256 bytes to prevent leaking info based on /// response size @@ -72,7 +75,6 @@ pub fn instantiate( } #[cfg(feature = "contract")] - ///////////////////////////////////// Handle ////////////////////////////////////// /// Returns HandleResult /// @@ -81,14 +83,9 @@ pub fn instantiate( /// * `deps` - mutable reference to Extern containing all the contract's external dependencies /// * `env` - Env of contract's environment /// * `msg` - HandleMsg passed in with the execute message -/// +/// #[entry_point] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> StdResult { +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { let response = match msg { ExecuteMsg::Input { inputs } => pre_execution(deps, env, inputs), ExecuteMsg::Output { outputs } => post_execution(deps, env, outputs), @@ -100,13 +97,10 @@ pub fn execute( #[entry_point] pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { match msg { - MigrateMsg::Migrate {} => { - Ok(Response::default()) - } + MigrateMsg::Migrate {} => Ok(Response::default()), } } - fn rotate_gateway_keys(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { // load config let state = CONFIG.load(deps.storage)?; @@ -115,10 +109,11 @@ fn rotate_gateway_keys(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult< // check if the keys have already been created if state.keyed { - //if keys were have already been created, check if admin is calling this + //if keys were have already been created, check if admin is calling this if state.admin != caller_raw { return Err(StdError::generic_err( - "keys have already been created and only admin is allowed to rotate gateway keys".to_string(), + "keys have already been created and only admin is allowed to rotate gateway keys" + .to_string(), )); } } @@ -196,49 +191,60 @@ fn pre_execution(deps: DepsMut, _env: Env, msg: PreExecutionMsg) -> StdResult { // If decryption is successful, attempt to verify match msg.verify(&deps) { - Ok(_) => decrypted_payload, // Both decryption and verification succeeded + Ok(_) => { + unsafe_payload = false; + // Both decryption and verification succeeded + decrypted_payload + } Err(_err) => { - unsafe_payload = true; //return Err(StdError::generic_err(format!("Verification failed: {}", err))); // Continue with the decrypted payload if only verification fails decrypted_payload } } - }, + } Err(_err) => { - unsafe_payload = true; //return Err(StdError::generic_err(format!("Decryption failed: {}", err))); // If decryption fails, continue with the original, encrypted payload // We are not verifying the payload in this case as it's already deemed unsafe from_binary(&Binary::from(msg.payload.as_slice()))? - }, + } }; - + // verify the internal verification key matches the user address if payload.user_key != msg.user_key { return Err(StdError::generic_err("verification key mismatch")); @@ -254,21 +260,30 @@ fn pre_execution(deps: DepsMut, _env: Env, msg: PreExecutionMsg) -> StdResult StdResult::try_from(config.signing_keys.sk.as_slice()).unwrap(); + let signing_key_bytes = config.signing_keys.sk.as_slice(); - let signature = deps.api.secp256k1_sign(&input_hash, &signing_key_bytes) + let signature = deps + .api + .secp256k1_sign(&input_hash, &signing_key_bytes) .map_err(|err| StdError::generic_err(err.to_string()))?; // construct the message to send to the destination contract @@ -334,9 +351,13 @@ fn post_execution(deps: DepsMut, env: Env, msg: PostExecutionMsg) -> StdResult bytes, - Err(_) => {return Err(StdError::generic_err("could not decode base64 result string"));} + Err(_) => { + return Err(StdError::generic_err( + "could not decode base64 result string", + )); + } }; // rename for clarity (original source network is now the routing destination) @@ -358,11 +379,11 @@ fn post_execution(deps: DepsMut, env: Env, msg: PostExecutionMsg) -> StdResult StdResult StdResult StdResult()); + let payload_hash = format!( + "0x{}", + task_info.payload_hash.as_slice().encode_hex::() + ); let result = format!("0x{}", result.as_slice().encode_hex::()); let packet_hash = format!("0x{}", sha_256(&packet_hash).encode_hex::()); - let packet_signature = format!("0x{}{:x}", &packet_signature.encode_hex::(),packet_recovery_id); - let callback_address = format!("0x{}", task_info.callback_address.as_slice().encode_hex::()); - let callback_selector = format!("0x{}", task_info.callback_selector.as_slice().encode_hex::()); - let callback_gas_limit = format!("0x{}", task_info.callback_gas_limit.to_be_bytes().encode_hex::()); + let packet_signature = format!( + "0x{}{:x}", + &packet_signature.encode_hex::(), + packet_recovery_id + ); + let callback_address = format!( + "0x{}", + task_info.callback_address.as_slice().encode_hex::() + ); + let callback_selector = format!( + "0x{}", + task_info + .callback_selector + .as_slice() + .encode_hex::() + ); + let callback_gas_limit = format!( + "0x{}", + task_info + .callback_gas_limit + .to_be_bytes() + .encode_hex::() + ); // task info let result_info = ResultInfo { @@ -492,7 +530,10 @@ fn post_execution(deps: DepsMut, env: Env, msg: PostExecutionMsg) -> StdResult StdResult StdResult { let response = match msg { QueryMsg::GetPublicKeys {} => query_public_keys(deps), - QueryMsg::GetExecutionResult {task} => query_execution_result(deps, task), + QueryMsg::GetExecutionResult { task } => query_execution_result(deps, task), }; pad_query_result(response, BLOCK_SIZE) } fn query_execution_result(deps: Deps, task: Task) -> StdResult { - let task_info = RESULT_MAP .get(deps.storage, &task) .ok_or_else(|| StdError::generic_err("task not found"))?; @@ -536,7 +576,7 @@ fn query_execution_result(deps: Deps, task: Task) -> StdResult { packet_signature: task_info.packet_signature, callback_address: task_info.callback_address, callback_selector: task_info.callback_selector, - callback_gas_limit: task_info.callback_gas_limit + callback_gas_limit: task_info.callback_gas_limit, }) } @@ -545,7 +585,10 @@ fn query_public_keys(deps: Deps) -> StdResult { let state: State = CONFIG.load(deps.storage)?; to_binary(&PublicKeyResponse { encryption_key: state.encryption_keys.pk, - verification_key: format!("0x{}",state.signing_keys.pk.as_slice().encode_hex::()), + verification_key: format!( + "0x{}", + state.signing_keys.pk.as_slice().encode_hex::() + ), }) } @@ -558,10 +601,7 @@ fn query_public_keys(deps: Deps) -> StdResult { /// # Arguments /// /// * `env` - contract's environment to be used for randomization -pub fn generate_keypair( - env: &Env, -) -> Result<(PrivateKey, PublicKey), StdError> { - +pub fn generate_keypair(env: &Env) -> Result<(PrivateKey, PublicKey), StdError> { // generate and return key pair let mut rng = ContractPrng::from_env(env); let sk = PrivateKey::parse(&rng.rand_bytes())?; @@ -570,13 +610,12 @@ pub fn generate_keypair( Ok((sk, pk)) } - #[cfg(test)] mod tests { use super::*; use crate::types::*; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_binary, Addr, Api, Binary, Empty}; + use cosmwasm_std::{from_binary, Addr, Binary}; use chacha20poly1305::aead::{Aead, NewAead}; use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce}; @@ -680,8 +719,14 @@ mod tests { routing_code_hash: routing_code_hash.clone(), user_address: user_address.clone(), user_key: user_key.clone(), - callback_address: base64::encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()).as_bytes().into(), - callback_selector: base64::encode(hex::decode("faef40fe").unwrap()).as_bytes().into(), + callback_address: STANDARD + .encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()) + .as_bytes() + .into(), + callback_selector: STANDARD + .encode(hex::decode("faef40fe").unwrap()) + .as_bytes() + .into(), callback_gas_limit: 300_000u32, }; let serialized_payload = to_binary(&payload).unwrap(); @@ -699,18 +744,14 @@ mod tests { let prefix = "\x19Ethereum Signed Message:\n32".as_bytes(); let mut hasher = Keccak256::new(); - // NOTE: hmmm shouldn't this be a hash of the non-encrypted payload? hasher.update(encrypted_payload.as_slice()); let payload_hash_tmp = hasher.finalize_reset(); hasher.update([prefix, &payload_hash_tmp].concat()); let payload_hash = hasher.finalize(); - // let message = Message::from_slice(&payload_hash).unwrap(); - // let payload_signature = secp.sign_ecdsa(&message, &secret_key); - - let payload_signature = deps.api.secp256k1_sign(&payload_hash, secret_key.as_ref()).unwrap(); + let payload_signature = secp.sign_ecdsa(&Message::from_slice(&payload_hash).unwrap(), &secret_key).serialize_compact(); - // mock wrong payload (encrypted with a key that does not match the one inside the payload) + // mock wrong payload (signed payload_hash does not correspond to the payload) let wrong_user_address = Addr::unchecked("wrong eth address".to_string()); let wrong_user_key = Binary(wrong_public_key.serialize().to_vec()); @@ -720,8 +761,14 @@ mod tests { routing_code_hash: routing_code_hash.clone(), user_address: wrong_user_address.clone(), user_key: wrong_user_key.clone(), - callback_address: base64::encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()).as_bytes().into(), - callback_selector: base64::encode(hex::decode("faef40fe").unwrap()).as_bytes().into(), + callback_address: STANDARD + .encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()) + .as_bytes() + .into(), + callback_selector: STANDARD + .encode(hex::decode("faef40fe").unwrap()) + .as_bytes() + .into(), callback_gas_limit: 300_000u32, }; let wrong_serialized_payload = to_binary(&wrong_payload).unwrap(); @@ -751,6 +798,70 @@ mod tests { inputs: pre_execution_msg, }; let err = execute(deps.as_mut(), env.clone(), info.clone(), handle_msg).unwrap_err(); + assert_eq!( + err, + StdError::generic_err("Hashed Payload does not match payload hash") + ); + + // mock payload with wrong user address (encrypted with a key that does not match the one inside the payload) + let wrong_user_address = Addr::unchecked("wrong eth address".to_string()); + let wrong_user_key = Binary(wrong_public_key.serialize().to_vec()); + + let wrong_payload = Payload { + data: data.clone(), + routing_info: routing_info.clone(), + routing_code_hash: routing_code_hash.clone(), + user_address: wrong_user_address.clone(), + user_key: wrong_user_key.clone(), + callback_address: STANDARD + .encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()) + .as_bytes() + .into(), + callback_selector: STANDARD + .encode(hex::decode("faef40fe").unwrap()) + .as_bytes() + .into(), + callback_gas_limit: 300_000u32, + }; + let wrong_serialized_payload = to_binary(&wrong_payload).unwrap(); + + // encrypt the mock wrong payload + let wrong_encrypted_payload = cipher + .encrypt(nonce, wrong_serialized_payload.as_slice()) + .unwrap(); + + // make wrong payload hash + let prefix = "\x19Ethereum Signed Message:\n32".as_bytes(); + let mut hasher = Keccak256::new(); + + hasher.update(wrong_encrypted_payload.as_slice()); + let wrong_payload_hash_tmp = hasher.finalize_reset(); + hasher.update([prefix, &wrong_payload_hash_tmp].concat()); + let wrong_payload_hash = hasher.finalize(); + + // make wrong payload signature + let wrong_payload_signature = secp.sign_ecdsa(&Message::from_slice(&wrong_payload_hash).unwrap(), &secret_key).serialize_compact(); + + // test payload user_key does not match given user_key + let pre_execution_msg = PreExecutionMsg { + task_id: "1".to_string(), + source_network: "ethereum".to_string(), + routing_info: routing_info.clone(), + routing_code_hash: routing_code_hash.clone(), + payload: Binary(wrong_encrypted_payload.clone()), + payload_hash: Binary(wrong_payload_hash.to_vec()), + payload_signature: Binary(wrong_payload_signature.to_vec()), + user_address: wrong_user_address.clone(), + user_key: user_key.clone(), + user_pubkey: user_pubkey.clone(), + handle: "test".to_string(), + nonce: Binary(b"unique nonce".to_vec()), + callback_gas_limit: 300_000u32, + }; + let handle_msg = ExecuteMsg::Input { + inputs: pre_execution_msg, + }; + let err = execute(deps.as_mut(), env.clone(), info.clone(), handle_msg).unwrap_err(); assert_eq!(err, StdError::generic_err("verification key mismatch")); // wrong routing info @@ -850,8 +961,14 @@ mod tests { routing_code_hash: routing_code_hash.clone(), user_address: user_address.clone(), user_key: user_key.clone(), - callback_address: base64::encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()).as_bytes().into(), - callback_selector: base64::encode(hex::decode("faef40fe").unwrap()).as_bytes().into(), + callback_address: STANDARD + .encode(hex::decode("ae2Fc483527B8EF99EB5D9B44875F005ba1FaE13").unwrap()) + .as_bytes() + .into(), + callback_selector: STANDARD + .encode(hex::decode("faef40fe").unwrap()) + .as_bytes() + .into(), callback_gas_limit: 300_000u32, }; let serialized_payload = to_binary(&payload).unwrap(); @@ -874,7 +991,7 @@ mod tests { hasher.update([prefix, &payload_hash_tmp].concat()); let payload_hash = hasher.finalize(); - let payload_signature = deps.api.secp256k1_sign(&payload_hash, secret_key.as_ref()).unwrap(); + let payload_signature = secp.sign_ecdsa(&Message::from_slice(&payload_hash).unwrap(), &secret_key).serialize_compact(); // execute input handle let pre_execution_msg = PreExecutionMsg { @@ -899,8 +1016,11 @@ mod tests { // test incorrect input_hash let wrong_post_execution_msg = PostExecutionMsg { - result: base64::encode("{\"answer\": 42}".to_string()), - task: Task { network: "ethereum".to_string(), task_id: "1".to_string() }, + result: STANDARD.encode("{\"answer\": 42}".to_string()), + task: Task { + network: "ethereum".to_string(), + task_id: "1".to_string(), + }, input_hash: Binary(sha_256("wrong data".as_bytes()).to_vec()), }; let handle_msg = ExecuteMsg::Output { @@ -911,8 +1031,11 @@ mod tests { // test output handle let post_execution_msg = PostExecutionMsg { - result: base64::encode("{\"answer\": 42}".to_string()), - task: Task { network: "ethereum".to_string(), task_id: "1".to_string() }, + result: STANDARD.encode("{\"answer\": 42}".to_string()), + task: Task { + network: "ethereum".to_string(), + task_id: "1".to_string(), + }, input_hash: Binary( sha_256(&[data.as_bytes(), "1".to_string().as_bytes(), &[0u8]].concat()).to_vec(), ), @@ -960,7 +1083,8 @@ mod tests { 65 ); assert_eq!( - base64::decode(hex::decode(logs[7].value.clone().strip_prefix("0x").unwrap()).unwrap()) + STANDARD + .decode(hex::decode(logs[7].value.clone().strip_prefix("0x").unwrap()).unwrap()) .unwrap() .len(), 20 diff --git a/config.yml b/config.yml index 0d90406..a747431 100644 --- a/config.yml +++ b/config.yml @@ -211,7 +211,7 @@ "25": #Cronos Mainnet - active: true + active: false type: "evm" chain_id: "25" api_endpoint: "https://cronos-evm-rpc.publicnode.com" @@ -368,7 +368,7 @@ active: true type: "solana" chain_id: "SolDN" - api_endpoint: https://api.devnet.solana.com + api_endpoint: https://rpc.ankr.com/solana_devnet program_id: "DKDX8XbTnCgEk8o1RNnCUokiCmadG1Ch5HLxaz7CnhcD" timeout: 2 @@ -433,7 +433,7 @@ "Ubit Testnet": #UBIT Testnet - active: true + active: false type: "evm" chain_id: "Ubit Testnet" api_endpoint: "https://testnet-rpc.ubitscan.io/" @@ -442,7 +442,7 @@ contract_schema: '[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"increaseTaskId","inputs":[{"name":"_newTaskId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"initialize","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"payoutBalance","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"postExecution","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_sourceNetwork","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.PostExecutionInfo","components":[{"name":"payload_hash","type":"bytes32","internalType":"bytes32"},{"name":"packet_hash","type":"bytes32","internalType":"bytes32"},{"name":"callback_address","type":"bytes20","internalType":"bytes20"},{"name":"callback_selector","type":"bytes4","internalType":"bytes4"},{"name":"callback_gas_limit","type":"bytes4","internalType":"bytes4"},{"name":"packet_signature","type":"bytes","internalType":"bytes"},{"name":"result","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"requestRandomness","inputs":[{"name":"_numWords","type":"uint32","internalType":"uint32"},{"name":"_callbackGasLimit","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"requestId","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"type":"function","name":"send","inputs":[{"name":"_payloadHash","type":"bytes32","internalType":"bytes32"},{"name":"_userAddress","type":"address","internalType":"address"},{"name":"_routingInfo","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"taskId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"tasks","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"payload_hash_reduced","type":"bytes31","internalType":"bytes31"},{"name":"completed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeHandler","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TaskCompleted","inputs":[{"name":"taskId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"callbackSuccessful","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"logNewTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"source_network","type":"string","indexed":false,"internalType":"string"},{"name":"user_address","type":"address","indexed":false,"internalType":"address"},{"name":"routing_info","type":"string","indexed":false,"internalType":"string"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"info","type":"tuple","indexed":false,"internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidBytesLength","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidPacketSignature","inputs":[]},{"type":"error","name":"InvalidPayloadHash","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignatureLength","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"PaidRequestFeeTooLow","inputs":[]},{"type":"error","name":"TaskAlreadyCompleted","inputs":[]},{"type":"error","name":"TooManyVRFRandomWordsRequested","inputs":[]}]' "713715": #Sei Devnet - active: true + active: false type: "evm" chain_id: "713715" api_endpoint: "https://evm-rpc-arctic-1.sei-apis.com" @@ -452,7 +452,7 @@ "10200": #Gnosis Chiado - active: true + active: false type: "evm" chain_id: "10200" api_endpoint: "https://gnosis-chiado-rpc.publicnode.com" @@ -461,7 +461,7 @@ contract_schema: '[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"increaseTaskId","inputs":[{"name":"_newTaskId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"initialize","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"payoutBalance","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"postExecution","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_sourceNetwork","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.PostExecutionInfo","components":[{"name":"payload_hash","type":"bytes32","internalType":"bytes32"},{"name":"packet_hash","type":"bytes32","internalType":"bytes32"},{"name":"callback_address","type":"bytes20","internalType":"bytes20"},{"name":"callback_selector","type":"bytes4","internalType":"bytes4"},{"name":"callback_gas_limit","type":"bytes4","internalType":"bytes4"},{"name":"packet_signature","type":"bytes","internalType":"bytes"},{"name":"result","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"requestRandomness","inputs":[{"name":"_numWords","type":"uint32","internalType":"uint32"},{"name":"_callbackGasLimit","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"requestId","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"type":"function","name":"send","inputs":[{"name":"_payloadHash","type":"bytes32","internalType":"bytes32"},{"name":"_userAddress","type":"address","internalType":"address"},{"name":"_routingInfo","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"taskId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"tasks","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"payload_hash_reduced","type":"bytes31","internalType":"bytes31"},{"name":"completed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeHandler","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TaskCompleted","inputs":[{"name":"taskId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"callbackSuccessful","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"logNewTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"source_network","type":"string","indexed":false,"internalType":"string"},{"name":"user_address","type":"address","indexed":false,"internalType":"address"},{"name":"routing_info","type":"string","indexed":false,"internalType":"string"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"info","type":"tuple","indexed":false,"internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidBytesLength","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidPacketSignature","inputs":[]},{"type":"error","name":"InvalidPayloadHash","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignatureLength","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"PaidRequestFeeTooLow","inputs":[]},{"type":"error","name":"TaskAlreadyCompleted","inputs":[]},{"type":"error","name":"TooManyVRFRandomWordsRequested","inputs":[]}]' "338": #Cronos Testnet - active: true + active: false type: "evm" chain_id: "338" api_endpoint: "https://cronos-testnet.drpc.org" @@ -469,12 +469,20 @@ timeout: 1 contract_schema: '[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"increaseTaskId","inputs":[{"name":"_newTaskId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"initialize","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"payoutBalance","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"postExecution","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_sourceNetwork","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.PostExecutionInfo","components":[{"name":"payload_hash","type":"bytes32","internalType":"bytes32"},{"name":"packet_hash","type":"bytes32","internalType":"bytes32"},{"name":"callback_address","type":"bytes20","internalType":"bytes20"},{"name":"callback_selector","type":"bytes4","internalType":"bytes4"},{"name":"callback_gas_limit","type":"bytes4","internalType":"bytes4"},{"name":"packet_signature","type":"bytes","internalType":"bytes"},{"name":"result","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"requestRandomness","inputs":[{"name":"_numWords","type":"uint32","internalType":"uint32"},{"name":"_callbackGasLimit","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"requestId","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"type":"function","name":"send","inputs":[{"name":"_payloadHash","type":"bytes32","internalType":"bytes32"},{"name":"_userAddress","type":"address","internalType":"address"},{"name":"_routingInfo","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"taskId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"tasks","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"payload_hash_reduced","type":"bytes31","internalType":"bytes31"},{"name":"completed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeHandler","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TaskCompleted","inputs":[{"name":"taskId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"callbackSuccessful","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"logNewTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"source_network","type":"string","indexed":false,"internalType":"string"},{"name":"user_address","type":"address","indexed":false,"internalType":"address"},{"name":"routing_info","type":"string","indexed":false,"internalType":"string"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"info","type":"tuple","indexed":false,"internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidBytesLength","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidPacketSignature","inputs":[]},{"type":"error","name":"InvalidPayloadHash","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignatureLength","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"PaidRequestFeeTooLow","inputs":[]},{"type":"error","name":"TaskAlreadyCompleted","inputs":[]},{"type":"error","name":"TooManyVRFRandomWordsRequested","inputs":[]}]' +"#Zksync Era Sepolia": #Zksync Era Sepolia + active: false + type: "evm" + chain_id: "#Zksync Era Sepolia" + api_endpoint: "https://sepolia.era.zksync.dev" + contract_address: "0xAaA666CE51E4c4dcB50781d4F84461e267392fC9" + timeout: 1 + contract_schema: '[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"increaseTaskId","inputs":[{"name":"_newTaskId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"initialize","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"payoutBalance","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"postExecution","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_sourceNetwork","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.PostExecutionInfo","components":[{"name":"payload_hash","type":"bytes32","internalType":"bytes32"},{"name":"packet_hash","type":"bytes32","internalType":"bytes32"},{"name":"callback_address","type":"bytes20","internalType":"bytes20"},{"name":"callback_selector","type":"bytes4","internalType":"bytes4"},{"name":"callback_gas_limit","type":"bytes4","internalType":"bytes4"},{"name":"packet_signature","type":"bytes","internalType":"bytes"},{"name":"result","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"requestRandomness","inputs":[{"name":"_numWords","type":"uint32","internalType":"uint32"},{"name":"_callbackGasLimit","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"requestId","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"type":"function","name":"send","inputs":[{"name":"_payloadHash","type":"bytes32","internalType":"bytes32"},{"name":"_userAddress","type":"address","internalType":"address"},{"name":"_routingInfo","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"taskId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"tasks","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"payload_hash_reduced","type":"bytes31","internalType":"bytes31"},{"name":"completed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeHandler","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TaskCompleted","inputs":[{"name":"taskId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"callbackSuccessful","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"logNewTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"source_network","type":"string","indexed":false,"internalType":"string"},{"name":"user_address","type":"address","indexed":false,"internalType":"address"},{"name":"routing_info","type":"string","indexed":false,"internalType":"string"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"info","type":"tuple","indexed":false,"internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"task_destination_network","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"callback_gas_limit","type":"uint32","internalType":"uint32"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidBytesLength","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidPacketSignature","inputs":[]},{"type":"error","name":"InvalidPayloadHash","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignatureLength","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"PaidRequestFeeTooLow","inputs":[]},{"type":"error","name":"TaskAlreadyCompleted","inputs":[]},{"type":"error","name":"TooManyVRFRandomWordsRequested","inputs":[]}]' "pulsar-3": active: true type: "secret" chain_id: "pulsar-3" - api_endpoint: "https://lcd.testnet.secretsaturn.net" + api_endpoint: "http://81.171.3.86:1317" contract_address: "secret1drjkzeg2x0yyt927zpggnx289aj7ptcq4w6gw3" code_hash: "dfa2af6f3c1dae11343169466fd936db8cefd5cf4955afd73d778597ec2390a6" feegrant_address: "secret1gutgtpw0caqfsp8ja0r5yecv8jxz2y8vhpnck8"