anvil_core/eth/
mod.rs

1use crate::{eth::subscription::SubscriptionId, types::ReorgOptions};
2use alloy_primitives::{Address, Bytes, TxHash, B256, B64, U256};
3use alloy_rpc_types::{
4    anvil::{Forking, MineOptions},
5    pubsub::{Params as SubscriptionParams, SubscriptionKind},
6    request::TransactionRequest,
7    simulate::SimulatePayload,
8    state::StateOverride,
9    trace::{
10        filter::TraceFilter,
11        geth::{GethDebugTracingCallOptions, GethDebugTracingOptions},
12    },
13    BlockId, BlockNumberOrTag as BlockNumber, Filter, Index,
14};
15use alloy_serde::WithOtherFields;
16use foundry_common::serde_helpers::{
17    deserialize_number, deserialize_number_opt, deserialize_number_seq,
18};
19
20pub mod block;
21pub mod proof;
22pub mod subscription;
23pub mod transaction;
24pub mod trie;
25pub mod wallet;
26
27pub mod serde_helpers;
28use self::serde_helpers::*;
29
30/// Wrapper type that ensures the type is named `params`
31#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
32pub struct Params<T: Default> {
33    #[serde(default)]
34    pub params: T,
35}
36
37/// Represents ethereum JSON-RPC API
38#[derive(Clone, Debug, serde::Deserialize)]
39#[serde(tag = "method", content = "params")]
40#[expect(clippy::large_enum_variant)]
41pub enum EthRequest {
42    #[serde(rename = "web3_clientVersion", with = "empty_params")]
43    Web3ClientVersion(()),
44
45    #[serde(rename = "web3_sha3", with = "sequence")]
46    Web3Sha3(Bytes),
47
48    #[serde(rename = "eth_chainId", with = "empty_params")]
49    EthChainId(()),
50
51    #[serde(rename = "eth_networkId", alias = "net_version", with = "empty_params")]
52    EthNetworkId(()),
53
54    #[serde(rename = "net_listening", with = "empty_params")]
55    NetListening(()),
56
57    #[serde(rename = "eth_gasPrice", with = "empty_params")]
58    EthGasPrice(()),
59
60    #[serde(rename = "eth_maxPriorityFeePerGas", with = "empty_params")]
61    EthMaxPriorityFeePerGas(()),
62
63    #[serde(rename = "eth_blobBaseFee", with = "empty_params")]
64    EthBlobBaseFee(()),
65
66    #[serde(rename = "eth_accounts", alias = "eth_requestAccounts", with = "empty_params")]
67    EthAccounts(()),
68
69    #[serde(rename = "eth_blockNumber", with = "empty_params")]
70    EthBlockNumber(()),
71
72    #[serde(rename = "eth_getBalance")]
73    EthGetBalance(Address, Option<BlockId>),
74
75    #[serde(rename = "eth_getAccount")]
76    EthGetAccount(Address, Option<BlockId>),
77
78    #[serde(rename = "eth_getStorageAt")]
79    EthGetStorageAt(Address, U256, Option<BlockId>),
80
81    #[serde(rename = "eth_getBlockByHash")]
82    EthGetBlockByHash(B256, bool),
83
84    #[serde(rename = "eth_getBlockByNumber")]
85    EthGetBlockByNumber(
86        #[serde(deserialize_with = "lenient_block_number::lenient_block_number")] BlockNumber,
87        bool,
88    ),
89
90    #[serde(rename = "eth_getTransactionCount")]
91    EthGetTransactionCount(Address, Option<BlockId>),
92
93    #[serde(rename = "eth_getBlockTransactionCountByHash", with = "sequence")]
94    EthGetTransactionCountByHash(B256),
95
96    #[serde(
97        rename = "eth_getBlockTransactionCountByNumber",
98        deserialize_with = "lenient_block_number::lenient_block_number_seq"
99    )]
100    EthGetTransactionCountByNumber(BlockNumber),
101
102    #[serde(rename = "eth_getUncleCountByBlockHash", with = "sequence")]
103    EthGetUnclesCountByHash(B256),
104
105    #[serde(
106        rename = "eth_getUncleCountByBlockNumber",
107        deserialize_with = "lenient_block_number::lenient_block_number_seq"
108    )]
109    EthGetUnclesCountByNumber(BlockNumber),
110
111    #[serde(rename = "eth_getCode")]
112    EthGetCodeAt(Address, Option<BlockId>),
113
114    /// Returns the account and storage values of the specified account including the Merkle-proof.
115    /// This call can be used to verify that the data you are pulling from is not tampered with.
116    #[serde(rename = "eth_getProof")]
117    EthGetProof(Address, Vec<B256>, Option<BlockId>),
118
119    /// The sign method calculates an Ethereum specific signature with:
120    #[serde(rename = "eth_sign")]
121    EthSign(Address, Bytes),
122
123    /// The sign method calculates an Ethereum specific signature, equivalent to eth_sign:
124    /// <https://docs.metamask.io/wallet/reference/personal_sign/>
125    #[serde(rename = "personal_sign")]
126    PersonalSign(Bytes, Address),
127
128    #[serde(rename = "eth_signTransaction", with = "sequence")]
129    EthSignTransaction(Box<WithOtherFields<TransactionRequest>>),
130
131    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
132    #[serde(rename = "eth_signTypedData")]
133    EthSignTypedData(Address, serde_json::Value),
134
135    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
136    #[serde(rename = "eth_signTypedData_v3")]
137    EthSignTypedDataV3(Address, serde_json::Value),
138
139    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md), and includes full support of arrays and recursive data structures.
140    #[serde(rename = "eth_signTypedData_v4")]
141    EthSignTypedDataV4(Address, alloy_dyn_abi::TypedData),
142
143    #[serde(rename = "eth_sendTransaction", with = "sequence")]
144    EthSendTransaction(Box<WithOtherFields<TransactionRequest>>),
145
146    #[serde(rename = "eth_sendRawTransaction", with = "sequence")]
147    EthSendRawTransaction(Bytes),
148
149    #[serde(rename = "eth_call")]
150    EthCall(
151        WithOtherFields<TransactionRequest>,
152        #[serde(default)] Option<BlockId>,
153        #[serde(default)] Option<StateOverride>,
154    ),
155
156    #[serde(rename = "eth_simulateV1")]
157    EthSimulateV1(SimulatePayload, #[serde(default)] Option<BlockId>),
158
159    #[serde(rename = "eth_createAccessList")]
160    EthCreateAccessList(WithOtherFields<TransactionRequest>, #[serde(default)] Option<BlockId>),
161
162    #[serde(rename = "eth_estimateGas")]
163    EthEstimateGas(
164        WithOtherFields<TransactionRequest>,
165        #[serde(default)] Option<BlockId>,
166        #[serde(default)] Option<StateOverride>,
167    ),
168
169    #[serde(rename = "eth_getTransactionByHash", with = "sequence")]
170    EthGetTransactionByHash(TxHash),
171
172    #[serde(rename = "eth_getTransactionByBlockHashAndIndex")]
173    EthGetTransactionByBlockHashAndIndex(TxHash, Index),
174
175    #[serde(rename = "eth_getTransactionByBlockNumberAndIndex")]
176    EthGetTransactionByBlockNumberAndIndex(BlockNumber, Index),
177
178    #[serde(rename = "eth_getRawTransactionByHash", with = "sequence")]
179    EthGetRawTransactionByHash(TxHash),
180
181    #[serde(rename = "eth_getRawTransactionByBlockHashAndIndex")]
182    EthGetRawTransactionByBlockHashAndIndex(TxHash, Index),
183
184    #[serde(rename = "eth_getRawTransactionByBlockNumberAndIndex")]
185    EthGetRawTransactionByBlockNumberAndIndex(BlockNumber, Index),
186
187    #[serde(rename = "eth_getTransactionReceipt", with = "sequence")]
188    EthGetTransactionReceipt(B256),
189
190    #[serde(rename = "eth_getBlockReceipts", with = "sequence")]
191    EthGetBlockReceipts(BlockId),
192
193    #[serde(rename = "eth_getUncleByBlockHashAndIndex")]
194    EthGetUncleByBlockHashAndIndex(B256, Index),
195
196    #[serde(rename = "eth_getUncleByBlockNumberAndIndex")]
197    EthGetUncleByBlockNumberAndIndex(
198        #[serde(deserialize_with = "lenient_block_number::lenient_block_number")] BlockNumber,
199        Index,
200    ),
201
202    #[serde(rename = "eth_getLogs", with = "sequence")]
203    EthGetLogs(Filter),
204
205    /// Creates a filter object, based on filter options, to notify when the state changes (logs).
206    #[serde(rename = "eth_newFilter", with = "sequence")]
207    EthNewFilter(Filter),
208
209    /// Polling method for a filter, which returns an array of logs which occurred since last poll.
210    #[serde(rename = "eth_getFilterChanges", with = "sequence")]
211    EthGetFilterChanges(String),
212
213    /// Creates a filter in the node, to notify when a new block arrives.
214    /// To check if the state has changed, call `eth_getFilterChanges`.
215    #[serde(rename = "eth_newBlockFilter", with = "empty_params")]
216    EthNewBlockFilter(()),
217
218    /// Creates a filter in the node, to notify when new pending transactions arrive.
219    /// To check if the state has changed, call `eth_getFilterChanges`.
220    #[serde(rename = "eth_newPendingTransactionFilter", with = "empty_params")]
221    EthNewPendingTransactionFilter(()),
222
223    /// Returns an array of all logs matching filter with given id.
224    #[serde(rename = "eth_getFilterLogs", with = "sequence")]
225    EthGetFilterLogs(String),
226
227    /// Removes the filter, returns true if the filter was installed
228    #[serde(rename = "eth_uninstallFilter", with = "sequence")]
229    EthUninstallFilter(String),
230
231    #[serde(rename = "eth_getWork", with = "empty_params")]
232    EthGetWork(()),
233
234    #[serde(rename = "eth_submitWork")]
235    EthSubmitWork(B64, B256, B256),
236
237    #[serde(rename = "eth_submitHashrate")]
238    EthSubmitHashRate(U256, B256),
239
240    #[serde(rename = "eth_feeHistory")]
241    EthFeeHistory(
242        #[serde(deserialize_with = "deserialize_number")] U256,
243        BlockNumber,
244        #[serde(default)] Vec<f64>,
245    ),
246
247    #[serde(rename = "eth_syncing", with = "empty_params")]
248    EthSyncing(()),
249
250    /// geth's `debug_getRawTransaction`  endpoint
251    #[serde(rename = "debug_getRawTransaction", with = "sequence")]
252    DebugGetRawTransaction(TxHash),
253
254    /// geth's `debug_traceTransaction`  endpoint
255    #[serde(rename = "debug_traceTransaction")]
256    DebugTraceTransaction(B256, #[serde(default)] GethDebugTracingOptions),
257
258    /// geth's `debug_traceCall`  endpoint
259    #[serde(rename = "debug_traceCall")]
260    DebugTraceCall(
261        WithOtherFields<TransactionRequest>,
262        #[serde(default)] Option<BlockId>,
263        #[serde(default)] GethDebugTracingCallOptions,
264    ),
265
266    /// Trace transaction endpoint for parity's `trace_transaction`
267    #[serde(rename = "trace_transaction", with = "sequence")]
268    TraceTransaction(B256),
269
270    /// Trace transaction endpoint for parity's `trace_block`
271    #[serde(
272        rename = "trace_block",
273        deserialize_with = "lenient_block_number::lenient_block_number_seq"
274    )]
275    TraceBlock(BlockNumber),
276
277    // Return filtered traces over blocks
278    #[serde(rename = "trace_filter", with = "sequence")]
279    TraceFilter(TraceFilter),
280
281    // Custom endpoints, they're not extracted to a separate type out of serde convenience
282    /// send transactions impersonating specific account and contract addresses.
283    #[serde(
284        rename = "anvil_impersonateAccount",
285        alias = "hardhat_impersonateAccount",
286        with = "sequence"
287    )]
288    ImpersonateAccount(Address),
289    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`
290    #[serde(
291        rename = "anvil_stopImpersonatingAccount",
292        alias = "hardhat_stopImpersonatingAccount",
293        with = "sequence"
294    )]
295    StopImpersonatingAccount(Address),
296    /// Will make every account impersonated
297    #[serde(
298        rename = "anvil_autoImpersonateAccount",
299        alias = "hardhat_autoImpersonateAccount",
300        with = "sequence"
301    )]
302    AutoImpersonateAccount(bool),
303    /// Returns true if automatic mining is enabled, and false.
304    #[serde(rename = "anvil_getAutomine", alias = "hardhat_getAutomine", with = "empty_params")]
305    GetAutoMine(()),
306    /// Mines a series of blocks
307    #[serde(rename = "anvil_mine", alias = "hardhat_mine")]
308    Mine(
309        /// Number of blocks to mine, if not set `1` block is mined
310        #[serde(default, deserialize_with = "deserialize_number_opt")]
311        Option<U256>,
312        /// The time interval between each block in seconds, defaults to `1` seconds
313        /// The interval is applied only to blocks mined in the given method invocation, not to
314        /// blocks mined afterwards. Set this to `0` to instantly mine _all_ blocks
315        #[serde(default, deserialize_with = "deserialize_number_opt")]
316        Option<U256>,
317    ),
318
319    /// Enables or disables, based on the single boolean argument, the automatic mining of new
320    /// blocks with each new transaction submitted to the network.
321    #[serde(rename = "anvil_setAutomine", alias = "evm_setAutomine", with = "sequence")]
322    SetAutomine(bool),
323
324    /// Sets the mining behavior to interval with the given interval (seconds)
325    #[serde(
326        rename = "anvil_setIntervalMining",
327        alias = "evm_setIntervalMining",
328        with = "sequence"
329    )]
330    SetIntervalMining(u64),
331
332    /// Gets the current mining behavior
333    #[serde(rename = "anvil_getIntervalMining", with = "empty_params")]
334    GetIntervalMining(()),
335
336    /// Removes transactions from the pool
337    #[serde(
338        rename = "anvil_dropTransaction",
339        alias = "hardhat_dropTransaction",
340        with = "sequence"
341    )]
342    DropTransaction(B256),
343
344    /// Removes transactions from the pool
345    #[serde(
346        rename = "anvil_dropAllTransactions",
347        alias = "hardhat_dropAllTransactions",
348        with = "empty_params"
349    )]
350    DropAllTransactions(),
351
352    /// Reset the fork to a fresh forked state, and optionally update the fork config
353    #[serde(rename = "anvil_reset", alias = "hardhat_reset")]
354    Reset(#[serde(default)] Option<Params<Option<Forking>>>),
355
356    /// Sets the backend rpc url
357    #[serde(rename = "anvil_setRpcUrl", with = "sequence")]
358    SetRpcUrl(String),
359
360    /// Modifies the balance of an account.
361    #[serde(rename = "anvil_setBalance", alias = "hardhat_setBalance")]
362    SetBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
363
364    /// Sets the code of a contract
365    #[serde(rename = "anvil_setCode", alias = "hardhat_setCode")]
366    SetCode(Address, Bytes),
367
368    /// Sets the nonce of an address
369    #[serde(rename = "anvil_setNonce", alias = "hardhat_setNonce", alias = "evm_setAccountNonce")]
370    SetNonce(Address, #[serde(deserialize_with = "deserialize_number")] U256),
371
372    /// Writes a single slot of the account's storage
373    #[serde(rename = "anvil_setStorageAt", alias = "hardhat_setStorageAt")]
374    SetStorageAt(
375        Address,
376        /// slot
377        U256,
378        /// value
379        B256,
380    ),
381
382    /// Sets the coinbase address
383    #[serde(rename = "anvil_setCoinbase", alias = "hardhat_setCoinbase", with = "sequence")]
384    SetCoinbase(Address),
385
386    /// Sets the chain id
387    #[serde(rename = "anvil_setChainId", with = "sequence")]
388    SetChainId(u64),
389
390    /// Enable or disable logging
391    #[serde(
392        rename = "anvil_setLoggingEnabled",
393        alias = "hardhat_setLoggingEnabled",
394        with = "sequence"
395    )]
396    SetLogging(bool),
397
398    /// Set the minimum gas price for the node
399    #[serde(
400        rename = "anvil_setMinGasPrice",
401        alias = "hardhat_setMinGasPrice",
402        deserialize_with = "deserialize_number_seq"
403    )]
404    SetMinGasPrice(U256),
405
406    /// Sets the base fee of the next block
407    #[serde(
408        rename = "anvil_setNextBlockBaseFeePerGas",
409        alias = "hardhat_setNextBlockBaseFeePerGas",
410        deserialize_with = "deserialize_number_seq"
411    )]
412    SetNextBlockBaseFeePerGas(U256),
413
414    /// Sets the specific timestamp
415    /// Accepts timestamp (Unix epoch) with millisecond precision and returns the number of seconds
416    /// between the given timestamp and the current time.
417    #[serde(
418        rename = "anvil_setTime",
419        alias = "evm_setTime",
420        deserialize_with = "deserialize_number_seq"
421    )]
422    EvmSetTime(U256),
423
424    /// Serializes the current state (including contracts code, contract's storage, accounts
425    /// properties, etc.) into a saveable data blob
426    #[serde(rename = "anvil_dumpState", alias = "hardhat_dumpState")]
427    DumpState(#[serde(default)] Option<Params<Option<bool>>>),
428
429    /// Adds state previously dumped with `DumpState` to the current chain
430    #[serde(rename = "anvil_loadState", alias = "hardhat_loadState", with = "sequence")]
431    LoadState(Bytes),
432
433    /// Retrieves the Anvil node configuration params
434    #[serde(rename = "anvil_nodeInfo", with = "empty_params")]
435    NodeInfo(()),
436
437    /// Retrieves the Anvil node metadata.
438    #[serde(rename = "anvil_metadata", alias = "hardhat_metadata", with = "empty_params")]
439    AnvilMetadata(()),
440
441    // Ganache compatible calls
442    /// Snapshot the state of the blockchain at the current block.
443    ///
444    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_snapshot>
445    #[serde(rename = "anvil_snapshot", alias = "evm_snapshot", with = "empty_params")]
446    EvmSnapshot(()),
447
448    /// Revert the state of the blockchain to a previous snapshot.
449    /// Takes a single parameter, which is the snapshot id to revert to.
450    ///
451    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_revert>
452    #[serde(
453        rename = "anvil_revert",
454        alias = "evm_revert",
455        deserialize_with = "deserialize_number_seq"
456    )]
457    EvmRevert(U256),
458
459    /// Jump forward in time by the given amount of time, in seconds.
460    #[serde(
461        rename = "anvil_increaseTime",
462        alias = "evm_increaseTime",
463        deserialize_with = "deserialize_number_seq"
464    )]
465    EvmIncreaseTime(U256),
466
467    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
468    #[serde(
469        rename = "anvil_setNextBlockTimestamp",
470        alias = "evm_setNextBlockTimestamp",
471        deserialize_with = "deserialize_number_seq"
472    )]
473    EvmSetNextBlockTimeStamp(U256),
474
475    /// Set the exact gas limit that you want in the next block
476    #[serde(
477        rename = "anvil_setBlockGasLimit",
478        alias = "evm_setBlockGasLimit",
479        deserialize_with = "deserialize_number_seq"
480    )]
481    EvmSetBlockGasLimit(U256),
482
483    /// Similar to `evm_increaseTime` but takes sets a block timestamp `interval`.
484    ///
485    /// The timestamp of the next block will be computed as `lastBlock_timestamp + interval`.
486    #[serde(rename = "anvil_setBlockTimestampInterval", with = "sequence")]
487    EvmSetBlockTimeStampInterval(u64),
488
489    /// Removes a `anvil_setBlockTimestampInterval` if it exists
490    #[serde(rename = "anvil_removeBlockTimestampInterval", with = "empty_params")]
491    EvmRemoveBlockTimeStampInterval(()),
492
493    /// Mine a single block
494    #[serde(rename = "evm_mine")]
495    EvmMine(#[serde(default)] Option<Params<Option<MineOptions>>>),
496
497    /// Mine a single block and return detailed data
498    ///
499    /// This behaves exactly as `EvmMine` but returns different output, for compatibility reasons
500    /// this is a separate call since `evm_mine` is not an anvil original.
501    #[serde(rename = "anvil_mine_detailed", alias = "evm_mine_detailed")]
502    EvmMineDetailed(#[serde(default)] Option<Params<Option<MineOptions>>>),
503
504    /// Execute a transaction regardless of signature status
505    #[serde(rename = "eth_sendUnsignedTransaction", with = "sequence")]
506    EthSendUnsignedTransaction(Box<WithOtherFields<TransactionRequest>>),
507
508    /// Turn on call traces for transactions that are returned to the user when they execute a
509    /// transaction (instead of just txhash/receipt)
510    #[serde(rename = "anvil_enableTraces", with = "empty_params")]
511    EnableTraces(()),
512
513    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
514    /// well as the ones that are being scheduled for future execution only.
515    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status>
516    #[serde(rename = "txpool_status", with = "empty_params")]
517    TxPoolStatus(()),
518
519    /// Returns a summary of all the transactions currently pending for inclusion in the next
520    /// block(s), as well as the ones that are being scheduled for future execution only.
521    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect>
522    #[serde(rename = "txpool_inspect", with = "empty_params")]
523    TxPoolInspect(()),
524
525    /// Returns the details of all transactions currently pending for inclusion in the next
526    /// block(s), as well as the ones that are being scheduled for future execution only.
527    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content>
528    #[serde(rename = "txpool_content", with = "empty_params")]
529    TxPoolContent(()),
530
531    /// Otterscan's `ots_getApiLevel` endpoint
532    /// Otterscan currently requires this endpoint, even though it's not part of the ots_*
533    /// <https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71>
534    /// Related upstream issue: <https://github.com/otterscan/otterscan/issues/1081>
535    #[serde(rename = "erigon_getHeaderByNumber")]
536    ErigonGetHeaderByNumber(
537        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq")] BlockNumber,
538    ),
539
540    /// Otterscan's `ots_getApiLevel` endpoint
541    /// Used as a simple API versioning scheme for the ots_* namespace
542    #[serde(rename = "ots_getApiLevel", with = "empty_params")]
543    OtsGetApiLevel(()),
544
545    /// Otterscan's `ots_getInternalOperations` endpoint
546    /// Traces internal ETH transfers, contracts creation (CREATE/CREATE2) and self-destructs for a
547    /// certain transaction.
548    #[serde(rename = "ots_getInternalOperations", with = "sequence")]
549    OtsGetInternalOperations(B256),
550
551    /// Otterscan's `ots_hasCode` endpoint
552    /// Check if an ETH address contains code at a certain block number.
553    #[serde(rename = "ots_hasCode")]
554    OtsHasCode(
555        Address,
556        #[serde(deserialize_with = "lenient_block_number::lenient_block_number", default)]
557        BlockNumber,
558    ),
559
560    /// Otterscan's `ots_traceTransaction` endpoint
561    /// Trace a transaction and generate a trace call tree.
562    #[serde(rename = "ots_traceTransaction", with = "sequence")]
563    OtsTraceTransaction(B256),
564
565    /// Otterscan's `ots_getTransactionError` endpoint
566    /// Given a transaction hash, returns its raw revert reason.
567    #[serde(rename = "ots_getTransactionError", with = "sequence")]
568    OtsGetTransactionError(B256),
569
570    /// Otterscan's `ots_getBlockDetails` endpoint
571    /// Given a block number, return its data. Similar to the standard eth_getBlockByNumber/Hash
572    /// method, but can be optimized by excluding unnecessary data such as transactions and
573    /// logBloom
574    #[serde(rename = "ots_getBlockDetails")]
575    OtsGetBlockDetails(
576        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq", default)]
577        BlockNumber,
578    ),
579
580    /// Otterscan's `ots_getBlockDetails` endpoint
581    /// Same as `ots_getBlockDetails`, but receiving a block hash instead of number
582    #[serde(rename = "ots_getBlockDetailsByHash", with = "sequence")]
583    OtsGetBlockDetailsByHash(B256),
584
585    /// Otterscan's `ots_getBlockTransactions` endpoint
586    /// Gets paginated transaction data for a certain block. Return data is similar to
587    /// eth_getBlockBy* + eth_getTransactionReceipt.
588    #[serde(rename = "ots_getBlockTransactions")]
589    OtsGetBlockTransactions(u64, usize, usize),
590
591    /// Otterscan's `ots_searchTransactionsBefore` endpoint
592    /// Address history navigation. searches backwards from certain point in time.
593    #[serde(rename = "ots_searchTransactionsBefore")]
594    OtsSearchTransactionsBefore(Address, u64, usize),
595
596    /// Otterscan's `ots_searchTransactionsAfter` endpoint
597    /// Address history navigation. searches forward from certain point in time.
598    #[serde(rename = "ots_searchTransactionsAfter")]
599    OtsSearchTransactionsAfter(Address, u64, usize),
600
601    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
602    /// Given a sender address and a nonce, returns the tx hash or null if not found. It returns
603    /// only the tx hash on success, you can use the standard eth_getTransactionByHash after that
604    /// to get the full transaction data.
605    #[serde(rename = "ots_getTransactionBySenderAndNonce")]
606    OtsGetTransactionBySenderAndNonce(
607        Address,
608        #[serde(deserialize_with = "deserialize_number")] U256,
609    ),
610
611    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
612    /// Given an ETH contract address, returns the tx hash and the direct address who created the
613    /// contract.
614    #[serde(rename = "ots_getContractCreator", with = "sequence")]
615    OtsGetContractCreator(Address),
616
617    /// Removes transactions from the pool by sender origin.
618    #[serde(rename = "anvil_removePoolTransactions", with = "sequence")]
619    RemovePoolTransactions(Address),
620
621    /// Reorg the chain
622    #[serde(rename = "anvil_reorg")]
623    Reorg(ReorgOptions),
624
625    /// Rollback the chain
626    #[serde(rename = "anvil_rollback", with = "sequence")]
627    Rollback(Option<u64>),
628
629    /// Wallet
630    #[serde(rename = "wallet_getCapabilities", with = "empty_params")]
631    WalletGetCapabilities(()),
632
633    /// Wallet send_tx
634    #[serde(
635        rename = "wallet_sendTransaction",
636        alias = "odyssey_sendTransaction",
637        with = "sequence"
638    )]
639    WalletSendTransaction(Box<WithOtherFields<TransactionRequest>>),
640
641    /// Add an address to the [`DelegationCapability`] of the wallet
642    ///
643    /// [`DelegationCapability`]: wallet::DelegationCapability  
644    #[serde(rename = "anvil_addCapability", with = "sequence")]
645    AnvilAddCapability(Address),
646
647    /// Set the executor (sponsor) wallet
648    #[serde(rename = "anvil_setExecutor", with = "sequence")]
649    AnvilSetExecutor(String),
650}
651
652/// Represents ethereum JSON-RPC API
653#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
654#[serde(tag = "method", content = "params")]
655pub enum EthPubSub {
656    /// Subscribe to an eth subscription
657    #[serde(rename = "eth_subscribe")]
658    EthSubscribe(SubscriptionKind, #[serde(default)] Box<SubscriptionParams>),
659
660    /// Unsubscribe from an eth subscription
661    #[serde(rename = "eth_unsubscribe", with = "sequence")]
662    EthUnSubscribe(SubscriptionId),
663}
664
665/// Container type for either a request or a pub sub
666#[derive(Clone, Debug, serde::Deserialize)]
667#[serde(untagged)]
668pub enum EthRpcCall {
669    Request(Box<EthRequest>),
670    PubSub(EthPubSub),
671}
672
673#[cfg(test)]
674mod tests {
675    use super::*;
676
677    #[test]
678    fn test_web3_client_version() {
679        let s = r#"{"method": "web3_clientVersion", "params":[]}"#;
680        let value: serde_json::Value = serde_json::from_str(s).unwrap();
681        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
682    }
683
684    #[test]
685    fn test_web3_sha3() {
686        let s = r#"{"method": "web3_sha3", "params":["0x68656c6c6f20776f726c64"]}"#;
687        let value: serde_json::Value = serde_json::from_str(s).unwrap();
688        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
689    }
690
691    #[test]
692    fn test_eth_accounts() {
693        let s = r#"{"method": "eth_accounts", "params":[]}"#;
694        let value: serde_json::Value = serde_json::from_str(s).unwrap();
695        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
696    }
697
698    #[test]
699    fn test_eth_network_id() {
700        let s = r#"{"method": "eth_networkId", "params":[]}"#;
701        let value: serde_json::Value = serde_json::from_str(s).unwrap();
702        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
703    }
704
705    #[test]
706    fn test_eth_get_proof() {
707        let s = r#"{"method":"eth_getProof","params":["0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842",["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"],"latest"]}"#;
708        let value: serde_json::Value = serde_json::from_str(s).unwrap();
709        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
710    }
711
712    #[test]
713    fn test_eth_chain_id() {
714        let s = r#"{"method": "eth_chainId", "params":[]}"#;
715        let value: serde_json::Value = serde_json::from_str(s).unwrap();
716        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
717    }
718
719    #[test]
720    fn test_net_listening() {
721        let s = r#"{"method": "net_listening", "params":[]}"#;
722        let value: serde_json::Value = serde_json::from_str(s).unwrap();
723        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
724    }
725
726    #[test]
727    fn test_eth_block_number() {
728        let s = r#"{"method": "eth_blockNumber", "params":[]}"#;
729        let value: serde_json::Value = serde_json::from_str(s).unwrap();
730        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
731    }
732
733    #[test]
734    fn test_eth_max_priority_fee() {
735        let s = r#"{"method": "eth_maxPriorityFeePerGas", "params":[]}"#;
736        let value: serde_json::Value = serde_json::from_str(s).unwrap();
737        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
738    }
739
740    #[test]
741    fn test_eth_syncing() {
742        let s = r#"{"method": "eth_syncing", "params":[]}"#;
743        let value: serde_json::Value = serde_json::from_str(s).unwrap();
744        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
745    }
746
747    #[test]
748    fn test_custom_impersonate_account() {
749        let s = r#"{"method": "anvil_impersonateAccount", "params":
750["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
751        let value: serde_json::Value = serde_json::from_str(s).unwrap();
752        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
753    }
754
755    #[test]
756    fn test_custom_stop_impersonate_account() {
757        let s = r#"{"method": "anvil_stopImpersonatingAccount",  "params":
758["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
759        let value: serde_json::Value = serde_json::from_str(s).unwrap();
760        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
761    }
762
763    #[test]
764    fn test_custom_auto_impersonate_account() {
765        let s = r#"{"method": "anvil_autoImpersonateAccount",  "params": [true]}"#;
766        let value: serde_json::Value = serde_json::from_str(s).unwrap();
767        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
768    }
769
770    #[test]
771    fn test_custom_get_automine() {
772        let s = r#"{"method": "anvil_getAutomine", "params": []}"#;
773        let value: serde_json::Value = serde_json::from_str(s).unwrap();
774        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
775    }
776
777    #[test]
778    fn test_custom_mine() {
779        let s = r#"{"method": "anvil_mine", "params": []}"#;
780        let value: serde_json::Value = serde_json::from_str(s).unwrap();
781        let req = serde_json::from_value::<EthRequest>(value).unwrap();
782        match req {
783            EthRequest::Mine(num, time) => {
784                assert!(num.is_none());
785                assert!(time.is_none());
786            }
787            _ => unreachable!(),
788        }
789        let s = r#"{"method": "anvil_mine", "params":
790["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
791        let value: serde_json::Value = serde_json::from_str(s).unwrap();
792        let req = serde_json::from_value::<EthRequest>(value).unwrap();
793        match req {
794            EthRequest::Mine(num, time) => {
795                assert!(num.is_some());
796                assert!(time.is_none());
797            }
798            _ => unreachable!(),
799        }
800        let s = r#"{"method": "anvil_mine", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
801        let value: serde_json::Value = serde_json::from_str(s).unwrap();
802        let req = serde_json::from_value::<EthRequest>(value).unwrap();
803        match req {
804            EthRequest::Mine(num, time) => {
805                assert!(num.is_some());
806                assert!(time.is_some());
807            }
808            _ => unreachable!(),
809        }
810    }
811
812    #[test]
813    fn test_custom_auto_mine() {
814        let s = r#"{"method": "anvil_setAutomine", "params": [false]}"#;
815        let value: serde_json::Value = serde_json::from_str(s).unwrap();
816        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
817        let s = r#"{"method": "evm_setAutomine", "params": [false]}"#;
818        let value: serde_json::Value = serde_json::from_str(s).unwrap();
819        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
820    }
821
822    #[test]
823    fn test_custom_interval_mining() {
824        let s = r#"{"method": "anvil_setIntervalMining", "params": [100]}"#;
825        let value: serde_json::Value = serde_json::from_str(s).unwrap();
826        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
827        let s = r#"{"method": "evm_setIntervalMining", "params": [100]}"#;
828        let value: serde_json::Value = serde_json::from_str(s).unwrap();
829        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
830    }
831
832    #[test]
833    fn test_custom_drop_tx() {
834        let s = r#"{"method": "anvil_dropTransaction", "params":
835["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
836        let value: serde_json::Value = serde_json::from_str(s).unwrap();
837        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
838    }
839
840    #[test]
841    fn test_custom_reset() {
842        let s = r#"{"method": "anvil_reset", "params": [{"forking": {"jsonRpcUrl": "https://ethereumpublicnode.com",
843        "blockNumber": "18441649"
844      }
845    }]}"#;
846        let value: serde_json::Value = serde_json::from_str(s).unwrap();
847        let req = serde_json::from_value::<EthRequest>(value).unwrap();
848        match req {
849            EthRequest::Reset(forking) => {
850                let forking = forking.and_then(|f| f.params);
851                assert_eq!(
852                    forking,
853                    Some(Forking {
854                        json_rpc_url: Some("https://ethereumpublicnode.com".into()),
855                        block_number: Some(18441649)
856                    })
857                )
858            }
859            _ => unreachable!(),
860        }
861
862        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
863                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>",
864                "blockNumber": 11095000
865        }}]}"#;
866        let value: serde_json::Value = serde_json::from_str(s).unwrap();
867        let req = serde_json::from_value::<EthRequest>(value).unwrap();
868        match req {
869            EthRequest::Reset(forking) => {
870                let forking = forking.and_then(|f| f.params);
871                assert_eq!(
872                    forking,
873                    Some(Forking {
874                        json_rpc_url: Some(
875                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
876                        ),
877                        block_number: Some(11095000)
878                    })
879                )
880            }
881            _ => unreachable!(),
882        }
883
884        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
885                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>"
886        }}]}"#;
887        let value: serde_json::Value = serde_json::from_str(s).unwrap();
888        let req = serde_json::from_value::<EthRequest>(value).unwrap();
889        match req {
890            EthRequest::Reset(forking) => {
891                let forking = forking.and_then(|f| f.params);
892                assert_eq!(
893                    forking,
894                    Some(Forking {
895                        json_rpc_url: Some(
896                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
897                        ),
898                        block_number: None
899                    })
900                )
901            }
902            _ => unreachable!(),
903        }
904
905        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545", "blockNumber": 14000000}]}"#;
906        let value: serde_json::Value = serde_json::from_str(s).unwrap();
907        let req = serde_json::from_value::<EthRequest>(value).unwrap();
908        match req {
909            EthRequest::Reset(forking) => {
910                let forking = forking.and_then(|f| f.params);
911                assert_eq!(
912                    forking,
913                    Some(Forking {
914                        json_rpc_url: Some("http://localhost:8545".to_string()),
915                        block_number: Some(14000000)
916                    })
917                )
918            }
919            _ => unreachable!(),
920        }
921
922        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": 14000000}]}"#;
923        let value: serde_json::Value = serde_json::from_str(s).unwrap();
924        let req = serde_json::from_value::<EthRequest>(value).unwrap();
925        match req {
926            EthRequest::Reset(forking) => {
927                let forking = forking.and_then(|f| f.params);
928                assert_eq!(
929                    forking,
930                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
931                )
932            }
933            _ => unreachable!(),
934        }
935
936        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": "14000000"}]}"#;
937        let value: serde_json::Value = serde_json::from_str(s).unwrap();
938        let req = serde_json::from_value::<EthRequest>(value).unwrap();
939        match req {
940            EthRequest::Reset(forking) => {
941                let forking = forking.and_then(|f| f.params);
942                assert_eq!(
943                    forking,
944                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
945                )
946            }
947            _ => unreachable!(),
948        }
949
950        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545"}]}"#;
951        let value: serde_json::Value = serde_json::from_str(s).unwrap();
952        let req = serde_json::from_value::<EthRequest>(value).unwrap();
953        match req {
954            EthRequest::Reset(forking) => {
955                let forking = forking.and_then(|f| f.params);
956                assert_eq!(
957                    forking,
958                    Some(Forking {
959                        json_rpc_url: Some("http://localhost:8545".to_string()),
960                        block_number: None
961                    })
962                )
963            }
964            _ => unreachable!(),
965        }
966
967        let s = r#"{"method": "anvil_reset"}"#;
968        let value: serde_json::Value = serde_json::from_str(s).unwrap();
969        let req = serde_json::from_value::<EthRequest>(value).unwrap();
970        match req {
971            EthRequest::Reset(forking) => {
972                assert!(forking.is_none())
973            }
974            _ => unreachable!(),
975        }
976    }
977
978    #[test]
979    fn test_custom_set_balance() {
980        let s = r#"{"method": "anvil_setBalance", "params":
981["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
982        let value: serde_json::Value = serde_json::from_str(s).unwrap();
983        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
984
985        let s = r#"{"method": "anvil_setBalance", "params":
986["0xd84de507f3fada7df80908082d3239466db55a71", 1337]}"#;
987        let value: serde_json::Value = serde_json::from_str(s).unwrap();
988        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
989    }
990
991    #[test]
992    fn test_custom_set_code() {
993        let s = r#"{"method": "anvil_setCode", "params":
994["0xd84de507f3fada7df80908082d3239466db55a71", "0x0123456789abcdef"]}"#;
995        let value: serde_json::Value = serde_json::from_str(s).unwrap();
996        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
997
998        let s = r#"{"method": "anvil_setCode", "params":
999["0xd84de507f3fada7df80908082d3239466db55a71", "0x"]}"#;
1000        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1001        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1002
1003        let s = r#"{"method": "anvil_setCode", "params":
1004["0xd84de507f3fada7df80908082d3239466db55a71", ""]}"#;
1005        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1006        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1007    }
1008
1009    #[test]
1010    fn test_custom_set_nonce() {
1011        let s = r#"{"method": "anvil_setNonce", "params":
1012["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1013        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1014        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1015        let s = r#"{"method":
1016"hardhat_setNonce", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1017        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1018        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1019        let s = r#"{"method": "evm_setAccountNonce", "params":
1020["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1021        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1022        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1023    }
1024
1025    #[test]
1026    fn test_serde_custom_set_storage_at() {
1027        let s = r#"{"method": "anvil_setStorageAt", "params":
1028["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0",
1029"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1030        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1031        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1032
1033        let s = r#"{"method": "hardhat_setStorageAt", "params":
1034["0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
1035"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
1036"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1037        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1038        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1039    }
1040
1041    #[test]
1042    fn test_serde_custom_coinbase() {
1043        let s = r#"{"method": "anvil_setCoinbase", "params":
1044["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#;
1045        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1046        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1047    }
1048
1049    #[test]
1050    fn test_serde_custom_logging() {
1051        let s = r#"{"method": "anvil_setLoggingEnabled", "params": [false]}"#;
1052        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1053        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1054    }
1055
1056    #[test]
1057    fn test_serde_custom_min_gas_price() {
1058        let s = r#"{"method": "anvil_setMinGasPrice", "params": ["0x0"]}"#;
1059        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1060        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1061    }
1062
1063    #[test]
1064    fn test_serde_custom_next_block_base_fee() {
1065        let s = r#"{"method": "anvil_setNextBlockBaseFeePerGas", "params": ["0x0"]}"#;
1066        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1067        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1068    }
1069
1070    #[test]
1071    fn test_serde_set_time() {
1072        let s = r#"{"method": "anvil_setTime", "params": ["0x0"]}"#;
1073        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1074        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1075
1076        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1077        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1078        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1079    }
1080
1081    #[test]
1082    fn test_serde_custom_dump_state() {
1083        let s = r#"{"method": "anvil_dumpState", "params": [true]}"#;
1084        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1085        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1086
1087        let s = r#"{"method": "anvil_dumpState"}"#;
1088        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1089        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1090        match req {
1091            EthRequest::DumpState(param) => {
1092                assert!(param.is_none());
1093            }
1094            _ => unreachable!(),
1095        }
1096    }
1097
1098    #[test]
1099    fn test_serde_custom_load_state() {
1100        let s = r#"{"method": "anvil_loadState", "params": ["0x0001"] }"#;
1101        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1102        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1103    }
1104
1105    #[test]
1106    fn test_serde_custom_snapshot() {
1107        let s = r#"{"method": "anvil_snapshot", "params": [] }"#;
1108        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1109        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1110
1111        let s = r#"{"method": "evm_snapshot", "params": [] }"#;
1112        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1113        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1114    }
1115
1116    #[test]
1117    fn test_serde_custom_revert() {
1118        let s = r#"{"method": "anvil_revert", "params": ["0x0"]}"#;
1119        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1120        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1121    }
1122
1123    #[test]
1124    fn test_serde_custom_increase_time() {
1125        let s = r#"{"method": "anvil_increaseTime", "params": ["0x0"]}"#;
1126        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1127        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1128
1129        let s = r#"{"method": "anvil_increaseTime", "params": [1]}"#;
1130        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1131        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1132
1133        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1134        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1135        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1136
1137        let s = r#"{"method": "evm_increaseTime", "params": ["0x0"]}"#;
1138        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1139        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1140
1141        let s = r#"{"method": "evm_increaseTime", "params": [1]}"#;
1142        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1143        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1144
1145        let s = r#"{"method": "evm_increaseTime", "params": 1}"#;
1146        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1147        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1148    }
1149
1150    #[test]
1151    fn test_serde_custom_next_timestamp() {
1152        let s = r#"{"method": "anvil_setNextBlockTimestamp", "params": [100]}"#;
1153        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1154        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1155        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": [100]}"#;
1156        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1157        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1158        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": ["0x64e0f308"]}"#;
1159        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1160        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1161    }
1162
1163    #[test]
1164    fn test_serde_custom_timestamp_interval() {
1165        let s = r#"{"method": "anvil_setBlockTimestampInterval", "params": [100]}"#;
1166        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1167        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1168    }
1169
1170    #[test]
1171    fn test_serde_custom_remove_timestamp_interval() {
1172        let s = r#"{"method": "anvil_removeBlockTimestampInterval", "params": []}"#;
1173        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1174        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1175    }
1176
1177    #[test]
1178    fn test_serde_custom_evm_mine() {
1179        let s = r#"{"method": "evm_mine", "params": [100]}"#;
1180        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1181        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1182        let s = r#"{"method": "evm_mine", "params": [{
1183            "timestamp": 100,
1184            "blocks": 100
1185        }]}"#;
1186        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1187        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1188        match req {
1189            EthRequest::EvmMine(params) => {
1190                assert_eq!(
1191                    params.unwrap().params.unwrap_or_default(),
1192                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1193                )
1194            }
1195            _ => unreachable!(),
1196        }
1197
1198        let s = r#"{"method": "evm_mine"}"#;
1199        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1200        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1201
1202        match req {
1203            EthRequest::EvmMine(params) => {
1204                assert!(params.is_none())
1205            }
1206            _ => unreachable!(),
1207        }
1208
1209        let s = r#"{"method": "evm_mine", "params": []}"#;
1210        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1211        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1212    }
1213
1214    #[test]
1215    fn test_serde_custom_evm_mine_detailed() {
1216        let s = r#"{"method": "anvil_mine_detailed", "params": [100]}"#;
1217        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1218        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1219        let s = r#"{"method": "anvil_mine_detailed", "params": [{
1220            "timestamp": 100,
1221            "blocks": 100
1222        }]}"#;
1223        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1224        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1225        match req {
1226            EthRequest::EvmMineDetailed(params) => {
1227                assert_eq!(
1228                    params.unwrap().params.unwrap_or_default(),
1229                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1230                )
1231            }
1232            _ => unreachable!(),
1233        }
1234
1235        let s = r#"{"method": "evm_mine_detailed"}"#;
1236        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1237        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1238
1239        match req {
1240            EthRequest::EvmMineDetailed(params) => {
1241                assert!(params.is_none())
1242            }
1243            _ => unreachable!(),
1244        }
1245
1246        let s = r#"{"method": "anvil_mine_detailed", "params": []}"#;
1247        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1248        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1249    }
1250
1251    #[test]
1252    fn test_serde_custom_evm_mine_hex() {
1253        let s = r#"{"method": "evm_mine", "params": ["0x63b6ff08"]}"#;
1254        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1255        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1256        match req {
1257            EthRequest::EvmMine(params) => {
1258                assert_eq!(
1259                    params.unwrap().params.unwrap_or_default(),
1260                    MineOptions::Timestamp(Some(1672937224))
1261                )
1262            }
1263            _ => unreachable!(),
1264        }
1265
1266        let s = r#"{"method": "evm_mine", "params": [{"timestamp": "0x63b6ff08"}]}"#;
1267        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1268        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1269        match req {
1270            EthRequest::EvmMine(params) => {
1271                assert_eq!(
1272                    params.unwrap().params.unwrap_or_default(),
1273                    MineOptions::Options { timestamp: Some(1672937224), blocks: None }
1274                )
1275            }
1276            _ => unreachable!(),
1277        }
1278    }
1279
1280    #[test]
1281    fn test_eth_uncle_count_by_block_hash() {
1282        let s = r#"{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1283        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1284        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1285    }
1286
1287    #[test]
1288    fn test_eth_block_tx_count_by_block_hash() {
1289        let s = r#"{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1290        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1291        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1292    }
1293
1294    #[test]
1295    fn test_eth_get_logs() {
1296        let s = r#"{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}"#;
1297        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1298        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1299    }
1300
1301    #[test]
1302    fn test_eth_new_filter() {
1303        let s = r#"{"method": "eth_newFilter", "params": [{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":73}"#;
1304        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1305        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1306    }
1307
1308    #[test]
1309    fn test_serde_eth_unsubscribe() {
1310        let s = r#"{"id": 1, "method": "eth_unsubscribe", "params":
1311["0x9cef478923ff08bf67fde6c64013158d"]}"#;
1312        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1313        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1314    }
1315
1316    #[test]
1317    fn test_serde_eth_subscribe() {
1318        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}"#;
1319        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1320        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1321
1322        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["logs", {"address":
1323"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics":
1324["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}"#;
1325        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1326        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1327
1328        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}"#;
1329        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1330        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1331
1332        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["syncing"]}"#;
1333        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1334        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1335    }
1336
1337    #[test]
1338    fn test_serde_debug_raw_transaction() {
1339        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransaction","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1340        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1341        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1342
1343        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByHash","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1344        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1345        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1346
1347        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockHashAndIndex","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c",1],"id":1}"#;
1348        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1349        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1350
1351        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockNumberAndIndex","params":["0x3ed3a89b",0],"id":1}"#;
1352        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1353        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1354    }
1355
1356    #[test]
1357    fn test_serde_debug_trace_transaction() {
1358        let s = r#"{"method": "debug_traceTransaction", "params":
1359["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1360        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1361        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1362
1363        let s = r#"{"method": "debug_traceTransaction", "params":
1364["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {}]}"#;
1365        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1366        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1367
1368        let s = r#"{"method": "debug_traceTransaction", "params":
1369["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"disableStorage":
1370true}]}"#;
1371        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1372        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1373    }
1374
1375    #[test]
1376    fn test_serde_debug_trace_call() {
1377        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
1378        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1379        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1380
1381        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
1382        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1383        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1384
1385        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
1386        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1387        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1388
1389        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
1390        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1391        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1392
1393        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }, {"disableStorage": true}]}"#;
1394        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1395        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1396    }
1397
1398    #[test]
1399    fn test_serde_eth_storage() {
1400        let s = r#"{"method": "eth_getStorageAt", "params":
1401["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"]}"#;
1402        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1403        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1404    }
1405
1406    #[test]
1407    fn test_eth_call() {
1408        let req = r#"{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}"#;
1409        let _req = serde_json::from_str::<TransactionRequest>(req).unwrap();
1410
1411        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"},"latest"]}"#;
1412        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1413
1414        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
1415        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1416
1417        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
1418        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1419
1420        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
1421        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1422
1423        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
1424        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1425    }
1426
1427    #[test]
1428    fn test_serde_eth_balance() {
1429        let s = r#"{"method": "eth_getBalance", "params":
1430["0x295a70b2de5e3953354a6a8344e616ed314d7251", "latest"]}"#;
1431        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1432
1433        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1434    }
1435
1436    #[test]
1437    fn test_serde_eth_block_by_number() {
1438        let s = r#"{"method": "eth_getBlockByNumber", "params": ["0x0", true]}"#;
1439        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1440        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1441        let s = r#"{"method": "eth_getBlockByNumber", "params": ["latest", true]}"#;
1442        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1443        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1444        let s = r#"{"method": "eth_getBlockByNumber", "params": ["earliest", true]}"#;
1445        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1446        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1447        let s = r#"{"method": "eth_getBlockByNumber", "params": ["pending", true]}"#;
1448        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1449        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1450
1451        // this case deviates from the spec, but we're supporting this for legacy reasons: <https://github.com/foundry-rs/foundry/issues/1868>
1452        let s = r#"{"method": "eth_getBlockByNumber", "params": [0, true]}"#;
1453        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1454        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1455    }
1456
1457    #[test]
1458    fn test_eth_sign() {
1459        let s = r#"{"method": "eth_sign", "params":
1460["0xd84de507f3fada7df80908082d3239466db55a71", "0x00"]}"#;
1461        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1462        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1463        let s = r#"{"method": "personal_sign", "params":
1464["0x00", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1465        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1466        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1467    }
1468
1469    #[test]
1470    fn test_eth_sign_typed_data() {
1471        let s = r#"{"method":"eth_signTypedData_v4","params":["0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", {"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":1,"verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","wallet":"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},"contents":"Hello, Bob!"}}]}"#;
1472        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1473        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1474    }
1475
1476    #[test]
1477    fn test_remove_pool_transactions() {
1478        let s = r#"{"method": "anvil_removePoolTransactions",  "params":["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
1479        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1480        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1481    }
1482
1483    #[test]
1484    fn test_serde_anvil_reorg() {
1485        // TransactionData::JSON
1486        let s = r#"
1487        {
1488            "method": "anvil_reorg",
1489            "params": [
1490                5,
1491                [
1492                    [
1493                        {
1494                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1495                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1496                            "value": 100
1497                        },
1498                        1
1499                    ],
1500                    [
1501                        {
1502                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1503                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1504                            "value": 200
1505                        },
1506                        2
1507                    ]
1508                ]
1509            ]
1510        }
1511        "#;
1512        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1513        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1514        // TransactionData::Raw
1515        let s = r#"
1516        {
1517            "method": "anvil_reorg",
1518            "params": [
1519                5,
1520                [
1521                    [
1522                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
1523                        1
1524                    ]
1525                ]
1526            ]
1527        }
1528        "#;
1529        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1530        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1531        // TransactionData::Raw and TransactionData::JSON
1532        let s = r#"
1533        {
1534            "method": "anvil_reorg",
1535            "params": [
1536                5,
1537                [
1538                    [
1539                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
1540                        1
1541                    ],
1542                    [
1543                        {
1544                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1545                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1546                            "value": 200
1547                        },
1548                        2
1549                    ]
1550                ]
1551            ]
1552        }
1553        "#;
1554        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1555        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1556    }
1557}