Skip to main content

anvil_core/eth/
mod.rs

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