avail_rust_core/rpc/system/
fetch_extrinsics.rs1use crate::{HashNumber, rpc::Error};
2use primitive_types::H256;
3use serde::{Deserialize, Serialize};
4use std::str::FromStr;
5use subxt_rpcs::{RpcClient, rpc_params};
6
7pub async fn fetch_extrinsics_v1(
8 client: &RpcClient,
9 block_id: HashNumber,
10 options: &Options,
11) -> Result<Vec<ExtrinsicInfo>, Error> {
12 let options: RpcOptions = RpcOptions {
13 filter: Filter {
14 transaction: Some(options.transaction_filter.clone()),
15 signature: SignatureFilter {
16 ss58_address: options.ss58_address.clone(),
17 app_id: options.app_id,
18 nonce: options.nonce,
19 },
20 },
21 encode_selector: Some(options.encode_as),
22 };
23
24 let params = rpc_params![block_id, options];
25 let value: Vec<ExtrinsicInformation> = client.request("system_fetchExtrinsicsV1", params).await?;
26 let value: Vec<ExtrinsicInfo> = value.into_iter().map(|x| x.into()).collect();
27 Ok(value)
28}
29
30#[derive(Debug, Default, Clone)]
31pub struct Options {
32 pub transaction_filter: ExtrinsicFilter,
33 pub ss58_address: Option<String>,
34 pub app_id: Option<u32>,
35 pub nonce: Option<u32>,
36 pub encode_as: EncodeSelector,
37}
38
39impl Options {
40 pub fn new() -> Self {
41 Self::default()
42 }
43
44 pub fn nonce(mut self, value: u32) -> Self {
45 self.nonce = Some(value);
46 self
47 }
48
49 pub fn app_id(mut self, value: u32) -> Self {
50 self.app_id = Some(value);
51 self
52 }
53
54 pub fn ss58_address(mut self, value: impl Into<String>) -> Self {
55 self.ss58_address = Some(value.into());
56 self
57 }
58
59 pub fn filter(mut self, value: impl Into<ExtrinsicFilter>) -> Self {
60 self.transaction_filter = value.into();
61 self
62 }
63
64 pub fn encode_as(mut self, value: EncodeSelector) -> Self {
65 self.encode_as = value;
66 self
67 }
68}
69
70#[derive(Debug, Clone, Default, Copy, Serialize, Deserialize)]
71#[repr(u8)]
72pub enum EncodeSelector {
73 None = 0,
74 Call = 1,
75 #[default]
76 Extrinsic = 2,
77}
78
79#[derive(Debug, Clone)]
80pub struct ExtrinsicInfo {
81 pub data: Option<String>,
83 pub ext_hash: H256,
84 pub ext_index: u32,
85 pub pallet_id: u8,
86 pub variant_id: u8,
87 pub signer_payload: Option<SignerPayload>,
88}
89
90impl From<ExtrinsicInformation> for ExtrinsicInfo {
91 fn from(value: ExtrinsicInformation) -> Self {
92 Self {
93 data: value.encoded,
94 ext_hash: value.tx_hash,
95 ext_index: value.tx_index,
96 pallet_id: value.pallet_id,
97 variant_id: value.call_id,
98 signer_payload: value.signature,
99 }
100 }
101}
102
103#[derive(Debug, Default, Clone, Serialize, Deserialize)]
104pub struct SignerPayload {
105 pub app_id: u32,
106 pub nonce: u32,
107 pub ss58_address: Option<String>,
108 pub mortality: Option<(u64, u64)>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub enum ExtrinsicFilter {
113 All,
114 TxHash(Vec<H256>),
115 TxIndex(Vec<u32>),
116 Pallet(Vec<u8>),
117 PalletCall(Vec<(u8, u8)>),
118}
119
120impl ExtrinsicFilter {
121 pub fn new() -> Self {
122 Self::default()
123 }
124}
125
126impl Default for ExtrinsicFilter {
127 fn default() -> Self {
128 Self::All
129 }
130}
131
132impl TryFrom<String> for ExtrinsicFilter {
133 type Error = String;
134
135 fn try_from(value: String) -> Result<Self, Self::Error> {
136 Self::try_from(value.as_str())
137 }
138}
139
140impl TryFrom<&String> for ExtrinsicFilter {
141 type Error = String;
142
143 fn try_from(value: &String) -> Result<Self, Self::Error> {
144 Self::try_from(value.as_str())
145 }
146}
147
148impl TryFrom<&str> for ExtrinsicFilter {
149 type Error = String;
150
151 fn try_from(value: &str) -> Result<Self, Self::Error> {
152 let h256 = H256::from_str(value).map_err(|x| x.to_string())?;
153 Ok(Self::TxHash(vec![h256]))
154 }
155}
156
157impl From<H256> for ExtrinsicFilter {
158 fn from(value: H256) -> Self {
159 Self::TxHash(vec![value])
160 }
161}
162
163impl From<Vec<H256>> for ExtrinsicFilter {
164 fn from(value: Vec<H256>) -> Self {
165 Self::TxHash(value)
166 }
167}
168
169impl From<&Vec<H256>> for ExtrinsicFilter {
170 fn from(value: &Vec<H256>) -> Self {
171 Self::TxHash(value.clone())
172 }
173}
174
175impl From<&[H256]> for ExtrinsicFilter {
176 fn from(value: &[H256]) -> Self {
177 Self::TxHash(value.to_vec())
178 }
179}
180
181impl From<u32> for ExtrinsicFilter {
182 fn from(value: u32) -> Self {
183 Self::TxIndex(vec![value])
184 }
185}
186
187impl From<Vec<u32>> for ExtrinsicFilter {
188 fn from(value: Vec<u32>) -> Self {
189 Self::TxIndex(value)
190 }
191}
192
193impl From<&Vec<u32>> for ExtrinsicFilter {
194 fn from(value: &Vec<u32>) -> Self {
195 Self::TxIndex(value.clone())
196 }
197}
198
199impl From<&[u32]> for ExtrinsicFilter {
200 fn from(value: &[u32]) -> Self {
201 Self::TxIndex(value.to_vec())
202 }
203}
204
205impl From<u8> for ExtrinsicFilter {
206 fn from(value: u8) -> Self {
207 Self::Pallet(vec![value])
208 }
209}
210
211impl From<&[u8]> for ExtrinsicFilter {
212 fn from(value: &[u8]) -> Self {
213 Self::Pallet(value.to_vec())
214 }
215}
216
217impl From<Vec<u8>> for ExtrinsicFilter {
218 fn from(value: Vec<u8>) -> Self {
219 Self::Pallet(value)
220 }
221}
222
223impl From<&Vec<u8>> for ExtrinsicFilter {
224 fn from(value: &Vec<u8>) -> Self {
225 Self::Pallet(value.clone())
226 }
227}
228
229impl From<(u8, u8)> for ExtrinsicFilter {
230 fn from(value: (u8, u8)) -> Self {
231 Self::PalletCall(vec![value])
232 }
233}
234
235impl From<&[(u8, u8)]> for ExtrinsicFilter {
236 fn from(value: &[(u8, u8)]) -> Self {
237 Self::PalletCall(value.to_vec())
238 }
239}
240
241impl From<Vec<(u8, u8)>> for ExtrinsicFilter {
242 fn from(value: Vec<(u8, u8)>) -> Self {
243 Self::PalletCall(value)
244 }
245}
246
247impl From<&Vec<(u8, u8)>> for ExtrinsicFilter {
248 fn from(value: &Vec<(u8, u8)>) -> Self {
249 Self::PalletCall(value.clone())
250 }
251}
252
253#[derive(Debug, Clone, Default, Serialize, Deserialize)]
254struct RpcOptions {
255 pub filter: Filter,
256 pub encode_selector: Option<EncodeSelector>,
257}
258
259#[derive(Debug, Default, Clone, Serialize, Deserialize)]
260struct Filter {
261 pub transaction: Option<ExtrinsicFilter>,
262 pub signature: SignatureFilter,
263}
264
265#[derive(Debug, Default, Clone, Serialize, Deserialize)]
266struct SignatureFilter {
267 pub ss58_address: Option<String>,
268 pub app_id: Option<u32>,
269 pub nonce: Option<u32>,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize, Default)]
277pub struct ExtrinsicInformation {
278 pub encoded: Option<String>,
280 pub tx_hash: H256,
281 pub tx_index: u32,
282 pub pallet_id: u8,
283 pub call_id: u8,
284 pub signature: Option<SignerPayload>,
285}