avail_rust_client/clients/
rpc_api.rs

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 grandpa_block_justification_json(
309		&self,
310		at: u32,
311	) -> Result<Option<GrandpaJustification>, avail_rust_core::Error> {
312		let result = rpc::grandpa::block_justification_json(&self.client.rpc_client, at).await?;
313		let Some(result) = result else {
314			return Ok(None);
315		};
316
317		let justification: GrandpaJustification = serde_json::from_str(result.as_str()).map_err(|e| e.to_string())?;
318		Ok(Some(justification))
319	}
320
321	pub async fn grandpa_block_justification_json_ext(
322		&self,
323		at: u32,
324		retry_on_error: bool,
325	) -> Result<Option<GrandpaJustification>, avail_rust_core::Error> {
326		const MESSAGE: &str = "Failed to execute RPC: grandpa_blockJustificationJson";
327
328		let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
329		let result = loop {
330			match rpc::grandpa::block_justification_json(&self.client.rpc_client, at).await {
331				Ok(x) => break x,
332				Err(err) if !retry_on_error => {
333					return Err(err.into());
334				},
335				Err(err) => {
336					let Some(duration) = sleep_duration.pop() else {
337						return Err(err.into());
338					};
339					sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
340				},
341			};
342		};
343
344		let Some(result) = result else {
345			return Ok(None);
346		};
347
348		let justification: GrandpaJustification = serde_json::from_str(result.as_str()).map_err(|e| e.to_string())?;
349		Ok(Some(justification))
350	}
351
352	pub async fn system_fetch_events_v1(
353		&self,
354		at: H256,
355		options: fetch_events_v1_types::Options,
356	) -> Result<fetch_events_v1_types::Output, avail_rust_core::Error> {
357		Ok(rpc::system::fetch_events_v1(&self.client.rpc_client, at, Some(options)).await?)
358	}
359
360	pub async fn system_fetch_events_v1_ext(
361		&self,
362		at: H256,
363		options: fetch_events_v1_types::Options,
364		retry_on_error: bool,
365	) -> Result<fetch_events_v1_types::Output, avail_rust_core::Error> {
366		const MESSAGE: &str = "Failed to execute RPC: system_FetchEventsV1";
367
368		let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
369		loop {
370			match self.system_fetch_events_v1(at, options.clone()).await {
371				Ok(x) => return Ok(x),
372				Err(err) if !retry_on_error => {
373					return Err(err);
374				},
375				Err(err) => {
376					let Some(duration) = sleep_duration.pop() else {
377						return Err(err);
378					};
379					sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
380				},
381			};
382		}
383	}
384
385	pub async fn system_fetch_extrinsics_v1(
386		&self,
387		block_id: HashNumber,
388		options: fetch_extrinsics_v1_types::Options,
389	) -> Result<fetch_extrinsics_v1_types::Output, avail_rust_core::Error> {
390		Ok(rpc::system::fetch_extrinsics_v1(&self.client.rpc_client, block_id, Some(options)).await?)
391	}
392
393	pub async fn system_fetch_extrinsics_v1_ext(
394		&self,
395		block_id: HashNumber,
396		options: fetch_extrinsics_v1_types::Options,
397		retry_on_error: bool,
398	) -> Result<fetch_extrinsics_v1_types::Output, avail_rust_core::Error> {
399		const MESSAGE: &str = "Failed to execute RPC: system_FetchExtrinsicsV1";
400
401		let mut sleep_duration: Vec<u64> = vec![8, 5, 3, 2, 1];
402		loop {
403			match self.system_fetch_extrinsics_v1(block_id, options.clone()).await {
404				Ok(x) => return Ok(x),
405				Err(err) if !retry_on_error => {
406					return Err(err);
407				},
408				Err(err) => {
409					let Some(duration) = sleep_duration.pop() else {
410						return Err(err);
411					};
412					sleep_on_retry(duration, MESSAGE, &err.to_string()).await;
413				},
414			};
415		}
416	}
417}