1use anyhow::Context;
2use serde::{Deserialize, Serialize};
3
4#[derive(Default, Debug, Clone)]
5#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
6pub struct Query {
7 pub from_block: u64,
8 pub to_block: Option<u64>,
9 pub include_all_blocks: bool,
10 pub transactions: Vec<TransactionRequest>,
11 pub logs: Vec<LogRequest>,
12 pub traces: Vec<TraceRequest>,
13 pub fields: Fields,
14}
15
16#[derive(Debug, Clone, Copy)]
17pub struct Hash(pub [u8; 32]);
18
19#[derive(Debug, Clone, Copy)]
20pub struct Address(pub [u8; 20]);
21
22#[derive(Debug, Clone, Copy)]
23pub struct Sighash(pub [u8; 4]);
24
25#[derive(Debug, Clone, Copy)]
26pub struct Topic(pub [u8; 32]);
27
28#[cfg(feature = "pyo3")]
29fn extract_hex<const N: usize>(ob: &pyo3::Bound<'_, pyo3::PyAny>) -> pyo3::PyResult<[u8; N]> {
30 use pyo3::types::PyAnyMethods;
31
32 let s: &str = ob.extract()?;
33 let s = s.strip_prefix("0x").context("strip 0x prefix")?;
34 let mut out = [0; N];
35 faster_hex::hex_decode(s.as_bytes(), &mut out).context("decode hex")?;
36
37 Ok(out)
38}
39
40#[cfg(feature = "pyo3")]
41impl<'py> pyo3::FromPyObject<'py> for Hash {
42 fn extract_bound(ob: &pyo3::Bound<'py, pyo3::PyAny>) -> pyo3::PyResult<Self> {
43 let out = extract_hex(ob)?;
44 Ok(Self(out))
45 }
46}
47
48#[cfg(feature = "pyo3")]
49impl<'py> pyo3::FromPyObject<'py> for Address {
50 fn extract_bound(ob: &pyo3::Bound<'py, pyo3::PyAny>) -> pyo3::PyResult<Self> {
51 let out = extract_hex(ob)?;
52 Ok(Self(out))
53 }
54}
55
56#[cfg(feature = "pyo3")]
57impl<'py> pyo3::FromPyObject<'py> for Sighash {
58 fn extract_bound(ob: &pyo3::Bound<'py, pyo3::PyAny>) -> pyo3::PyResult<Self> {
59 let out = extract_hex(ob)?;
60 Ok(Self(out))
61 }
62}
63
64#[cfg(feature = "pyo3")]
65impl<'py> pyo3::FromPyObject<'py> for Topic {
66 fn extract_bound(ob: &pyo3::Bound<'py, pyo3::PyAny>) -> pyo3::PyResult<Self> {
67 let out = extract_hex(ob)?;
68 Ok(Self(out))
69 }
70}
71
72#[derive(Default, Debug, Clone)]
79#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
80pub struct TransactionRequest {
81 pub from_: Vec<Address>,
82 pub to: Vec<Address>,
83 pub sighash: Vec<Sighash>,
84 pub status: Vec<u8>,
85 pub type_: Vec<u8>,
86 pub contract_deployment_address: Vec<Address>,
87 pub hash: Vec<Hash>,
88 pub include_logs: bool,
89 pub include_traces: bool,
90 pub include_blocks: bool,
91}
92
93#[derive(Default, Debug, Clone)]
94#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
95pub struct LogRequest {
96 pub address: Vec<Address>,
97 pub topic0: Vec<Topic>,
98 pub topic1: Vec<Topic>,
99 pub topic2: Vec<Topic>,
100 pub topic3: Vec<Topic>,
101 pub include_transactions: bool,
102 pub include_transaction_logs: bool,
103 pub include_transaction_traces: bool,
104 pub include_blocks: bool,
105}
106
107#[derive(Default, Debug, Clone)]
108#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
109pub struct TraceRequest {
110 pub from_: Vec<Address>,
111 pub to: Vec<Address>,
112 pub address: Vec<Address>,
113 pub call_type: Vec<String>,
114 pub reward_type: Vec<String>,
115 pub type_: Vec<String>,
116 pub sighash: Vec<Sighash>,
117 pub author: Vec<Address>,
118 pub include_transactions: bool,
119 pub include_transaction_logs: bool,
120 pub include_transaction_traces: bool,
121 pub include_blocks: bool,
122}
123
124#[derive(Deserialize, Serialize, Default, Debug, Clone, Copy)]
125#[serde(default)]
126#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
127pub struct Fields {
128 pub block: BlockFields,
129 pub transaction: TransactionFields,
130 pub log: LogFields,
131 pub trace: TraceFields,
132}
133
134impl Fields {
135 pub fn all() -> Self {
136 Self {
137 block: BlockFields::all(),
138 transaction: TransactionFields::all(),
139 log: LogFields::all(),
140 trace: TraceFields::all(),
141 }
142 }
143}
144
145#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
146#[serde(default)]
147#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
148pub struct BlockFields {
149 pub number: bool,
150 pub hash: bool,
151 pub parent_hash: bool,
152 pub nonce: bool,
153 pub sha3_uncles: bool,
154 pub logs_bloom: bool,
155 pub transactions_root: bool,
156 pub state_root: bool,
157 pub receipts_root: bool,
158 pub miner: bool,
159 pub difficulty: bool,
160 pub total_difficulty: bool,
161 pub extra_data: bool,
162 pub size: bool,
163 pub gas_limit: bool,
164 pub gas_used: bool,
165 pub timestamp: bool,
166 pub uncles: bool,
167 pub base_fee_per_gas: bool,
168 pub blob_gas_used: bool,
169 pub excess_blob_gas: bool,
170 pub parent_beacon_block_root: bool,
171 pub withdrawals_root: bool,
172 pub withdrawals: bool,
173 pub l1_block_number: bool,
174 pub send_count: bool,
175 pub send_root: bool,
176 pub mix_hash: bool,
177}
178
179impl BlockFields {
180 pub fn all() -> Self {
181 BlockFields {
182 number: true,
183 hash: true,
184 parent_hash: true,
185 nonce: true,
186 sha3_uncles: true,
187 logs_bloom: true,
188 transactions_root: true,
189 state_root: true,
190 receipts_root: true,
191 miner: true,
192 difficulty: true,
193 total_difficulty: true,
194 extra_data: true,
195 size: true,
196 gas_limit: true,
197 gas_used: true,
198 timestamp: true,
199 uncles: true,
200 base_fee_per_gas: true,
201 blob_gas_used: true,
202 excess_blob_gas: true,
203 parent_beacon_block_root: true,
204 withdrawals_root: true,
205 withdrawals: true,
206 l1_block_number: true,
207 send_count: true,
208 send_root: true,
209 mix_hash: true,
210 }
211 }
212}
213
214#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
215#[serde(default)]
216#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
217pub struct TransactionFields {
218 pub block_hash: bool,
219 pub block_number: bool,
220 #[serde(rename = "from")]
221 pub from_: bool,
222 pub gas: bool,
223 pub gas_price: bool,
224 pub hash: bool,
225 pub input: bool,
226 pub nonce: bool,
227 pub to: bool,
228 pub transaction_index: bool,
229 pub value: bool,
230 pub v: bool,
231 pub r: bool,
232 pub s: bool,
233 pub max_priority_fee_per_gas: bool,
234 pub max_fee_per_gas: bool,
235 pub chain_id: bool,
236 pub cumulative_gas_used: bool,
237 pub effective_gas_price: bool,
238 pub gas_used: bool,
239 pub contract_address: bool,
240 pub logs_bloom: bool,
241 #[serde(rename = "type")]
242 pub type_: bool,
243 pub root: bool,
244 pub status: bool,
245 pub sighash: bool,
246 pub y_parity: bool,
247 pub access_list: bool,
248 pub l1_fee: bool,
249 pub l1_gas_price: bool,
250 pub l1_fee_scalar: bool,
251 pub gas_used_for_l1: bool,
252 pub max_fee_per_blob_gas: bool,
253 pub blob_versioned_hashes: bool,
254 pub deposit_nonce: bool,
255 pub blob_gas_price: bool,
256 pub deposit_receipt_version: bool,
257 pub blob_gas_used: bool,
258 pub l1_base_fee_scalar: bool,
259 pub l1_blob_base_fee: bool,
260 pub l1_blob_base_fee_scalar: bool,
261 pub l1_block_number: bool,
262 pub mint: bool,
263 pub source_hash: bool,
264}
265
266impl TransactionFields {
267 pub fn all() -> Self {
268 TransactionFields {
269 block_hash: true,
270 block_number: true,
271 from_: true,
272 gas: true,
273 gas_price: true,
274 hash: true,
275 input: true,
276 nonce: true,
277 to: true,
278 transaction_index: true,
279 value: true,
280 v: true,
281 r: true,
282 s: true,
283 max_priority_fee_per_gas: true,
284 max_fee_per_gas: true,
285 chain_id: true,
286 cumulative_gas_used: true,
287 effective_gas_price: true,
288 gas_used: true,
289 contract_address: true,
290 logs_bloom: true,
291 type_: true,
292 root: true,
293 status: true,
294 sighash: true,
295 y_parity: true,
296 access_list: true,
297 l1_fee: true,
298 l1_gas_price: true,
299 l1_fee_scalar: true,
300 gas_used_for_l1: true,
301 max_fee_per_blob_gas: true,
302 blob_versioned_hashes: true,
303 deposit_nonce: true,
304 blob_gas_price: true,
305 deposit_receipt_version: true,
306 blob_gas_used: true,
307 l1_base_fee_scalar: true,
308 l1_blob_base_fee: true,
309 l1_blob_base_fee_scalar: true,
310 l1_block_number: true,
311 mint: true,
312 source_hash: true,
313 }
314 }
315}
316
317#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
318#[serde(default)]
319#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
320pub struct LogFields {
321 pub removed: bool,
322 pub log_index: bool,
323 pub transaction_index: bool,
324 pub transaction_hash: bool,
325 pub block_hash: bool,
326 pub block_number: bool,
327 pub address: bool,
328 pub data: bool,
329 pub topic0: bool,
330 pub topic1: bool,
331 pub topic2: bool,
332 pub topic3: bool,
333}
334
335impl LogFields {
336 pub fn all() -> Self {
337 LogFields {
338 removed: true,
339 log_index: true,
340 transaction_index: true,
341 transaction_hash: true,
342 block_hash: true,
343 block_number: true,
344 address: true,
345 data: true,
346 topic0: true,
347 topic1: true,
348 topic2: true,
349 topic3: true,
350 }
351 }
352}
353
354#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
355#[serde(default)]
356#[cfg_attr(feature = "pyo3", derive(pyo3::FromPyObject))]
357pub struct TraceFields {
358 #[serde(rename = "from")]
359 pub from_: bool,
360 pub to: bool,
361 pub call_type: bool,
362 pub gas: bool,
363 pub input: bool,
364 pub init: bool,
365 pub value: bool,
366 pub author: bool,
367 pub reward_type: bool,
368 pub block_hash: bool,
369 pub block_number: bool,
370 pub address: bool,
371 pub code: bool,
372 pub gas_used: bool,
373 pub output: bool,
374 pub subtraces: bool,
375 pub trace_address: bool,
376 pub transaction_hash: bool,
377 pub transaction_position: bool,
378 #[serde(rename = "type")]
379 pub type_: bool,
380 pub error: bool,
381 pub sighash: bool,
382 pub action_address: bool,
383 pub balance: bool,
384 pub refund_address: bool,
385}
386
387impl TraceFields {
388 pub fn all() -> Self {
389 TraceFields {
390 from_: true,
391 to: true,
392 call_type: true,
393 gas: true,
394 input: true,
395 init: true,
396 value: true,
397 author: true,
398 reward_type: true,
399 block_hash: true,
400 block_number: true,
401 address: true,
402 code: true,
403 gas_used: true,
404 output: true,
405 subtraces: true,
406 trace_address: true,
407 transaction_hash: true,
408 transaction_position: true,
409 type_: true,
410 error: true,
411 sighash: true,
412 action_address: true,
413 balance: true,
414 refund_address: true,
415 }
416 }
417}