use std::hash::Hasher; use jsonrpsee::core::RpcResult; use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_api::macros::rpc_gen; use sov_modules_api::{Context, ModuleInfo, WorkingSet}; use sov_state::ZkStorage; #[derive(ModuleInfo)] pub struct TestStruct where D: std::hash::Hash + std::clone::Clone + borsh::BorshSerialize + borsh::BorshDeserialize + serde::Serialize + serde::de::DeserializeOwned + 'static, { #[address] pub(crate) address: C::Address, #[state] pub(crate) data: ::sov_modules_api::StateValue, } #[rpc_gen(client, server, namespace = "test")] impl TestStruct where D: std::hash::Hash + std::clone::Clone + borsh::BorshSerialize + borsh::BorshDeserialize + serde::Serialize + serde::de::DeserializeOwned + 'static, { #[rpc_method(name = "firstMethod")] pub fn first_method(&self, _working_set: &mut WorkingSet) -> RpcResult { Ok(11) } #[rpc_method(name = "secondMethod")] pub fn second_method( &self, result: D, _working_set: &mut WorkingSet, ) -> RpcResult<(D, u64)> { let mut hasher = std::collections::hash_map::DefaultHasher::new(); let value = result.clone(); value.hash(&mut hasher); let hashed_value = hasher.finish(); Ok((value, hashed_value)) } } pub struct TestRuntime { test_struct: TestStruct, } // This is generated by a macro annotating the state transition runner, // but we do not have that in scope here so generating the struct manually. struct RpcStorage { pub storage: C::Storage, } impl TestStructRpcImpl for RpcStorage { fn get_working_set( &self, ) -> ::sov_modules_api::WorkingSet { ::sov_modules_api::WorkingSet::new(self.storage.clone()) } } fn main() { let storage = ZkStorage::new(); let r: RpcStorage = RpcStorage { storage: storage.clone(), }; { let result = as TestStructRpcServer>::first_method( &r, ) .unwrap(); assert_eq!(result, 11); } { let result = as TestStructRpcServer>::second_method( &r, 22, ) .unwrap(); assert_eq!(result, (22, 15733059416522709050)); } println!("All tests passed!"); }