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#[derive(Clone, Debug, PartialEq, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct PeerInfo {
11 pub peer_id: String,
13 pub roles: String,
15 pub best_hash: H256,
17 pub best_number: u32,
19}
20
21pub type SystemProperties = serde_json::map::Map<String, serde_json::Value>;
23
24#[derive(Clone, Debug, PartialEq, Deserialize)]
26pub enum NodeRole {
27 Full,
29 Authority,
31}
32
33#[derive(Clone, Debug, PartialEq, Deserialize)]
35#[serde(rename_all = "camelCase")]
36pub struct SyncState {
37 pub starting_block: u32,
39 pub current_block: u32,
41 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 { filter, enable_encoding, enable_decoding }
153 }
154 }
155
156 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
157 #[repr(u8)]
158 pub enum Filter {
159 All = 0,
160 OnlyExtrinsics = 1,
161 OnlyNonExtrinsics = 2,
162 Only(Vec<u32>) = 3,
163 }
164
165 impl Default for Filter {
166 fn default() -> Self {
167 Self::All
168 }
169 }
170
171 #[derive(Clone, Debug, PartialEq, Deserialize)]
172 pub struct GroupedRuntimeEvents {
173 pub phase: RuntimePhase,
174 pub events: Vec<RuntimeEvent>,
175 }
176
177 #[derive(Clone, Debug, PartialEq, Deserialize)]
178 pub struct RuntimeEvent {
179 pub index: u32,
180 pub emitted_index: (u8, u8),
182 pub encoded: Option<String>,
183 pub decoded: Option<String>,
184 }
185}
186
187pub mod fetch_extrinsics_v1_types {
188 use super::*;
189 pub type Output = Vec<ExtrinsicInformation>;
190 pub type FetchExtrinsicsV1Options = Options;
191
192 #[derive(Clone, Default, Serialize, Deserialize)]
193 pub struct Options {
194 pub filter: Option<Filter>,
195 pub encode_selector: Option<EncodeSelector>,
196 }
197
198 impl Options {
199 pub fn new(filter: Option<Filter>, selector: Option<EncodeSelector>) -> Self {
200 Self { filter, encode_selector: selector }
201 }
202 }
203
204 #[derive(Default, Clone, Serialize, Deserialize)]
205 pub struct Filter {
206 pub transaction: Option<TransactionFilter>,
207 pub signature: Option<SignatureFilter>,
208 }
209
210 impl Filter {
211 pub fn new(tx: Option<TransactionFilter>, sig: Option<SignatureFilter>) -> Self {
212 Self { transaction: tx, signature: sig }
213 }
214 }
215
216 #[derive(Clone, Default, Copy, Serialize, Deserialize)]
217 #[repr(u8)]
218 pub enum EncodeSelector {
219 None = 0,
220 #[default]
221 Call = 1,
222 Extrinsic = 2,
223 }
224
225 #[derive(Debug, Clone, Serialize, Deserialize)]
226 pub struct ExtrinsicInformation {
227 pub encoded: Option<String>,
229 pub tx_hash: H256,
230 pub tx_index: u32,
231 pub pallet_id: u8,
232 pub call_id: u8,
233 pub signature: Option<TransactionSignature>,
234 }
235
236 #[derive(Clone, Serialize, Deserialize)]
237 pub enum TransactionFilter {
238 All,
239 TxHash(Vec<H256>),
240 TxIndex(Vec<u32>),
241 Pallet(Vec<u8>),
242 PalletCall(Vec<(u8, u8)>),
243 }
244
245 impl TransactionFilter {
246 pub fn new() -> Self {
247 Self::default()
248 }
249 }
250
251 impl Default for TransactionFilter {
252 fn default() -> Self {
253 Self::All
254 }
255 }
256
257 #[derive(Default, Clone, Serialize, Deserialize)]
258 pub struct SignatureFilter {
259 pub ss58_address: Option<String>,
260 pub app_id: Option<u32>,
261 pub nonce: Option<u32>,
262 }
263
264 impl SignatureFilter {
265 pub fn new(ss58_address: Option<String>, app_id: Option<u32>, nonce: Option<u32>) -> Self {
266 Self { ss58_address, app_id, nonce }
267 }
268
269 pub fn ss58_address(mut self, value: String) -> Self {
270 self.ss58_address = Some(value);
271 self
272 }
273
274 pub fn app_id(mut self, value: u32) -> Self {
275 self.app_id = Some(value);
276 self
277 }
278
279 pub fn nonce(mut self, value: u32) -> Self {
280 self.nonce = Some(value);
281 self
282 }
283 }
284
285 #[derive(Debug, Clone, Serialize, Deserialize)]
286 pub struct TransactionSignature {
287 pub ss58_address: Option<String>,
288 pub nonce: u32,
289 pub app_id: u32,
290 pub mortality: Option<(u64, u64)>,
291 }
292}