avail_rust_core/rpc/
system.rs

1use primitive_types::H256;
2use serde::{Deserialize, Serialize};
3use subxt_rpcs::{RpcClient, methods::legacy::SystemHealth, rpc_params};
4
5use crate::{HashNumber, decoded_events::RuntimePhase};
6
7/// Network Peer information
8#[derive(Clone, Debug, PartialEq, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct PeerInfo {
11	/// Peer ID
12	pub peer_id: String,
13	/// Roles
14	pub roles: String,
15	/// Peer best block hash
16	pub best_hash: H256,
17	/// Peer best block number
18	pub best_number: u32,
19}
20
21/// Arbitrary properties defined in chain spec as a JSON object
22pub type SystemProperties = serde_json::map::Map<String, serde_json::Value>;
23
24/// The role the node is running as
25#[derive(Clone, Debug, PartialEq, Deserialize)]
26pub enum NodeRole {
27	/// The node is a full node
28	Full,
29	/// The node is an authority
30	Authority,
31}
32
33/// The state of the syncing of the node.
34#[derive(Clone, Debug, PartialEq, Deserialize)]
35#[serde(rename_all = "camelCase")]
36pub struct SyncState {
37	/// Height of the block at which syncing started.
38	pub starting_block: u32,
39	/// Height of the current best block of the node.
40	pub current_block: u32,
41	/// Height of the highest block in the network.
42	pub highest_block: u32,
43}
44
45pub async fn account_next_index(client: &RpcClient, address: &str) -> Result<u32, subxt_rpcs::Error> {
46	let params = rpc_params![address];
47	let value = client.request("system_accountNextIndex", params).await?;
48	Ok(value)
49}
50
51pub async fn chain(client: &RpcClient) -> Result<String, subxt_rpcs::Error> {
52	let params = rpc_params![];
53	let value = client.request("system_chain", params).await?;
54	Ok(value)
55}
56
57pub async fn chain_type(client: &RpcClient) -> Result<String, subxt_rpcs::Error> {
58	let params = rpc_params![];
59	let value = client.request("system_chainType", params).await?;
60	Ok(value)
61}
62
63pub async fn health(client: &RpcClient) -> Result<SystemHealth, subxt_rpcs::Error> {
64	let params = rpc_params![];
65	let value = client.request("system_health", params).await?;
66	Ok(value)
67}
68
69pub async fn local_listen_addresses(client: &RpcClient) -> Result<Vec<String>, subxt_rpcs::Error> {
70	let params = rpc_params![];
71	let value = client.request("system_localListenAddresses", params).await?;
72	Ok(value)
73}
74
75pub async fn local_peer_id(client: &RpcClient) -> Result<String, subxt_rpcs::Error> {
76	let params = rpc_params![];
77	let value = client.request("system_localPeerId", params).await?;
78	Ok(value)
79}
80
81pub async fn name(client: &RpcClient) -> Result<String, subxt_rpcs::Error> {
82	let params = rpc_params![];
83	let value = client.request("system_name", params).await?;
84	Ok(value)
85}
86
87pub async fn node_roles(client: &RpcClient) -> Result<Vec<NodeRole>, subxt_rpcs::Error> {
88	let params = rpc_params![];
89	let value = client.request("system_nodeRoles", params).await?;
90	Ok(value)
91}
92
93pub async fn peers(client: &RpcClient) -> Result<Vec<PeerInfo>, subxt_rpcs::Error> {
94	let params = rpc_params![];
95	let value = client.request("system_peers", params).await?;
96	Ok(value)
97}
98
99pub async fn properties(client: &RpcClient) -> Result<SystemProperties, subxt_rpcs::Error> {
100	let params = rpc_params![];
101	let value = client.request("system_properties", params).await?;
102	Ok(value)
103}
104
105pub async fn sync_state(client: &RpcClient) -> Result<SyncState, subxt_rpcs::Error> {
106	let params = rpc_params![];
107	let value = client.request("system_syncState", params).await?;
108	Ok(value)
109}
110
111pub async fn version(client: &RpcClient) -> Result<String, subxt_rpcs::Error> {
112	let params = rpc_params![];
113	let value = client.request("system_version", params).await?;
114	Ok(value)
115}
116
117pub async fn fetch_events_v1(
118	client: &RpcClient,
119	at: H256,
120	options: Option<fetch_events_v1_types::Options>,
121) -> Result<fetch_events_v1_types::Output, subxt_rpcs::Error> {
122	let params = rpc_params![at, options];
123	let value = client.request("system_fetchEventsV1", params).await?;
124	Ok(value)
125}
126
127pub async fn fetch_extrinsics_v1(
128	client: &RpcClient,
129	block_id: HashNumber,
130	options: Option<fetch_extrinsics_v1_types::Options>,
131) -> Result<fetch_extrinsics_v1_types::Output, subxt_rpcs::Error> {
132	let params = rpc_params![block_id, options];
133	let value = client.request("system_fetchExtrinsicsV1", params).await?;
134	Ok(value)
135}
136
137pub mod fetch_events_v1_types {
138	pub use super::*;
139
140	pub type FetchEventsV1Options = Options;
141	pub type Output = Vec<GroupedRuntimeEvents>;
142
143	#[derive(Default, Clone, Debug, Serialize, Deserialize)]
144	pub struct Options {
145		pub filter: Option<Filter>,
146		pub enable_encoding: Option<bool>,
147		pub enable_decoding: Option<bool>,
148	}
149
150	impl Options {
151		pub fn new(filter: Option<Filter>, enable_encoding: Option<bool>, enable_decoding: Option<bool>) -> Self {
152			Self {
153				filter,
154				enable_encoding,
155				enable_decoding,
156			}
157		}
158	}
159
160	#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
161	#[repr(u8)]
162	pub enum Filter {
163		All = 0,
164		OnlyExtrinsics = 1,
165		OnlyNonExtrinsics = 2,
166		Only(Vec<u32>) = 3,
167	}
168
169	impl Default for Filter {
170		fn default() -> Self {
171			Self::All
172		}
173	}
174
175	#[derive(Clone, Debug, PartialEq, Deserialize)]
176	pub struct GroupedRuntimeEvents {
177		pub phase: RuntimePhase,
178		pub events: Vec<RuntimeEvent>,
179	}
180
181	#[derive(Clone, Debug, PartialEq, Deserialize)]
182	pub struct RuntimeEvent {
183		pub index: u32,
184		// (Pallet Id, Event Id)
185		pub emitted_index: (u8, u8),
186		pub encoded: Option<String>,
187		pub decoded: Option<String>,
188	}
189}
190
191pub mod fetch_extrinsics_v1_types {
192	use super::*;
193	pub type Output = Vec<ExtrinsicInformation>;
194	pub type FetchExtrinsicsV1Options = Options;
195
196	#[derive(Clone, Serialize, Deserialize)]
197	pub struct Options {
198		pub filter: Option<Filter>,
199		pub encode_selector: Option<EncodeSelector>,
200	}
201
202	impl Options {
203		pub fn new(filter: Option<Filter>, selector: Option<EncodeSelector>) -> Self {
204			Self {
205				filter,
206				encode_selector: selector,
207			}
208		}
209	}
210
211	#[derive(Default, Clone, Serialize, Deserialize)]
212	pub struct Filter {
213		pub transaction: Option<TransactionFilter>,
214		pub signature: Option<SignatureFilter>,
215	}
216
217	impl Filter {
218		pub fn new(tx: Option<TransactionFilter>, sig: Option<SignatureFilter>) -> Self {
219			Self {
220				transaction: tx,
221				signature: sig,
222			}
223		}
224	}
225
226	#[derive(Clone, Copy, Serialize, Deserialize)]
227	#[repr(u8)]
228	pub enum EncodeSelector {
229		None = 0,
230		Call = 1,
231		Extrinsic = 2,
232	}
233
234	#[derive(Debug, Clone, Serialize, Deserialize)]
235	pub struct ExtrinsicInformation {
236		// Hex string encoded
237		pub encoded: Option<String>,
238		pub tx_hash: H256,
239		pub tx_index: u32,
240		pub pallet_id: u8,
241		pub call_id: u8,
242		pub signature: Option<TransactionSignature>,
243	}
244
245	#[derive(Clone, Serialize, Deserialize)]
246	pub enum TransactionFilter {
247		All,
248		TxHash(Vec<H256>),
249		TxIndex(Vec<u32>),
250		Pallet(Vec<u8>),
251		PalletCall(Vec<(u8, u8)>),
252	}
253
254	impl TransactionFilter {
255		pub fn new() -> Self {
256			Self::default()
257		}
258	}
259
260	impl Default for TransactionFilter {
261		fn default() -> Self {
262			Self::All
263		}
264	}
265
266	#[derive(Default, Clone, Serialize, Deserialize)]
267	pub struct SignatureFilter {
268		pub ss58_address: Option<String>,
269		pub app_id: Option<u32>,
270		pub nonce: Option<u32>,
271	}
272
273	impl SignatureFilter {
274		pub fn new(ss58_address: Option<String>, app_id: Option<u32>, nonce: Option<u32>) -> Self {
275			Self {
276				ss58_address,
277				app_id,
278				nonce,
279			}
280		}
281	}
282
283	#[derive(Debug, Clone, Serialize, Deserialize)]
284	pub struct TransactionSignature {
285		pub ss58_address: Option<String>,
286		pub nonce: u32,
287		pub app_id: u32,
288		pub mortality: Option<(u64, u64)>,
289	}
290}