RPC Client Setup
To initialize your client, please pass in the URL in Access Information.
Client Template
pub(crate) struct SampleClient { rpc: WsClient, node_client: NodeClient, } impl SampleClient { pub(crate) async fn new(rpc_addr: String, rest_addr: String) -> Self { let rpc_socket: SocketAddr = rpc_addr.parse().unwrap(); let rpc = WsClientBuilder::default() .build(&format!("ws://127.0.0.1:{}", rpc_socket.port())) .await .unwrap(); let rest_socket: SocketAddr = rest_addr.parse().unwrap(); let node_client = NodeClient::new_unchecked(&format!("<http://127.0.0.1>:{}", rest_socket.port())); Self { rpc, node_client } } pub(crate) async fn svm_query_state(&self) -> anyhow::Result<String> { self.rpc .request("queryModuleState", rpc_params![]) .await .map_err(|e| anyhow!("Failed to query SVM state: {e}")) } #[allow(dead_code)] pub(crate) async fn svm_get_slot(&self) -> anyhow::Result<u64> { self.rpc .request("getSlot", rpc_params![]) .await .map_err(|e| anyhow!("Failed to get slot: {e}")) } pub(crate) async fn svm_get_account_info(&self, pubkey: Pubkey) -> anyhow::Result<Account> { let res: Response<Option<UiAccount>> = self .rpc .request("getAccountInfo", rpc_params![pubkey]) .await .map_err(|e| anyhow!("Failed to get account info: {e}"))?; res.value .ok_or_else(|| anyhow!("Failed to get account info"))? .decode() .ok_or_else(|| anyhow!("Failed to decode account info")) } pub(crate) async fn svm_get_account_balance(&self, pubkey: Pubkey) -> anyhow::Result<u64> { self.rpc .request("getBalance", rpc_params![pubkey]) .await .map_err(|e| anyhow!("Failed to get account balance: {e}")) } pub(crate) async fn svm_get_latest_blockhash(&self) -> anyhow::Result<Hash> { self.rpc .request("getLatestBlockhash", rpc_params![]) .await .map_err(|e| anyhow!("Failed to get blockhash: {e}")) } pub(crate) async fn svm_send_transaction(&self, tx: &Transaction) -> anyhow::Result<Hash> { let raw_tx = serialize_and_encode(tx, UiTransactionEncoding::Base58)?; self.rpc .request("sendTransaction", rpc_params![raw_tx]) .await .map_err(|e| anyhow!("Failed to send transaction: {e}")) } pub(crate) async fn get_minimum_balance_for_rent_exemption( &self, data_len: usize, ) -> anyhow::Result<u64> { self.rpc .request("getMinimumBalanceForRentExemption", rpc_params![data_len]) .await .map_err(|e| anyhow!("Failed to get rent balance: {e}")) } pub(crate) async fn get_fee_for_message(&self, message: Message) -> anyhow::Result<u64> { self.rpc .request("getFeeForMessage", rpc_params![message]) .await .map_err(|e| anyhow!("Failed to get fee for message: {e}")) } pub(crate) async fn simulate_call_message( &self, transactions: &[Transaction], ) -> anyhow::Result<u64> { let raw_txs = transactions .iter() .map(|tx| borsh::to_vec(tx).expect("Failed to serialize transaction")) .collect(); let msg = svm::call::CallMessage { transactions: raw_txs, }; let user = TestUser::<SvmRollupSpec>::generate_with_default_balance(); let partial_transaction: PartialTransaction = sov_rollup_apis::PartialTransaction::<SvmRollupSpec> { sender_pub_key: user.private_key().pub_key(), details: sov_modules_api::transaction::TxDetails { max_priority_fee_bips: PriorityFeeBips::ZERO, max_fee: TEST_DEFAULT_MAX_FEE, gas_limit: None, chain_id: config_chain_id(), }, encoded_call_message: <RT as EncodeCall<SVM<SvmRollupSpec>>>::encode_call(msg), gas_price: None, sequencer: None, generation: 0, } .try_into() .unwrap(); let simulation_result = self .node_client .client .simulate(&SimulateBody { body: partial_transaction, }) .await .map_err(|e| anyhow!("Failed to simulate call message: {e}"))? .data .clone() .unwrap(); let simulation_result_parsed: SimulateExecutionContainer<SvmRollupSpec> = simulation_result.try_into()?; let tx_consumption = simulation_result_parsed .apply_tx_result .transaction_consumption; let base_fee = tx_consumption.base_fee_value(); let priority_fee = tx_consumption.priority_fee(); Ok(base_fee.0 + priority_fee.0) } pub(crate) async fn get_total_fee_for_transaction( &self, transaction: &Transaction, ) -> anyhow::Result<u64> { let call_message_gas_fee_estimate = self.simulate_call_message(&[transaction.clone()]).await?; let svm_gas_fee_estimate = self .get_fee_for_message(transaction.message.clone()) .await?; Ok(call_message_gas_fee_estimate + svm_gas_fee_estimate) } }
Initializing the Client
let client = TestClient::new(config.rpc.rpc_addr, config.rpc.rest_addr).await;
Last updated
Was this helpful?