1use crate::{Client, clients::main_client::sleep_on_retry};
2use avail_rust_core::{
3 AvailHeader, H256, HashNumber,
4 ext::{
5 codec::Decode,
6 subxt_rpcs::{
7 client::RpcParams,
8 methods::legacy::{RuntimeVersion, SystemHealth},
9 },
10 },
11 grandpa::GrandpaJustification,
12 rpc::{
13 self, BlockWithJustifications,
14 author::SessionKeys,
15 kate::{BlockLength, Cell, GDataProof, GRow, ProofResponse},
16 rpc_methods::RpcMethods,
17 system::{NodeRole, PeerInfo, SyncState, SystemProperties, fetch_events_v1_types, fetch_extrinsics_v1_types},
18 },
19};
20
21#[derive(Clone)]
22pub struct RpcAPI {
23 client: Client,
24}
25
26impl RpcAPI {
27 pub fn new(client: Client) -> Self {
28 Self { client }
29 }
30
31 pub async fn call<T: serde::de::DeserializeOwned>(
32 &self,
33 method: &str,
34 params: RpcParams,
35 ) -> Result<T, avail_rust_core::Error> {
36 Ok(rpc::call_raw(&self.client.rpc_client, method, params).await?)
37 }
38
39 pub async fn system_account_next_index(&self, address: &str) -> Result<u32, avail_rust_core::Error> {
40 Ok(rpc::system::account_next_index(&self.client.rpc_client, address).await?)
41 }
42
43 pub async fn system_chain(&self) -> Result<String, avail_rust_core::Error> {
44 Ok(rpc::system::chain(&self.client.rpc_client).await?)
45 }
46
47 pub async fn system_chain_type(&self) -> Result<String, avail_rust_core::Error> {
48 Ok(rpc::system::chain_type(&self.client.rpc_client).await?)
49 }
50
51 pub async fn system_health(&self) -> Result<SystemHealth, avail_rust_core::Error> {
52 Ok(rpc::system::health(&self.client.rpc_client).await?)
53 }
54
55 pub async fn system_local_listen_addresses(&self) -> Result<Vec<String>, avail_rust_core::Error> {
56 Ok(rpc::system::local_listen_addresses(&self.client.rpc_client).await?)
57 }
58
59 pub async fn system_local_peer_id(&self) -> Result<String, avail_rust_core::Error> {
60 Ok(rpc::system::local_peer_id(&self.client.rpc_client).await?)
61 }
62
63 pub async fn system_name(&self) -> Result<String, avail_rust_core::Error> {
64 Ok(rpc::system::name(&self.client.rpc_client).await?)
65 }
66
67 pub async fn system_node_roles(&self) -> Result<Vec<NodeRole>, avail_rust_core::Error> {
68 Ok(rpc::system::node_roles(&self.client.rpc_client).await?)
69 }
70
71 pub async fn system_peers(&self) -> Result<Vec<PeerInfo>, avail_rust_core::Error> {
72 Ok(rpc::system::peers(&self.client.rpc_client).await?)
73 }
74
75 pub async fn system_properties(&self) -> Result<SystemProperties, avail_rust_core::Error> {
76 Ok(rpc::system::properties(&self.client.rpc_client).await?)
77 }
78
79 pub async fn system_sync_state(&self) -> Result<SyncState, avail_rust_core::Error> {
80 Ok(rpc::system::sync_state(&self.client.rpc_client).await?)
81 }
82
83 pub async fn system_sync_state_ext(&self, retry_on_error: bool) -> Result<SyncState, avail_rust_core::Error> {
84 const MESSAGE: &str = "Failed to execute RPC: system_sync_state";
85
86 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
87 loop {
88 match rpc::system::sync_state(&self.client.rpc_client).await {
89 Ok(x) => return Ok(x),
90 Err(err) if !retry_on_error => {
91 return Err(err.into());
92 },
93 Err(err) => {
94 let Some(duration) = sleep_duration.pop() else {
95 return Err(err.into());
96 };
97 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
98 },
99 };
100 }
101 }
102
103 pub async fn system_version(&self) -> Result<String, avail_rust_core::Error> {
104 Ok(rpc::system::version(&self.client.rpc_client).await?)
105 }
106
107 pub async fn chain_get_block(
108 &self,
109 at: Option<H256>,
110 ) -> Result<Option<BlockWithJustifications>, avail_rust_core::Error> {
111 Ok(rpc::chain::get_block(&self.client.rpc_client, at).await?)
112 }
113
114 pub async fn chain_get_block_hash(
115 &self,
116 block_height: Option<u32>,
117 ) -> Result<Option<H256>, avail_rust_core::Error> {
118 Ok(rpc::chain::get_block_hash(&self.client.rpc_client, block_height).await?)
119 }
120
121 pub async fn chain_get_block_hash_ext(
122 &self,
123 block_height: Option<u32>,
124 retry_on_error: bool,
125 retry_on_none: bool,
126 ) -> Result<Option<H256>, avail_rust_core::Error> {
127 const MESSAGE: &str = "Failed to fetch block hash";
128
129 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
130 loop {
131 match rpc::chain::get_block_hash(&self.client.rpc_client, block_height).await {
132 Ok(Some(x)) => return Ok(Some(x)),
133 Ok(None) if !retry_on_none => {
134 return Ok(None);
135 },
136 Ok(None) => {
137 let Some(duration) = sleep_duration.pop() else {
138 return Ok(None);
139 };
140 sleep_on_retry(duration, MESSAGE, "Option<None>").await;
141 },
142 Err(err) if !retry_on_error => {
143 return Err(err.into());
144 },
145 Err(err) => {
146 let Some(duration) = sleep_duration.pop() else {
147 return Err(err.into());
148 };
149 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
150 },
151 };
152 }
153 }
154
155 pub async fn chain_get_finalized_head(&self) -> Result<H256, avail_rust_core::Error> {
156 Ok(rpc::chain::get_finalized_head(&self.client.rpc_client).await?)
157 }
158
159 pub async fn chain_get_finalized_head_ext(&self, retry_on_error: bool) -> Result<H256, avail_rust_core::Error> {
160 const MESSAGE: &str = "Failed to execute RPC: chain_getFinalized_Head";
161
162 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
163 loop {
164 match rpc::chain::get_finalized_head(&self.client.rpc_client).await {
165 Ok(x) => return Ok(x),
166 Err(err) if !retry_on_error => {
167 return Err(err.into());
168 },
169 Err(err) => {
170 let Some(duration) = sleep_duration.pop() else {
171 return Err(err.into());
172 };
173 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
174 },
175 };
176 }
177 }
178
179 pub async fn chain_get_header(&self, at: Option<H256>) -> Result<Option<AvailHeader>, avail_rust_core::Error> {
180 Ok(rpc::chain::get_header(&self.client.rpc_client, at).await?)
181 }
182
183 pub async fn author_rotate_keys(&self) -> Result<SessionKeys, avail_rust_core::Error> {
184 rpc::author::rotate_keys(&self.client.rpc_client).await
185 }
186
187 pub async fn author_submit_extrinsic(&self, extrinsic: &[u8]) -> Result<H256, avail_rust_core::Error> {
188 Ok(rpc::author::submit_extrinsic(&self.client.rpc_client, extrinsic).await?)
189 }
190
191 pub async fn state_get_runtime_version(&self, at: Option<H256>) -> Result<RuntimeVersion, avail_rust_core::Error> {
192 Ok(rpc::state::get_runtime_version(&self.client.rpc_client, at).await?)
193 }
194
195 pub async fn state_call(
196 &self,
197 method: &str,
198 data: &[u8],
199 at: Option<H256>,
200 ) -> Result<String, avail_rust_core::Error> {
201 Ok(rpc::state::call(&self.client.rpc_client, method, data, at).await?)
202 }
203
204 pub async fn state_get_metadata(&self, at: Option<H256>) -> Result<Vec<u8>, avail_rust_core::Error> {
205 rpc::state::get_metadata(&self.client.rpc_client, at).await
206 }
207
208 pub async fn state_get_storage(
209 &self,
210 key: &str,
211 at: Option<H256>,
212 ) -> Result<Option<Vec<u8>>, avail_rust_core::Error> {
213 rpc::state::get_storage(&self.client.rpc_client, key, at).await
214 }
215
216 pub async fn state_get_keys_paged(
217 &self,
218 prefix: Option<String>,
219 count: u32,
220 start_key: Option<String>,
221 at: Option<H256>,
222 ) -> Result<Vec<String>, avail_rust_core::Error> {
223 rpc::state::get_keys_paged(&self.client.rpc_client, prefix, count, start_key, at).await
224 }
225
226 pub async fn rpc_methods(&self) -> Result<RpcMethods, avail_rust_core::Error> {
227 Ok(rpc::rpc_methods::call(&self.client.rpc_client).await?)
228 }
229
230 pub async fn chainspec_v1_genesishash(&self) -> Result<H256, avail_rust_core::Error> {
231 rpc::chainspec::v1_genesishash(&self.client.rpc_client).await
232 }
233
234 pub async fn kate_block_length(&self, at: Option<H256>) -> Result<BlockLength, avail_rust_core::Error> {
235 Ok(rpc::kate::block_length(&self.client.rpc_client, at).await?)
236 }
237
238 pub async fn kate_query_data_proof(
239 &self,
240 transaction_index: u32,
241 at: Option<H256>,
242 ) -> Result<ProofResponse, avail_rust_core::Error> {
243 Ok(rpc::kate::query_data_proof(&self.client.rpc_client, transaction_index, at).await?)
244 }
245
246 pub async fn kate_query_proof(
247 &self,
248 cells: Vec<Cell>,
249 at: Option<H256>,
250 ) -> Result<Vec<GDataProof>, avail_rust_core::Error> {
251 Ok(rpc::kate::query_proof(&self.client.rpc_client, cells, at).await?)
252 }
253
254 pub async fn kate_query_rows(&self, rows: Vec<u32>, at: Option<H256>) -> Result<Vec<GRow>, avail_rust_core::Error> {
255 Ok(rpc::kate::query_rows(&self.client.rpc_client, rows, at).await?)
256 }
257
258 pub async fn grandpa_block_justification(
259 &self,
260 at: u32,
261 ) -> Result<Option<GrandpaJustification>, avail_rust_core::Error> {
262 let result = rpc::grandpa::block_justification(&self.client.rpc_client, at).await?;
263 let Some(result) = result else {
264 return Ok(None);
265 };
266
267 let justification = const_hex::decode(result.trim_start_matches("0x"))
268 .map_err(|x| avail_rust_core::Error::from(x.to_string()))?;
269
270 let justification = GrandpaJustification::decode(&mut justification.as_slice()).map_err(|e| e.to_string())?;
271 Ok(Some(justification))
272 }
273
274 pub async fn grandpa_block_justification_ext(
275 &self,
276 at: u32,
277 retry_on_error: bool,
278 ) -> Result<Option<GrandpaJustification>, avail_rust_core::Error> {
279 const MESSAGE: &str = "Failed to execute RPC: grandpa_blockJustification";
280
281 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
282 let result = loop {
283 match rpc::grandpa::block_justification(&self.client.rpc_client, at).await {
284 Ok(x) => break x,
285 Err(err) if !retry_on_error => {
286 return Err(err.into());
287 },
288 Err(err) => {
289 let Some(duration) = sleep_duration.pop() else {
290 return Err(err.into());
291 };
292 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
293 },
294 };
295 };
296
297 let Some(result) = result else {
298 return Ok(None);
299 };
300
301 let justification = const_hex::decode(result.trim_start_matches("0x"))
302 .map_err(|x| avail_rust_core::Error::from(x.to_string()))?;
303
304 let justification = GrandpaJustification::decode(&mut justification.as_slice()).map_err(|e| e.to_string())?;
305 Ok(Some(justification))
306 }
307
308 pub async fn system_fetch_events_v1(
309 &self,
310 at: H256,
311 options: fetch_events_v1_types::Options,
312 ) -> Result<fetch_events_v1_types::Output, avail_rust_core::Error> {
313 Ok(rpc::system::fetch_events_v1(&self.client.rpc_client, at, Some(options)).await?)
314 }
315
316 pub async fn system_fetch_events_v1_ext(
317 &self,
318 at: H256,
319 options: fetch_events_v1_types::Options,
320 retry_on_error: bool,
321 ) -> Result<fetch_events_v1_types::Output, avail_rust_core::Error> {
322 const MESSAGE: &str = "Failed to execute RPC: system_FetchEventsV1";
323
324 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
325 loop {
326 match self.system_fetch_events_v1(at, options.clone()).await {
327 Ok(x) => return Ok(x),
328 Err(err) if !retry_on_error => {
329 return Err(err);
330 },
331 Err(err) => {
332 let Some(duration) = sleep_duration.pop() else {
333 return Err(err);
334 };
335 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
336 },
337 };
338 }
339 }
340
341 pub async fn system_fetch_extrinsics_v1(
342 &self,
343 block_id: HashNumber,
344 options: fetch_extrinsics_v1_types::Options,
345 ) -> Result<fetch_extrinsics_v1_types::Output, avail_rust_core::Error> {
346 Ok(rpc::system::fetch_extrinsics_v1(&self.client.rpc_client, block_id, Some(options)).await?)
347 }
348
349 pub async fn system_fetch_extrinsics_v1_ext(
350 &self,
351 block_id: HashNumber,
352 options: fetch_extrinsics_v1_types::Options,
353 retry_on_error: bool,
354 ) -> Result<fetch_extrinsics_v1_types::Output, avail_rust_core::Error> {
355 const MESSAGE: &str = "Failed to execute RPC: system_FetchExtrinsicsV1";
356
357 let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
358 loop {
359 match self.system_fetch_extrinsics_v1(block_id, options.clone()).await {
360 Ok(x) => return Ok(x),
361 Err(err) if !retry_on_error => {
362 return Err(err);
363 },
364 Err(err) => {
365 let Some(duration) = sleep_duration.pop() else {
366 return Err(err);
367 };
368 sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
369 },
370 };
371 }
372 }
373}