pallet_revive_eth_rpc/client/
runtime_api.rs1use crate::{
19 client::Balance,
20 subxt_client::{self, SrcChainConfig},
21 ClientError, LOG_TARGET,
22};
23use pallet_revive::{
24 evm::{GenericTransaction, Trace, H160, U256},
25 EthTransactInfo,
26};
27use subxt::OnlineClient;
28
29#[derive(Clone)]
31pub struct RuntimeApi(subxt::runtime_api::RuntimeApi<SrcChainConfig, OnlineClient<SrcChainConfig>>);
32
33impl RuntimeApi {
34 pub fn new(
36 api: subxt::runtime_api::RuntimeApi<SrcChainConfig, OnlineClient<SrcChainConfig>>,
37 ) -> Self {
38 Self(api)
39 }
40
41 pub async fn balance(&self, address: H160) -> Result<U256, ClientError> {
43 let address = address.0.into();
44 let payload = subxt_client::apis().revive_api().balance(address);
45 let balance = self.0.call(payload).await?;
46 Ok(*balance)
47 }
48
49 pub async fn get_storage(
51 &self,
52 contract_address: H160,
53 key: [u8; 32],
54 ) -> Result<Option<Vec<u8>>, ClientError> {
55 let contract_address = contract_address.0.into();
56 let payload = subxt_client::apis().revive_api().get_storage(contract_address, key);
57 let result = self.0.call(payload).await?.map_err(|_| ClientError::ContractNotFound)?;
58 Ok(result)
59 }
60
61 pub async fn dry_run(
63 &self,
64 tx: GenericTransaction,
65 ) -> Result<EthTransactInfo<Balance>, ClientError> {
66 let payload = subxt_client::apis().revive_api().eth_transact(tx.into());
67 let result = self.0.call(payload).await?;
68 match result {
69 Err(err) => {
70 log::debug!(target: LOG_TARGET, "Dry run failed {err:?}");
71 Err(ClientError::TransactError(err.0))
72 },
73 Ok(result) => Ok(result.0),
74 }
75 }
76
77 pub async fn nonce(&self, address: H160) -> Result<U256, ClientError> {
79 let address = address.0.into();
80 let payload = subxt_client::apis().revive_api().nonce(address);
81 let nonce = self.0.call(payload).await?;
82 Ok(nonce.into())
83 }
84
85 pub async fn gas_price(&self) -> Result<U256, ClientError> {
87 let payload = subxt_client::apis().revive_api().gas_price();
88 let gas_price = self.0.call(payload).await?;
89 Ok(*gas_price)
90 }
91
92 pub async fn block_gas_limit(&self) -> Result<U256, ClientError> {
94 let payload = subxt_client::apis().revive_api().block_gas_limit();
95 let gas_limit = self.0.call(payload).await?;
96 Ok(*gas_limit)
97 }
98
99 pub async fn block_author(&self) -> Result<Option<H160>, ClientError> {
101 let payload = subxt_client::apis().revive_api().block_author();
102 let author = self.0.call(payload).await?;
103 Ok(author)
104 }
105
106 pub async fn trace_tx(
108 &self,
109 block: sp_runtime::generic::Block<
110 sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>,
111 sp_runtime::OpaqueExtrinsic,
112 >,
113 transaction_index: u32,
114 tracer_type: crate::TracerType,
115 ) -> Result<Trace, ClientError> {
116 let payload = subxt_client::apis()
117 .revive_api()
118 .trace_tx(block.into(), transaction_index, tracer_type.into())
119 .unvalidated();
120
121 let trace = self.0.call(payload).await?.ok_or(ClientError::EthExtrinsicNotFound)?.0;
122 Ok(trace)
123 }
124
125 pub async fn trace_block(
127 &self,
128 block: sp_runtime::generic::Block<
129 sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>,
130 sp_runtime::OpaqueExtrinsic,
131 >,
132 tracer_type: crate::TracerType,
133 ) -> Result<Vec<(u32, Trace)>, ClientError> {
134 let payload = subxt_client::apis()
135 .revive_api()
136 .trace_block(block.into(), tracer_type.into())
137 .unvalidated();
138
139 let traces = self.0.call(payload).await?.into_iter().map(|(idx, t)| (idx, t.0)).collect();
140 Ok(traces)
141 }
142
143 pub async fn trace_call(
145 &self,
146 transaction: GenericTransaction,
147 tracer_type: crate::TracerType,
148 ) -> Result<Trace, ClientError> {
149 let payload = subxt_client::apis()
150 .revive_api()
151 .trace_call(transaction.into(), tracer_type.into())
152 .unvalidated();
153
154 let trace = self.0.call(payload).await?.map_err(|err| ClientError::TransactError(err.0))?;
155 Ok(trace.0)
156 }
157
158 pub async fn code(&self, address: H160) -> Result<Vec<u8>, ClientError> {
160 let payload = subxt_client::apis().revive_api().code(address);
161 let code = self.0.call(payload).await?;
162 Ok(code)
163 }
164}