1use ethers_primitives::*;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4use crate::error::ProviderError;
5
6pub use ethers_eip2718::AccessList;
7
8macro_rules! from_json {
9 ($name: ident) => {
10 impl TryFrom<&str> for $name {
11 type Error = serde_json::Error;
12
13 fn try_from(value: &str) -> Result<Self, Self::Error> {
14 serde_json::from_str(value)
15 }
16 }
17
18 impl TryFrom<String> for $name {
19 type Error = serde_json::Error;
20 fn try_from(value: String) -> Result<Self, Self::Error> {
21 Self::try_from(value.as_ref())
22 }
23 }
24
25 impl TryFrom<serde_json::Value> for $name {
26 type Error = serde_json::Error;
27 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
28 serde_json::from_value(value)
29 }
30 }
31 };
32}
33
34#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
50pub struct TopicFilter(Topic, Topic, Topic, Topic);
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
54pub enum Topic {
55 Unset,
57 OneOf(Vec<H256>),
59 This(H256),
61}
62
63impl Default for Topic {
64 fn default() -> Self {
65 Self::Unset
66 }
67}
68
69#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
70#[serde(untagged)]
71pub enum AddressFilter {
72 Address(Address),
73 Addresses(Vec<Address>),
74}
75
76impl From<Address> for AddressFilter {
77 fn from(value: Address) -> Self {
78 AddressFilter::Address(value)
79 }
80}
81
82impl From<Vec<Address>> for AddressFilter {
83 fn from(value: Vec<Address>) -> Self {
84 AddressFilter::Addresses(value)
85 }
86}
87
88from_json!(AddressFilter);
89
90#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
92#[serde(rename_all = "camelCase")]
93pub struct Filter {
94 pub from_block: Option<U256>,
96 pub to_block: Option<U256>,
98
99 pub address: Option<AddressFilter>,
100
101 pub topics: Option<TopicFilter>,
102}
103
104impl From<(Address, TopicFilter)> for Filter {
105 fn from(value: (Address, TopicFilter)) -> Self {
106 Filter {
107 from_block: None,
108 to_block: None,
109 address: Some(AddressFilter::Address(value.0)),
110 topics: Some(value.1),
111 }
112 }
113}
114
115impl From<(Vec<Address>, TopicFilter)> for Filter {
116 fn from(value: (Vec<Address>, TopicFilter)) -> Self {
117 Filter {
118 from_block: None,
119 to_block: None,
120 address: Some(AddressFilter::Addresses(value.0)),
121 topics: Some(value.1),
122 }
123 }
124}
125
126from_json!(Filter);
127
128#[derive(Serialize, Deserialize, PartialEq, Debug)]
130#[serde(untagged)]
131pub enum BlockNumberOrTag {
132 U256(U256),
133 Tag(BlockTag),
134}
135
136impl From<U256> for BlockNumberOrTag {
137 fn from(v: U256) -> Self {
138 BlockNumberOrTag::U256(v)
139 }
140}
141
142impl From<BlockTag> for BlockNumberOrTag {
143 fn from(v: BlockTag) -> Self {
144 BlockNumberOrTag::Tag(v)
145 }
146}
147
148impl Default for BlockNumberOrTag {
149 fn default() -> Self {
150 BlockNumberOrTag::Tag(BlockTag::Latest)
151 }
152}
153
154#[derive(Serialize, Deserialize, PartialEq, Debug)]
156#[serde(rename_all = "lowercase")]
157pub enum BlockTag {
158 Earliest,
159 Finalized,
160 Safe,
161 Latest,
162 Pending,
163}
164
165impl<'a> TryFrom<&'a str> for BlockNumberOrTag {
166 type Error = anyhow::Error;
167 fn try_from(value: &'a str) -> Result<Self, Self::Error> {
168 if value.starts_with("0x") {
169 Ok(BlockNumberOrTag::U256(serde_json::from_str(&format!(
170 "\"{}\"",
171 value
172 ))?))
173 } else {
174 Ok(BlockNumberOrTag::Tag(serde_json::from_str(&format!(
175 "\"{}\"",
176 value
177 ))?))
178 }
179 }
180}
181
182#[derive(Serialize, Deserialize)]
183#[serde(rename_all = "camelCase")]
184pub struct FeeHistory {
185 pub oldest_block: U256,
187
188 pub base_fee_per_gas: Vec<U256>,
189
190 pub reward: Vec<Vec<U256>>,
191}
192
193#[derive(Serialize, Deserialize, Debug)]
194#[serde(rename_all = "camelCase")]
195pub struct Log {
196 pub removed: bool,
197
198 pub log_index: U256,
199
200 pub transaction_index: U256,
201
202 pub transaction_hash: U256,
203
204 pub block_hash: H256,
205
206 pub block_number: U256,
207
208 pub address: Address,
209
210 pub data: Bytes,
211
212 pub topics: Vec<H256>,
213}
214
215#[derive(Serialize, Deserialize, Debug)]
216#[serde(untagged)]
217pub enum FilterEvents {
218 BlocksOrTransactions(Vec<H256>),
219
220 Logs(Vec<Log>),
221}
222
223#[derive(Debug, Serialize, Deserialize, PartialEq)]
224#[serde(untagged)]
225pub enum SyncingStatus {
226 Syncing(Syncing),
227
228 #[serde(deserialize_with = "from_bool", serialize_with = "as_bool")]
229 False,
230}
231
232impl Default for SyncingStatus {
233 fn default() -> Self {
234 SyncingStatus::False
235 }
236}
237
238fn from_bool<'de, D>(d: D) -> std::result::Result<(), D::Error>
239where
240 D: Deserializer<'de>,
241{
242 bool::deserialize(d).and_then(|flag| {
243 if !flag {
244 Ok(())
245 } else {
246 Err(ProviderError::Syncing).map_err(serde::de::Error::custom)
247 }
248 })
249}
250
251fn as_bool<S>(serializer: S) -> std::result::Result<S::Ok, S::Error>
252where
253 S: Serializer,
254{
255 serializer.serialize_bool(false)
256}
257
258#[derive(Debug, Serialize, Deserialize, PartialEq)]
259#[serde(rename_all = "camelCase")]
260pub struct Syncing {
261 starting_block: U256,
263
264 current_block: U256,
266
267 highest_block: U256,
269}
270
271#[derive(Serialize, Deserialize, Debug)]
272#[serde(rename_all = "camelCase")]
273pub struct TransactionReceipt {
274 pub from: Address,
276 pub to: Option<Address>,
278 pub contract_address: Option<Address>,
280 pub gas_used: U256,
282 pub cumulative_gas_used: U256,
284
285 pub effective_gas_price: U256,
286
287 transaction_index: U256,
288 pub block_hash: H256,
290 pub block_number: U256,
292 pub status: Option<Status>,
294 pub logs: Vec<Log>,
296 pub logs_bloom: Bytes,
298 pub root: Option<H256>,
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize)]
303pub enum Status {
304 #[serde(rename = "0x1")]
306 Success,
307 #[serde(rename = "0x0")]
309 Failure,
310}
311
312#[derive(Serialize, Deserialize)]
313#[serde(rename_all = "camelCase")]
314pub struct Block {
315 pub hash: Option<H256>,
317 #[serde(rename = "parentHash")]
319 pub parent_hash: H256,
320
321 #[serde(rename = "sha3Uncles")]
323 pub sha3_uncles: Option<H256>,
324
325 pub miner: Address,
327
328 #[serde(rename = "stateRoot")]
330 pub state_root: H256,
331
332 #[serde(rename = "transactionsRoot")]
334 pub transactions_root: H256,
335
336 #[serde(rename = "receiptsRoot")]
338 pub receipts_root: H256,
339
340 #[serde(rename = "logsBloom")]
342 #[serde(skip_serializing_if = "Option::is_none")]
343 pub logs_bloom: Option<Bytes>,
344
345 #[serde(skip_serializing_if = "Option::is_none")]
347 pub difficulty: Option<Bytes>,
348
349 pub number: Option<U256>,
351
352 #[serde(rename = "gasLimit")]
355 pub gas_limit: U256,
356
357 #[serde(rename = "gasUsed")]
359 pub gas_used: U256,
360
361 pub timestamp: U256,
363
364 #[serde(rename = "extraData")]
366 pub extra_data: Bytes,
367
368 #[serde(rename = "mixHash")]
370 pub mix_hash: Option<H256>,
371
372 pub nonce: Option<U256>,
374
375 #[serde(rename = "totalDeffficult")]
377 #[serde(skip_serializing_if = "Option::is_none")]
378 pub total_deffficult: Option<Bytes>,
379
380 #[serde(rename = "baseFeePerGas")]
382 #[serde(skip_serializing_if = "Option::is_none")]
383 pub base_fee_per_gas: Option<U256>,
384
385 pub size: U256,
387
388 pub transactions: Vec<TransactionOrHash>,
390
391 pub uncles: Vec<H256>,
393}
394
395#[derive(Serialize, Deserialize)]
396#[serde(untagged)]
397pub enum TransactionOrHash {
398 Null,
399 Hash(H256),
400 Transaction(Transaction),
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize)]
404pub enum TransactionType {
405 #[serde(rename = "0x00")]
407 Legacy,
408 #[serde(rename = "0x01")]
410 Eip2930,
411 #[serde(rename = "0x02")]
413 Eip1559,
414}
415
416#[derive(Serialize, Deserialize, Debug, Clone)]
417pub struct Transaction {
418 #[serde(skip_serializing_if = "Option::is_none")]
424 pub r#type: Option<TransactionType>,
425 #[serde(skip_serializing_if = "Option::is_none")]
427 pub nonce: Option<U256>,
428 pub to: Address,
430 #[serde(skip_serializing_if = "Option::is_none")]
432 pub gas: Option<U256>,
433
434 #[serde(rename = "transactionIndex")]
436 #[serde(skip_serializing_if = "Option::is_none")]
437 transaction_index: Option<U256>,
438 #[serde(rename = "blockHash")]
440 #[serde(skip_serializing_if = "Option::is_none")]
441 pub block_hash: Option<H256>,
442 #[serde(rename = "blockNumber")]
444 #[serde(skip_serializing_if = "Option::is_none")]
445 pub block_number: Option<U256>,
446 #[serde(rename = "gasPrice")]
448 #[serde(skip_serializing_if = "Option::is_none")]
449 pub gas_price: Option<U256>,
450 #[serde(skip_serializing_if = "Option::is_none")]
452 pub hash: Option<H256>,
453 #[serde(skip_serializing_if = "Option::is_none")]
455 pub value: Option<U256>,
456 pub input: Bytes,
458 #[serde(rename = "maxPriorityFeePerGas")]
460 #[serde(skip_serializing_if = "Option::is_none")]
461 pub max_priority_fee_per_gas: Option<U256>,
462 #[serde(rename = "maxFeePerGas")]
465 #[serde(skip_serializing_if = "Option::is_none")]
466 pub max_fee_per_gas: Option<U256>,
467 #[serde(skip_serializing_if = "Option::is_none")]
469 pub access_list: Option<AccessList>,
470 #[serde(rename = "chainId")]
472 #[serde(skip_serializing_if = "Option::is_none")]
473 pub chain_id: Option<U256>,
474 #[serde(skip_serializing_if = "Option::is_none")]
476 pub v: Option<U256>,
477 #[serde(skip_serializing_if = "Option::is_none")]
479 pub r: Option<U256>,
480 #[serde(skip_serializing_if = "Option::is_none")]
482 pub s: Option<U256>,
483}
484
485from_json!(Transaction);