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