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, U64, U256,
4    map::{HashMap, HashSet},
5};
6use alloy_rpc_types::{
7    BlockId, BlockNumberOrTag as BlockNumber, BlockOverrides, Bundle, Filter, Index, StateContext,
8    anvil::{Forking, MineOptions},
9    erc4337::TransactionConditional,
10    pubsub::{Params as SubscriptionParams, SubscriptionKind},
11    request::TransactionRequest,
12    simulate::SimulatePayload,
13    state::StateOverride,
14    trace::{
15        filter::TraceFilter,
16        geth::{GethDebugTracingCallOptions, GethDebugTracingOptions},
17        parity::TraceType,
18    },
19};
20use alloy_rpc_types_mev::EthCallBundle;
21use alloy_serde::WithOtherFields;
22use foundry_common::serde_helpers::{
23    deserialize_number, deserialize_number_opt, deserialize_number_seq, deserialize_u64_seq,
24    deserialize_u64_seq_opt,
25};
26
27pub mod block;
28pub mod subscription;
29pub mod transaction;
30pub mod wallet;
31
32pub mod serde_helpers;
33use self::serde_helpers::*;
34
35/// Wrapper type that ensures the type is named `params`
36#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
37pub struct Params<T> {
38    #[serde(default)]
39    pub params: T,
40}
41
42/// Parameters accepted by `eth_getTransactionCount`.
43#[derive(Clone, Debug, serde::Deserialize)]
44#[serde(untagged)]
45pub enum TransactionCountParams {
46    /// Address only.
47    Address((Address,)),
48    /// Standard address and block query.
49    Standard((Address, Option<BlockId>)),
50    /// EIP-8130 address, block, and nonce-key query.
51    #[cfg(feature = "base")]
52    Eip8130((Address, Option<BlockId>, U256)),
53}
54
55impl TransactionCountParams {
56    /// Splits the request into address, block, and optional EIP-8130 nonce key.
57    pub const fn into_parts(self) -> (Address, Option<BlockId>, Option<U256>) {
58        match self {
59            Self::Address((address,)) => (address, None, None),
60            Self::Standard((address, block)) => (address, block, None),
61            #[cfg(feature = "base")]
62            Self::Eip8130((address, block, nonce_key)) => (address, block, Some(nonce_key)),
63        }
64    }
65}
66
67/// Represents ethereum JSON-RPC API
68#[derive(Clone, Debug, serde::Deserialize)]
69#[serde(tag = "method", content = "params")]
70#[allow(clippy::large_enum_variant)]
71pub enum EthRequest {
72    #[serde(rename = "web3_clientVersion", with = "empty_params")]
73    Web3ClientVersion(()),
74
75    #[serde(rename = "web3_sha3", with = "sequence")]
76    Web3Sha3(Bytes),
77
78    /// Returns the current Ethereum protocol version.
79    #[serde(rename = "eth_protocolVersion", with = "empty_params")]
80    EthProtocolVersion(()),
81
82    #[serde(rename = "eth_chainId", with = "empty_params")]
83    EthChainId(()),
84
85    #[serde(rename = "eth_networkId", alias = "net_version", with = "empty_params")]
86    EthNetworkId(()),
87
88    #[serde(rename = "net_listening", with = "empty_params")]
89    NetListening(()),
90
91    /// Returns the number of hashes per second with which the node is mining.
92    #[serde(rename = "eth_hashrate", with = "empty_params")]
93    EthHashrate(()),
94
95    #[serde(rename = "eth_gasPrice", with = "empty_params")]
96    EthGasPrice(()),
97
98    #[serde(rename = "eth_baseFee", with = "empty_params")]
99    EthBaseFee(()),
100
101    #[serde(rename = "eth_maxPriorityFeePerGas", with = "empty_params")]
102    EthMaxPriorityFeePerGas(()),
103
104    #[serde(rename = "eth_blobBaseFee", with = "empty_params")]
105    EthBlobBaseFee(()),
106
107    #[serde(rename = "eth_accounts", alias = "eth_requestAccounts", with = "empty_params")]
108    EthAccounts(()),
109
110    #[serde(rename = "eth_blockNumber", with = "empty_params")]
111    EthBlockNumber(()),
112
113    /// Returns the client coinbase address.
114    #[serde(rename = "eth_coinbase", with = "empty_params")]
115    EthCoinbase(()),
116
117    #[serde(rename = "eth_getBalance")]
118    EthGetBalance(Address, #[serde(default)] Option<BlockId>),
119
120    #[serde(rename = "eth_getAccount")]
121    EthGetAccount(Address, Option<BlockId>),
122
123    #[serde(rename = "eth_getAccountInfo")]
124    EthGetAccountInfo(Address, Option<BlockId>),
125
126    #[serde(rename = "eth_getStorageAt")]
127    EthGetStorageAt(Address, U256, #[serde(default)] Option<BlockId>),
128
129    /// Returns storage values for multiple accounts and slots in a single call.
130    #[serde(rename = "eth_getStorageValues")]
131    EthGetStorageValues(HashMap<Address, Vec<B256>>, #[serde(default)] Option<BlockId>),
132
133    #[serde(rename = "eth_getBlockByHash")]
134    EthGetBlockByHash(B256, bool),
135
136    #[serde(rename = "eth_getHeaderByHash", with = "sequence")]
137    EthGetHeaderByHash(B256),
138
139    #[serde(rename = "eth_getBlockByNumber")]
140    EthGetBlockByNumber(
141        #[serde(deserialize_with = "lenient_block_number::lenient_block_number")] BlockNumber,
142        bool,
143    ),
144
145    #[serde(
146        rename = "eth_getHeaderByNumber",
147        deserialize_with = "lenient_block_number::lenient_block_number_seq"
148    )]
149    EthGetHeaderByNumber(BlockNumber),
150
151    #[serde(rename = "eth_getBlockAccessList", with = "sequence")]
152    EthGetBlockAccessList(BlockId),
153
154    #[serde(rename = "eth_getBlockAccessListByBlockHash", with = "sequence")]
155    EthGetBlockAccessListByBlockHash(B256),
156
157    #[serde(
158        rename = "eth_getBlockAccessListByBlockNumber",
159        deserialize_with = "lenient_block_number::lenient_block_number_seq"
160    )]
161    EthGetBlockAccessListByBlockNumber(BlockNumber),
162
163    #[serde(rename = "eth_getBlockAccessListRaw", with = "sequence")]
164    EthGetBlockAccessListRaw(BlockId),
165
166    #[serde(rename = "eth_getTransactionCount")]
167    EthGetTransactionCount(TransactionCountParams),
168
169    #[serde(rename = "eth_getBlockTransactionCountByHash", with = "sequence")]
170    EthGetTransactionCountByHash(B256),
171
172    #[serde(
173        rename = "eth_getBlockTransactionCountByNumber",
174        deserialize_with = "lenient_block_number::lenient_block_number_seq"
175    )]
176    EthGetTransactionCountByNumber(BlockNumber),
177
178    #[serde(rename = "eth_getUncleCountByBlockHash", with = "sequence")]
179    EthGetUnclesCountByHash(B256),
180
181    #[serde(
182        rename = "eth_getUncleCountByBlockNumber",
183        deserialize_with = "lenient_block_number::lenient_block_number_seq"
184    )]
185    EthGetUnclesCountByNumber(BlockNumber),
186
187    #[serde(rename = "eth_getCode")]
188    EthGetCodeAt(Address, #[serde(default)] Option<BlockId>),
189
190    /// Returns the account and storage values of the specified account including the Merkle-proof.
191    /// This call can be used to verify that the data you are pulling from is not tampered with.
192    #[serde(rename = "eth_getProof")]
193    EthGetProof(Address, Vec<B256>, #[serde(default)] Option<BlockId>),
194
195    /// The sign method calculates an Ethereum specific signature with:
196    #[serde(rename = "eth_sign")]
197    EthSign(Address, Bytes),
198
199    /// The sign method calculates an Ethereum specific signature, equivalent to eth_sign:
200    /// <https://docs.metamask.io/wallet/reference/personal_sign/>
201    #[serde(rename = "personal_sign")]
202    PersonalSign(Bytes, Address),
203
204    #[serde(rename = "eth_signTransaction", with = "sequence")]
205    EthSignTransaction(Box<WithOtherFields<TransactionRequest>>),
206
207    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
208    #[serde(rename = "eth_signTypedData")]
209    EthSignTypedData(Address, serde_json::Value),
210
211    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
212    #[serde(rename = "eth_signTypedData_v3")]
213    EthSignTypedDataV3(Address, serde_json::Value),
214
215    /// 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.
216    #[serde(rename = "eth_signTypedData_v4")]
217    EthSignTypedDataV4(Address, alloy_dyn_abi::TypedData),
218
219    #[serde(rename = "eth_sendTransaction", with = "sequence")]
220    EthSendTransaction(Box<WithOtherFields<TransactionRequest>>),
221
222    #[serde(rename = "eth_resend")]
223    EthResend(Box<WithOtherFields<TransactionRequest>>, Option<U256>, Option<U64>),
224
225    #[serde(rename = "eth_sendTransactionSync", with = "sequence")]
226    EthSendTransactionSync(Box<WithOtherFields<TransactionRequest>>),
227
228    #[serde(rename = "eth_sendRawTransaction", with = "sequence")]
229    EthSendRawTransaction(Bytes),
230
231    #[serde(rename = "eth_sendRawTransactionSync")]
232    EthSendRawTransactionSync(Bytes, #[serde(default)] Option<u64>),
233
234    #[serde(rename = "eth_sendRawTransactionConditional")]
235    EthSendRawTransactionConditional(Bytes, TransactionConditional),
236
237    /// Signs a raw Tempo transaction as the node's fee payer (sponsor) without broadcasting it.
238    #[serde(rename = "eth_signRawTransaction", with = "sequence")]
239    EthSignRawTransaction(Bytes),
240
241    #[serde(rename = "anvil_classifyTransaction", with = "sequence")]
242    AnvilClassifyTransaction(Bytes),
243
244    #[serde(rename = "eth_call")]
245    EthCall(
246        WithOtherFields<TransactionRequest>,
247        #[serde(default)] Option<BlockId>,
248        #[serde(default)] Option<StateOverride>,
249        #[serde(default)] Option<Box<BlockOverrides>>,
250    ),
251
252    #[serde(rename = "eth_callMany")]
253    EthCallMany(
254        Vec<Bundle<WithOtherFields<TransactionRequest>>>,
255        #[serde(default)] Option<StateContext>,
256        #[serde(default)] Option<StateOverride>,
257    ),
258
259    #[serde(rename = "eth_callBundle", with = "sequence")]
260    EthCallBundle(EthCallBundle),
261
262    #[serde(rename = "eth_simulateV1")]
263    EthSimulateV1(
264        SimulatePayload<WithOtherFields<TransactionRequest>>,
265        #[serde(default)] Option<BlockId>,
266    ),
267
268    #[serde(rename = "eth_createAccessList")]
269    EthCreateAccessList(
270        WithOtherFields<TransactionRequest>,
271        #[serde(default)] Option<BlockId>,
272        #[serde(default)] Option<StateOverride>,
273    ),
274
275    #[serde(rename = "eth_estimateGas")]
276    EthEstimateGas(
277        WithOtherFields<TransactionRequest>,
278        #[serde(default)] Option<BlockId>,
279        #[serde(default)] Option<StateOverride>,
280        #[serde(default)] Option<Box<BlockOverrides>>,
281    ),
282
283    #[serde(rename = "eth_fillTransaction", with = "sequence")]
284    EthFillTransaction(WithOtherFields<TransactionRequest>),
285
286    #[serde(rename = "eth_getTransactionByHash", with = "sequence")]
287    EthGetTransactionByHash(TxHash),
288
289    #[serde(rename = "eth_pendingTransactions", with = "empty_params")]
290    EthPendingTransactions(()),
291
292    /// Returns the blob for a given blob versioned hash.
293    #[serde(rename = "anvil_getBlobByHash", with = "sequence")]
294    GetBlobByHash(B256),
295
296    /// Returns the blobs for a given transaction hash.
297    #[serde(rename = "anvil_getBlobsByTransactionHash", with = "sequence")]
298    GetBlobByTransactionHash(TxHash),
299
300    /// Returns the genesis time for the chain
301    #[serde(rename = "anvil_getGenesisTime", with = "empty_params")]
302    GetGenesisTime(()),
303
304    /// Returns the UNIX wall time in milliseconds when the current head was installed.
305    #[serde(rename = "anvil_getLastBlockWallTime", with = "empty_params")]
306    GetLastBlockWallTime(()),
307
308    #[serde(rename = "eth_getTransactionByBlockHashAndIndex")]
309    EthGetTransactionByBlockHashAndIndex(B256, Index),
310
311    #[serde(rename = "eth_getTransactionByBlockNumberAndIndex")]
312    EthGetTransactionByBlockNumberAndIndex(BlockNumber, Index),
313
314    #[serde(rename = "eth_getRawTransactionByHash", with = "sequence")]
315    EthGetRawTransactionByHash(TxHash),
316
317    #[serde(rename = "eth_getRawTransactionByBlockHashAndIndex")]
318    EthGetRawTransactionByBlockHashAndIndex(B256, Index),
319
320    #[serde(rename = "eth_getRawTransactionByBlockNumberAndIndex")]
321    EthGetRawTransactionByBlockNumberAndIndex(BlockNumber, Index),
322
323    #[serde(rename = "eth_getTransactionReceipt", with = "sequence")]
324    EthGetTransactionReceipt(B256),
325
326    #[serde(rename = "eth_getBlockReceipts", with = "sequence")]
327    EthGetBlockReceipts(BlockId),
328
329    #[serde(rename = "eth_getUncleByBlockHashAndIndex")]
330    EthGetUncleByBlockHashAndIndex(B256, Index),
331
332    #[serde(rename = "eth_getUncleByBlockNumberAndIndex")]
333    EthGetUncleByBlockNumberAndIndex(
334        #[serde(deserialize_with = "lenient_block_number::lenient_block_number")] BlockNumber,
335        Index,
336    ),
337
338    #[serde(rename = "eth_getLogs", with = "sequence")]
339    EthGetLogs(Filter),
340
341    /// Creates a filter object, based on filter options, to notify when the state changes (logs).
342    #[serde(rename = "eth_newFilter", with = "sequence")]
343    EthNewFilter(Filter),
344
345    /// Polling method for a filter, which returns an array of logs which occurred since last poll.
346    #[serde(rename = "eth_getFilterChanges", with = "sequence")]
347    EthGetFilterChanges(String),
348
349    /// Creates a filter in the node, to notify when a new block arrives.
350    /// To check if the state has changed, call `eth_getFilterChanges`.
351    #[serde(rename = "eth_newBlockFilter", with = "empty_params")]
352    EthNewBlockFilter(()),
353
354    /// Creates a filter in the node, to notify when new pending transactions arrive.
355    /// To check if the state has changed, call `eth_getFilterChanges`.
356    #[serde(rename = "eth_newPendingTransactionFilter", with = "optional_sequence")]
357    EthNewPendingTransactionFilter(Option<bool>),
358
359    /// Returns an array of all logs matching filter with given id.
360    #[serde(rename = "eth_getFilterLogs", with = "sequence")]
361    EthGetFilterLogs(String),
362
363    /// Removes the filter, returns true if the filter was installed
364    #[serde(rename = "eth_uninstallFilter", with = "sequence")]
365    EthUninstallFilter(String),
366
367    #[serde(rename = "eth_getWork", with = "empty_params")]
368    EthGetWork(()),
369
370    #[serde(rename = "eth_submitWork")]
371    EthSubmitWork(B64, B256, B256),
372
373    #[serde(rename = "eth_submitHashrate")]
374    EthSubmitHashRate(U256, B256),
375
376    #[serde(rename = "eth_feeHistory")]
377    EthFeeHistory(
378        #[serde(deserialize_with = "deserialize_number")] U256,
379        BlockNumber,
380        #[serde(default)] Vec<f64>,
381    ),
382
383    #[serde(rename = "eth_syncing", with = "empty_params")]
384    EthSyncing(()),
385
386    #[serde(rename = "eth_config", with = "empty_params")]
387    EthConfig(()),
388
389    /// geth's `debug_getRawTransaction`  endpoint
390    #[serde(rename = "debug_getRawTransaction", with = "sequence")]
391    DebugGetRawTransaction(TxHash),
392
393    /// reth's `debug_getRawReceipts` endpoint.
394    #[serde(rename = "debug_getRawReceipts", with = "sequence")]
395    DebugGetRawReceipts(BlockId),
396
397    /// reth's `debug_getRawTransactions` endpoint.
398    #[serde(rename = "debug_getRawTransactions", with = "sequence")]
399    DebugGetRawTransactions(BlockId),
400
401    /// geth's `debug_getRawHeader` endpoint.
402    #[serde(rename = "debug_getRawHeader", with = "sequence")]
403    DebugGetRawHeader(BlockId),
404
405    /// geth's `debug_getRawBlock` endpoint.
406    #[serde(rename = "debug_getRawBlock", with = "sequence")]
407    DebugGetRawBlock(BlockId),
408
409    /// geth's `debug_clearTxpool` endpoint
410    #[serde(rename = "debug_clearTxpool", with = "empty_params")]
411    DebugClearTxpool(()),
412
413    /// geth's `debug_traceTransaction`  endpoint
414    #[serde(rename = "debug_traceTransaction")]
415    DebugTraceTransaction(B256, #[serde(default)] GethDebugTracingOptions),
416
417    /// geth's `debug_traceCall`  endpoint
418    #[serde(rename = "debug_traceCall")]
419    DebugTraceCall(
420        WithOtherFields<TransactionRequest>,
421        #[serde(default)] Option<BlockId>,
422        #[serde(default)] GethDebugTracingCallOptions,
423    ),
424
425    /// reth's `debug_codeByHash` endpoint
426    #[serde(rename = "debug_codeByHash")]
427    DebugCodeByHash(B256, #[serde(default)] Option<BlockId>),
428
429    /// reth's `debug_dbGet` endpoint
430    #[serde(rename = "debug_dbGet")]
431    DebugDbGet(String),
432
433    /// reth's `debug_getModifiedAccountsByNumber` endpoint.
434    #[serde(rename = "debug_getModifiedAccountsByNumber")]
435    DebugGetModifiedAccountsByNumber(u64, u64),
436
437    /// reth's `debug_freeOSMemory` endpoint.
438    #[serde(rename = "debug_freeOSMemory", with = "empty_params")]
439    DebugFreeOsMemory(()),
440
441    /// reth's `debug_accountInfoAt` endpoint.
442    #[serde(rename = "debug_accountInfoAt")]
443    DebugAccountInfoAt(BlockId, Index, Address),
444
445    /// reth's `debug_executionWitness` endpoint.
446    #[serde(rename = "debug_executionWitness", with = "sequence")]
447    DebugExecutionWitness(BlockNumber),
448
449    /// geth's `debug_traceBlock` endpoint.
450    #[serde(rename = "debug_traceBlock")]
451    DebugTraceBlock(Bytes, #[serde(default)] GethDebugTracingOptions),
452
453    /// geth's `debug_traceBlockByHash` endpoint
454    #[serde(rename = "debug_traceBlockByHash")]
455    DebugTraceBlockByHash(B256, #[serde(default)] GethDebugTracingOptions),
456
457    /// geth's `debug_traceBlockByNumber` endpoint
458    #[serde(rename = "debug_traceBlockByNumber")]
459    DebugTraceBlockByNumber(BlockNumber, #[serde(default)] GethDebugTracingOptions),
460
461    /// Trace call endpoint for parity's `trace_call`.
462    #[serde(rename = "trace_call")]
463    TraceCall(
464        WithOtherFields<TransactionRequest>,
465        #[serde(default)] HashSet<TraceType>,
466        #[serde(default)] Option<BlockId>,
467    ),
468
469    /// Trace transaction endpoint for parity's `trace_transaction`
470    #[serde(rename = "trace_transaction", with = "sequence")]
471    TraceTransaction(B256),
472
473    /// Trace transaction endpoint for parity's `trace_block`
474    #[serde(
475        rename = "trace_block",
476        deserialize_with = "lenient_block_number::lenient_block_number_seq"
477    )]
478    TraceBlock(BlockNumber),
479
480    // Return filtered traces over blocks
481    #[serde(rename = "trace_filter", with = "sequence")]
482    TraceFilter(TraceFilter),
483
484    /// Trace get endpoint for parity's `trace_get`.
485    #[serde(rename = "trace_get")]
486    TraceGet(B256, #[serde(deserialize_with = "trace_address::deserialize")] Vec<Index>),
487
488    /// Trace transaction endpoint for parity's `trace_replayBlockTransactions`
489    #[serde(rename = "trace_replayBlockTransactions")]
490    TraceReplayBlockTransactions(
491        #[serde(deserialize_with = "lenient_block_number::lenient_block_number")] BlockNumber,
492        HashSet<TraceType>,
493    ),
494
495    /// Trace transaction endpoint for parity's `trace_replayTransaction`.
496    #[serde(rename = "trace_replayTransaction")]
497    TraceReplayTransaction(B256, HashSet<TraceType>),
498
499    /// Opcode gas trace endpoint for reth's `trace_transactionOpcodeGas`.
500    #[serde(rename = "trace_transactionOpcodeGas", with = "sequence")]
501    TraceTransactionOpcodeGas(B256),
502
503    /// Opcode gas trace endpoint for reth's `trace_blockOpcodeGas`.
504    #[serde(rename = "trace_blockOpcodeGas", with = "sequence")]
505    TraceBlockOpcodeGas(BlockId),
506
507    /// Trace raw transaction endpoint for parity's `trace_rawTransaction`.
508    #[serde(rename = "trace_rawTransaction")]
509    TraceRawTransaction(Bytes, HashSet<TraceType>, #[serde(default)] Option<BlockId>),
510
511    /// Trace call list endpoint for parity's `trace_callMany`.
512    #[serde(rename = "trace_callMany")]
513    TraceCallMany(
514        Vec<(WithOtherFields<TransactionRequest>, HashSet<TraceType>)>,
515        #[serde(default)] Option<BlockId>,
516    ),
517
518    // Custom endpoints, they're not extracted to a separate type out of serde convenience
519    /// send transactions impersonating specific account and contract addresses.
520    #[serde(
521        rename = "anvil_impersonateAccount",
522        alias = "hardhat_impersonateAccount",
523        with = "sequence"
524    )]
525    ImpersonateAccount(Address),
526    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`
527    #[serde(
528        rename = "anvil_stopImpersonatingAccount",
529        alias = "hardhat_stopImpersonatingAccount",
530        with = "sequence"
531    )]
532    StopImpersonatingAccount(Address),
533    /// Will make every account impersonated
534    #[serde(
535        rename = "anvil_autoImpersonateAccount",
536        alias = "hardhat_autoImpersonateAccount",
537        with = "sequence"
538    )]
539    AutoImpersonateAccount(bool),
540
541    /// Registers a signature/address pair for faking `ecrecover` results
542    #[serde(rename = "anvil_impersonateSignature", with = "sequence")]
543    ImpersonateSignature(Bytes, Address),
544
545    /// Returns true if automatic mining is enabled, and false.
546    #[serde(rename = "anvil_getAutomine", alias = "hardhat_getAutomine", with = "empty_params")]
547    GetAutoMine(()),
548    /// Mines a series of blocks
549    #[serde(rename = "anvil_mine", alias = "hardhat_mine")]
550    Mine(
551        /// Number of blocks to mine, if not set `1` block is mined
552        #[serde(default, deserialize_with = "deserialize_number_opt")]
553        Option<U256>,
554        /// The time interval between each block in seconds, defaults to `1` seconds
555        /// The interval is applied only to blocks mined in the given method invocation, not to
556        /// blocks mined afterwards. Set this to `0` to instantly mine _all_ blocks
557        #[serde(default, deserialize_with = "deserialize_number_opt")]
558        Option<U256>,
559    ),
560
561    /// Enables or disables, based on the single boolean argument, the automatic mining of new
562    /// blocks with each new transaction submitted to the network.
563    #[serde(rename = "anvil_setAutomine", alias = "evm_setAutomine", with = "sequence")]
564    SetAutomine(bool),
565
566    /// Sets the mining behavior to interval with the given interval (seconds)
567    #[serde(
568        rename = "anvil_setIntervalMining",
569        alias = "evm_setIntervalMining",
570        deserialize_with = "deserialize_u64_seq"
571    )]
572    SetIntervalMining(u64),
573
574    /// Gets the current mining behavior
575    #[serde(rename = "anvil_getIntervalMining", with = "empty_params")]
576    GetIntervalMining(()),
577
578    /// Removes transactions from the pool
579    #[serde(rename = "anvil_dropTransaction", alias = "hardhat_dropTransaction", with = "sequence")]
580    DropTransaction(B256),
581
582    /// Removes transactions from the pool
583    #[serde(
584        rename = "anvil_dropAllTransactions",
585        alias = "hardhat_dropAllTransactions",
586        with = "empty_params"
587    )]
588    DropAllTransactions(),
589
590    /// Reset the fork to a fresh forked state, and optionally update the fork config
591    #[serde(rename = "anvil_reset", alias = "hardhat_reset")]
592    Reset(#[serde(default)] Option<Params<Option<Forking>>>),
593
594    /// Sets the backend rpc url
595    #[serde(rename = "anvil_setRpcUrl", with = "sequence")]
596    SetRpcUrl(String),
597
598    /// Modifies the balance of an account.
599    #[serde(
600        rename = "anvil_setBalance",
601        alias = "hardhat_setBalance",
602        alias = "tenderly_setBalance"
603    )]
604    SetBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
605
606    /// Increases the balance of an account.
607    #[serde(
608        rename = "anvil_addBalance",
609        alias = "hardhat_addBalance",
610        alias = "tenderly_addBalance"
611    )]
612    AddBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
613
614    /// Modifies the ERC20 balance of an account.
615    #[serde(
616        rename = "anvil_dealERC20",
617        alias = "hardhat_dealERC20",
618        alias = "anvil_setERC20Balance"
619    )]
620    DealERC20(Address, Address, #[serde(deserialize_with = "deserialize_number")] U256),
621
622    /// Modifies the TIP-20 balance of an account.
623    #[serde(rename = "anvil_dealTIP20")]
624    DealTIP20(Address, Address, #[serde(deserialize_with = "deserialize_number")] U256),
625
626    /// Sets the ERC20 allowance for a spender
627    #[serde(rename = "anvil_setERC20Allowance")]
628    SetERC20Allowance(
629        Address,
630        Address,
631        Address,
632        #[serde(deserialize_with = "deserialize_number")] U256,
633    ),
634
635    /// Sets the code of a contract
636    #[serde(rename = "anvil_setCode", alias = "hardhat_setCode")]
637    SetCode(Address, Bytes),
638
639    /// Sets the nonce of an address
640    #[serde(rename = "anvil_setNonce", alias = "hardhat_setNonce", alias = "evm_setAccountNonce")]
641    SetNonce(Address, #[serde(deserialize_with = "deserialize_number")] U256),
642
643    /// Writes a single slot of the account's storage
644    #[serde(rename = "anvil_setStorageAt", alias = "hardhat_setStorageAt")]
645    SetStorageAt(
646        Address,
647        /// slot
648        U256,
649        /// value
650        B256,
651    ),
652
653    /// Sets the coinbase address
654    #[serde(rename = "anvil_setCoinbase", alias = "hardhat_setCoinbase", with = "sequence")]
655    SetCoinbase(Address),
656
657    /// Sets the `prevrandao` value of the next block
658    #[serde(rename = "anvil_setNextBlockPrevRandao", with = "sequence")]
659    SetNextBlockPrevRandao(B256),
660
661    /// Sets the parent beacon block root of the next block
662    #[serde(rename = "anvil_setNextBlockParentBeaconBlockRoot", with = "sequence")]
663    SetNextBlockParentBeaconBlockRoot(B256),
664
665    /// Sets the chain id
666    #[serde(rename = "anvil_setChainId", deserialize_with = "deserialize_u64_seq")]
667    SetChainId(u64),
668
669    /// Enable or disable logging
670    #[serde(
671        rename = "anvil_setLoggingEnabled",
672        alias = "hardhat_setLoggingEnabled",
673        with = "sequence"
674    )]
675    SetLogging(bool),
676
677    /// Set the minimum gas price for the node
678    #[serde(
679        rename = "anvil_setMinGasPrice",
680        alias = "hardhat_setMinGasPrice",
681        deserialize_with = "deserialize_number_seq"
682    )]
683    SetMinGasPrice(U256),
684
685    /// Sets the base fee of the next block
686    #[serde(
687        rename = "anvil_setNextBlockBaseFeePerGas",
688        alias = "hardhat_setNextBlockBaseFeePerGas",
689        deserialize_with = "deserialize_number_seq"
690    )]
691    SetNextBlockBaseFeePerGas(U256),
692
693    /// Sets the specific timestamp
694    /// Accepts timestamp (Unix epoch) with millisecond precision and returns the number of seconds
695    /// between the given timestamp and the current time.
696    #[serde(
697        rename = "anvil_setTime",
698        alias = "evm_setTime",
699        deserialize_with = "deserialize_number_seq"
700    )]
701    EvmSetTime(U256),
702
703    /// Serializes the current state (including contracts code, contract's storage, accounts
704    /// properties, etc.) into a saveable data blob
705    #[serde(rename = "anvil_dumpState", alias = "hardhat_dumpState")]
706    DumpState(#[serde(default)] Option<Params<Option<bool>>>),
707
708    /// Adds state previously dumped with `DumpState` to the current chain
709    #[serde(rename = "anvil_loadState", alias = "hardhat_loadState", with = "sequence")]
710    LoadState(Bytes),
711
712    /// Retrieves the Anvil node configuration params
713    #[serde(rename = "anvil_nodeInfo", with = "empty_params")]
714    NodeInfo(()),
715
716    /// Retrieves the Anvil node metadata.
717    #[serde(rename = "anvil_metadata", alias = "hardhat_metadata", with = "empty_params")]
718    AnvilMetadata(()),
719
720    // Ganache compatible calls
721    /// Snapshot the state of the blockchain at the current block.
722    ///
723    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_snapshot>
724    #[serde(rename = "anvil_snapshot", alias = "evm_snapshot", with = "empty_params")]
725    EvmSnapshot(()),
726
727    /// Revert the state of the blockchain to a previous snapshot.
728    /// Takes a single parameter, which is the snapshot id to revert to.
729    ///
730    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_revert>
731    #[serde(
732        rename = "anvil_revert",
733        alias = "evm_revert",
734        deserialize_with = "deserialize_number_seq"
735    )]
736    EvmRevert(U256),
737
738    /// Jump forward in time by the given amount of time, in seconds.
739    #[serde(
740        rename = "anvil_increaseTime",
741        alias = "evm_increaseTime",
742        deserialize_with = "deserialize_number_seq"
743    )]
744    EvmIncreaseTime(U256),
745
746    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
747    #[serde(
748        rename = "anvil_setNextBlockTimestamp",
749        alias = "evm_setNextBlockTimestamp",
750        deserialize_with = "deserialize_number_seq"
751    )]
752    EvmSetNextBlockTimeStamp(U256),
753
754    /// Set the exact gas limit that you want in the next block
755    #[serde(
756        rename = "anvil_setBlockGasLimit",
757        alias = "evm_setBlockGasLimit",
758        deserialize_with = "deserialize_number_seq"
759    )]
760    EvmSetBlockGasLimit(U256),
761
762    /// Similar to `evm_increaseTime` but takes sets a block timestamp `interval`.
763    ///
764    /// The timestamp of the next block will be computed as `lastBlock_timestamp + interval`.
765    #[serde(rename = "anvil_setBlockTimestampInterval", deserialize_with = "deserialize_u64_seq")]
766    EvmSetBlockTimeStampInterval(u64),
767
768    /// Removes a `anvil_setBlockTimestampInterval` if it exists
769    #[serde(rename = "anvil_removeBlockTimestampInterval", with = "empty_params")]
770    EvmRemoveBlockTimeStampInterval(()),
771
772    /// Mine a single block
773    #[serde(rename = "evm_mine")]
774    EvmMine(#[serde(default)] Option<Params<Option<MineOptions>>>),
775
776    /// Mine a single block and return detailed data
777    ///
778    /// This behaves exactly as `EvmMine` but returns different output, for compatibility reasons
779    /// this is a separate call since `evm_mine` is not an anvil original.
780    #[serde(rename = "anvil_mine_detailed", alias = "evm_mine_detailed")]
781    EvmMineDetailed(#[serde(default)] Option<Params<Option<MineOptions>>>),
782
783    /// Execute a transaction regardless of signature status
784    #[serde(rename = "eth_sendUnsignedTransaction", with = "sequence")]
785    EthSendUnsignedTransaction(Box<WithOtherFields<TransactionRequest>>),
786
787    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
788    /// well as the ones that are being scheduled for future execution only.
789    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status>
790    #[serde(rename = "txpool_status", with = "empty_params")]
791    TxPoolStatus(()),
792
793    /// Returns a summary of all the transactions currently pending for inclusion in the next
794    /// block(s), as well as the ones that are being scheduled for future execution only.
795    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect>
796    #[serde(rename = "txpool_inspect", with = "empty_params")]
797    TxPoolInspect(()),
798
799    /// Returns the details of all transactions currently pending for inclusion in the next
800    /// block(s), as well as the ones that are being scheduled for future execution only.
801    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content>
802    #[serde(rename = "txpool_content", with = "empty_params")]
803    TxPoolContent(()),
804
805    /// Returns the details of all transactions currently pending for inclusion in the next
806    /// block(s), as well as the ones that are being scheduled for future execution only, filtered
807    /// by sender.
808    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom>
809    #[serde(rename = "txpool_contentFrom", with = "sequence")]
810    TxPoolContentFrom(Address),
811
812    /// Otterscan's `ots_getApiLevel` endpoint
813    /// Otterscan currently requires this endpoint, even though it's not part of the ots_*
814    /// <https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71>
815    /// Related upstream issue: <https://github.com/otterscan/otterscan/issues/1081>
816    #[serde(rename = "erigon_getHeaderByNumber")]
817    ErigonGetHeaderByNumber(
818        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq")] BlockNumber,
819    ),
820
821    /// Otterscan's `ots_getApiLevel` endpoint
822    /// Used as a simple API versioning scheme for the ots_* namespace
823    #[serde(rename = "ots_getApiLevel", with = "empty_params")]
824    OtsGetApiLevel(()),
825
826    /// Otterscan's `ots_getInternalOperations` endpoint
827    /// Traces internal ETH transfers, contracts creation (CREATE/CREATE2) and self-destructs for a
828    /// certain transaction.
829    #[serde(rename = "ots_getInternalOperations", with = "sequence")]
830    OtsGetInternalOperations(B256),
831
832    /// Otterscan's `ots_hasCode` endpoint
833    /// Check if an ETH address contains code at a certain block number.
834    #[serde(rename = "ots_hasCode")]
835    OtsHasCode(
836        Address,
837        #[serde(deserialize_with = "lenient_block_number::lenient_block_number", default)]
838        BlockNumber,
839    ),
840
841    /// Otterscan's `ots_traceTransaction` endpoint
842    /// Trace a transaction and generate a trace call tree.
843    #[serde(rename = "ots_traceTransaction", with = "sequence")]
844    OtsTraceTransaction(B256),
845
846    /// Otterscan's `ots_getTransactionError` endpoint
847    /// Given a transaction hash, returns its raw revert reason.
848    #[serde(rename = "ots_getTransactionError", with = "sequence")]
849    OtsGetTransactionError(B256),
850
851    /// Otterscan's `ots_getBlockDetails` endpoint
852    /// Given a block number, return its data. Similar to the standard eth_getBlockByNumber/Hash
853    /// method, but can be optimized by excluding unnecessary data such as transactions and
854    /// logBloom
855    #[serde(rename = "ots_getBlockDetails")]
856    OtsGetBlockDetails(
857        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq", default)]
858        BlockNumber,
859    ),
860
861    /// Otterscan's `ots_getBlockDetails` endpoint
862    /// Same as `ots_getBlockDetails`, but receiving a block hash instead of number
863    #[serde(rename = "ots_getBlockDetailsByHash", with = "sequence")]
864    OtsGetBlockDetailsByHash(B256),
865
866    /// Otterscan's `ots_getBlockTransactions` endpoint
867    /// Gets paginated transaction data for a certain block. Return data is similar to
868    /// eth_getBlockBy* + eth_getTransactionReceipt.
869    #[serde(rename = "ots_getBlockTransactions")]
870    OtsGetBlockTransactions(u64, usize, usize),
871
872    /// Otterscan's `ots_searchTransactionsBefore` endpoint
873    /// Address history navigation. searches backwards from certain point in time.
874    #[serde(rename = "ots_searchTransactionsBefore")]
875    OtsSearchTransactionsBefore(Address, u64, usize),
876
877    /// Otterscan's `ots_searchTransactionsAfter` endpoint
878    /// Address history navigation. searches forward from certain point in time.
879    #[serde(rename = "ots_searchTransactionsAfter")]
880    OtsSearchTransactionsAfter(Address, u64, usize),
881
882    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
883    /// Given a sender address and a nonce, returns the tx hash or null if not found. It returns
884    /// only the tx hash on success, you can use the standard eth_getTransactionByHash after that
885    /// to get the full transaction data.
886    #[serde(rename = "ots_getTransactionBySenderAndNonce")]
887    OtsGetTransactionBySenderAndNonce(
888        Address,
889        #[serde(deserialize_with = "deserialize_number")] U256,
890    ),
891
892    /// Returns the transaction by sender and nonce
893    /// Returns the full transaction data.
894    #[serde(rename = "eth_getTransactionBySenderAndNonce")]
895    EthGetTransactionBySenderAndNonce(
896        Address,
897        #[serde(deserialize_with = "deserialize_number")] U256,
898    ),
899
900    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
901    /// Given an ETH contract address, returns the tx hash and the direct address who created the
902    /// contract.
903    #[serde(rename = "ots_getContractCreator", with = "sequence")]
904    OtsGetContractCreator(Address),
905
906    /// Removes transactions from the pool by sender origin.
907    #[serde(rename = "anvil_removePoolTransactions", with = "sequence")]
908    RemovePoolTransactions(Address),
909
910    /// Reorg the chain
911    #[serde(rename = "anvil_reorg")]
912    Reorg(ReorgOptions),
913
914    /// Rollback the chain
915    #[serde(rename = "anvil_rollback", deserialize_with = "deserialize_u64_seq_opt")]
916    Rollback(Option<u64>),
917
918    /// Sets the fee token for a user (Tempo-only)
919    #[serde(rename = "anvil_setFeeToken")]
920    SetFeeToken(Address, Address),
921
922    /// Sets the fee token for a validator (Tempo-only)
923    #[serde(rename = "anvil_setValidatorFeeToken")]
924    SetValidatorFeeToken(Address, Address),
925
926    /// Mints FeeAMM liquidity for a token pair (Tempo-only)
927    #[serde(rename = "anvil_setFeeAmmLiquidity")]
928    SetFeeAmmLiquidity(
929        /// user_token
930        Address,
931        /// validator_token
932        Address,
933        /// amount
934        #[serde(deserialize_with = "deserialize_number")]
935        U256,
936    ),
937}
938
939/// Represents ethereum JSON-RPC API
940#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
941#[serde(tag = "method", content = "params")]
942pub enum EthPubSub {
943    /// Subscribe to an eth subscription
944    #[serde(rename = "eth_subscribe")]
945    EthSubscribe(SubscriptionKind, #[serde(default)] Box<SubscriptionParams>),
946
947    /// Unsubscribe from an eth subscription
948    #[serde(rename = "eth_unsubscribe", with = "sequence")]
949    EthUnSubscribe(SubscriptionId),
950}
951
952/// Container type for either a request or a pub sub
953#[derive(Clone, Debug)]
954pub enum EthRpcCall {
955    Request(Box<EthRequest>),
956    PubSub(EthPubSub),
957}
958
959impl<'de> serde::Deserialize<'de> for EthRpcCall {
960    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
961    where
962        D: serde::Deserializer<'de>,
963    {
964        let value = serde_json::Value::deserialize(deserializer)?;
965        match value.get("method").and_then(serde_json::Value::as_str) {
966            Some("eth_subscribe" | "eth_unsubscribe") => serde_json::from_value(value)
967                .map(Self::PubSub)
968                .map_err(<D::Error as serde::de::Error>::custom),
969            _ => serde_json::from_value(value)
970                .map(Box::new)
971                .map(Self::Request)
972                .map_err(<D::Error as serde::de::Error>::custom),
973        }
974    }
975}
976
977#[cfg(test)]
978mod tests {
979    use super::*;
980
981    #[test]
982    fn test_web3_client_version() {
983        let s = r#"{"method": "web3_clientVersion", "params":[]}"#;
984        let value: serde_json::Value = serde_json::from_str(s).unwrap();
985        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
986    }
987
988    #[test]
989    fn test_web3_sha3() {
990        let s = r#"{"method": "web3_sha3", "params":["0x68656c6c6f20776f726c64"]}"#;
991        let value: serde_json::Value = serde_json::from_str(s).unwrap();
992        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
993    }
994
995    #[test]
996    fn unknown_rpc_call_preserves_method_error() {
997        let err = serde_json::from_str::<EthRpcCall>(r#"{"method":"no_such_method","params":[]}"#)
998            .unwrap_err();
999
1000        assert!(err.to_string().contains("unknown variant"));
1001    }
1002
1003    #[test]
1004    fn test_eth_accounts() {
1005        let s = r#"{"method": "eth_accounts", "params":[]}"#;
1006        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1007        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1008    }
1009
1010    #[test]
1011    fn test_eth_network_id() {
1012        let s = r#"{"method": "eth_networkId", "params":[]}"#;
1013        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1014        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1015    }
1016
1017    #[test]
1018    fn test_eth_get_proof() {
1019        let s = r#"{"method":"eth_getProof","params":["0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842",["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"],"latest"]}"#;
1020        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1021        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1022    }
1023
1024    #[test]
1025    fn test_eth_chain_id() {
1026        let s = r#"{"method": "eth_chainId", "params":[]}"#;
1027        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1028        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1029    }
1030
1031    #[test]
1032    fn test_net_listening() {
1033        let s = r#"{"method": "net_listening", "params":[]}"#;
1034        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1035        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1036    }
1037
1038    #[test]
1039    fn test_eth_block_number() {
1040        let s = r#"{"method": "eth_blockNumber", "params":[]}"#;
1041        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1042        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1043    }
1044
1045    #[test]
1046    fn test_eth_pending_transactions() {
1047        let s = r#"{"method": "eth_pendingTransactions", "params":[]}"#;
1048        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1049        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1050    }
1051
1052    #[test]
1053    fn test_eth_create_access_list_with_state_override() {
1054        let s = r#"{"method":"eth_createAccessList","params":[{"to":"0x0000000000000000000000000000000000000001"},"latest",{"0x0000000000000000000000000000000000000001":{"code":"0x60005400"}}]}"#;
1055        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1056        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1057    }
1058
1059    #[test]
1060    fn test_eth_get_header_by_hash() {
1061        let s = r#"{"method": "eth_getHeaderByHash", "params":["0x12e65af7b09d4e08ec0a7786ee606b1b6b710d3f9c39f73d7e065527e0e839d3"]}"#;
1062        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1063        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1064    }
1065
1066    #[test]
1067    fn test_txpool_content_from() {
1068        let address = "0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842";
1069        let s = format!(r#"{{"method": "txpool_contentFrom", "params":["{address}"]}}"#);
1070        let value: serde_json::Value = serde_json::from_str(&s).unwrap();
1071        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1072        match req {
1073            EthRequest::TxPoolContentFrom(from) => {
1074                assert_eq!(from, address.parse::<Address>().unwrap());
1075            }
1076            _ => unreachable!(),
1077        }
1078    }
1079
1080    #[test]
1081    fn test_eth_get_header_by_number() {
1082        let s = r#"{"method": "eth_getHeaderByNumber", "params":["latest"]}"#;
1083        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1084        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1085    }
1086
1087    #[test]
1088    fn test_eth_max_priority_fee() {
1089        let s = r#"{"method": "eth_maxPriorityFeePerGas", "params":[]}"#;
1090        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1091        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1092    }
1093
1094    #[test]
1095    fn test_eth_send_raw_transaction_sync() {
1096        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef"]}"#;
1097        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1098        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1099        match req {
1100            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1101                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1102                assert_eq!(timeout, None);
1103            }
1104            _ => unreachable!(),
1105        }
1106
1107        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef", null]}"#;
1108        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1109        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1110        match req {
1111            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1112                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1113                assert_eq!(timeout, None);
1114            }
1115            _ => unreachable!(),
1116        }
1117
1118        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef", 1]}"#;
1119        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1120        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1121        match req {
1122            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1123                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1124                assert_eq!(timeout, Some(1));
1125            }
1126            _ => unreachable!(),
1127        }
1128    }
1129
1130    #[test]
1131    fn test_eth_base_fee() {
1132        let s = r#"{"method": "eth_baseFee", "params":[]}"#;
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_eth_syncing() {
1139        let s = r#"{"method": "eth_syncing", "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
1144    #[test]
1145    fn test_custom_impersonate_account() {
1146        let s = r#"{"method": "anvil_impersonateAccount", "params":
1147["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1148        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1149        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1150    }
1151
1152    #[test]
1153    fn test_custom_stop_impersonate_account() {
1154        let s = r#"{"method": "anvil_stopImpersonatingAccount",  "params":
1155["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
1156        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1157        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1158    }
1159
1160    #[test]
1161    fn test_custom_auto_impersonate_account() {
1162        let s = r#"{"method": "anvil_autoImpersonateAccount",  "params": [true]}"#;
1163        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1164        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1165    }
1166
1167    #[test]
1168    fn test_custom_get_automine() {
1169        let s = r#"{"method": "anvil_getAutomine", "params": []}"#;
1170        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1171        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1172    }
1173
1174    #[test]
1175    fn test_custom_get_last_block_wall_time() {
1176        let s = r#"{"method": "anvil_getLastBlockWallTime", "params": []}"#;
1177        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1178        assert!(matches!(
1179            serde_json::from_value::<EthRequest>(value).unwrap(),
1180            EthRequest::GetLastBlockWallTime(())
1181        ));
1182    }
1183
1184    #[test]
1185    fn test_custom_mine() {
1186        let s = r#"{"method": "anvil_mine", "params": []}"#;
1187        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1188        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1189        match req {
1190            EthRequest::Mine(num, time) => {
1191                assert!(num.is_none());
1192                assert!(time.is_none());
1193            }
1194            _ => unreachable!(),
1195        }
1196        let s = r#"{"method": "anvil_mine", "params":
1197["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1198        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1199        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1200        match req {
1201            EthRequest::Mine(num, time) => {
1202                assert!(num.is_some());
1203                assert!(time.is_none());
1204            }
1205            _ => unreachable!(),
1206        }
1207        let s = r#"{"method": "anvil_mine", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1208        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1209        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1210        match req {
1211            EthRequest::Mine(num, time) => {
1212                assert!(num.is_some());
1213                assert!(time.is_some());
1214            }
1215            _ => unreachable!(),
1216        }
1217    }
1218
1219    #[test]
1220    fn test_custom_auto_mine() {
1221        let s = r#"{"method": "anvil_setAutomine", "params": [false]}"#;
1222        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1223        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1224        let s = r#"{"method": "evm_setAutomine", "params": [false]}"#;
1225        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1226        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1227    }
1228
1229    #[test]
1230    fn test_custom_interval_mining() {
1231        let s = r#"{"method": "anvil_setIntervalMining", "params": [100]}"#;
1232        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1233        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1234        let s = r#"{"method": "evm_setIntervalMining", "params": [100]}"#;
1235        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1236        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1237    }
1238
1239    #[test]
1240    fn test_numeric_params_accept_hex_and_decimal_strings() {
1241        // Standard JSON-RPC clients (web3.js / ethers / viem) encode numeric params as hex
1242        // strings. These methods keep their internal `u64` types, but use a U64-aware
1243        // deserializer for RPC params.
1244        let parse = |s: &str| {
1245            let value: serde_json::Value = serde_json::from_str(s).unwrap();
1246            serde_json::from_value::<EthRequest>(value)
1247        };
1248
1249        match parse(r#"{"method": "anvil_setIntervalMining", "params": [100]}"#).unwrap() {
1250            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1251            req => panic!("unexpected request: {req:?}"),
1252        }
1253        match parse(r#"{"method": "anvil_setIntervalMining", "params": 100}"#).unwrap() {
1254            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1255            req => panic!("unexpected request: {req:?}"),
1256        }
1257        match parse(r#"{"method": "anvil_setIntervalMining", "params": ["0x64"]}"#).unwrap() {
1258            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1259            req => panic!("unexpected request: {req:?}"),
1260        }
1261        match parse(r#"{"method": "anvil_setIntervalMining", "params": "0x64"}"#).unwrap() {
1262            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1263            req => panic!("unexpected request: {req:?}"),
1264        }
1265        match parse(r#"{"method": "anvil_setIntervalMining", "params": ["100"]}"#).unwrap() {
1266            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1267            req => panic!("unexpected request: {req:?}"),
1268        }
1269        match parse(r#"{"method": "anvil_setIntervalMining", "params": "100"}"#).unwrap() {
1270            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1271            req => panic!("unexpected request: {req:?}"),
1272        }
1273        match parse(r#"{"method": "anvil_setChainId", "params": ["0x539"]}"#).unwrap() {
1274            EthRequest::SetChainId(chain_id) => assert_eq!(chain_id, 1337),
1275            req => panic!("unexpected request: {req:?}"),
1276        }
1277        match parse(r#"{"method": "anvil_setBlockTimestampInterval", "params": ["0xa"]}"#).unwrap()
1278        {
1279            EthRequest::EvmSetBlockTimeStampInterval(interval) => assert_eq!(interval, 10),
1280            req => panic!("unexpected request: {req:?}"),
1281        }
1282        match parse(r#"{"method": "anvil_rollback", "params": ["0x5"]}"#).unwrap() {
1283            EthRequest::Rollback(depth) => assert_eq!(depth, Some(5)),
1284            req => panic!("unexpected request: {req:?}"),
1285        }
1286        match parse(r#"{"method": "anvil_rollback", "params": []}"#).unwrap() {
1287            EthRequest::Rollback(depth) => assert_eq!(depth, None),
1288            req => panic!("unexpected request: {req:?}"),
1289        }
1290        match parse(r#"{"method": "anvil_rollback", "params": [null]}"#).unwrap() {
1291            EthRequest::Rollback(depth) => assert_eq!(depth, None),
1292            req => panic!("unexpected request: {req:?}"),
1293        }
1294
1295        assert!(
1296            parse(r#"{"method": "anvil_setIntervalMining", "params": ["0x10000000000000000"]}"#)
1297                .is_err()
1298        );
1299    }
1300
1301    #[test]
1302    fn test_custom_drop_tx() {
1303        let s = r#"{"method": "anvil_dropTransaction", "params":
1304["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1305        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1306        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1307    }
1308
1309    #[test]
1310    fn test_custom_reset() {
1311        let s = r#"{"method": "anvil_reset", "params": [{"forking": {"jsonRpcUrl": "https://ethereumpublicnode.com",
1312        "blockNumber": "18441649"
1313      }
1314    }]}"#;
1315        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1316        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1317        match req {
1318            EthRequest::Reset(forking) => {
1319                let forking = forking.and_then(|f| f.params);
1320                assert_eq!(
1321                    forking,
1322                    Some(Forking {
1323                        json_rpc_url: Some("https://ethereumpublicnode.com".into()),
1324                        block_number: Some(18441649)
1325                    })
1326                )
1327            }
1328            _ => unreachable!(),
1329        }
1330
1331        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
1332                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>",
1333                "blockNumber": 11095000
1334        }}]}"#;
1335        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1336        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1337        match req {
1338            EthRequest::Reset(forking) => {
1339                let forking = forking.and_then(|f| f.params);
1340                assert_eq!(
1341                    forking,
1342                    Some(Forking {
1343                        json_rpc_url: Some(
1344                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
1345                        ),
1346                        block_number: Some(11095000)
1347                    })
1348                )
1349            }
1350            _ => unreachable!(),
1351        }
1352
1353        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
1354                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>"
1355        }}]}"#;
1356        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1357        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1358        match req {
1359            EthRequest::Reset(forking) => {
1360                let forking = forking.and_then(|f| f.params);
1361                assert_eq!(
1362                    forking,
1363                    Some(Forking {
1364                        json_rpc_url: Some(
1365                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
1366                        ),
1367                        block_number: None
1368                    })
1369                )
1370            }
1371            _ => unreachable!(),
1372        }
1373
1374        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545", "blockNumber": 14000000}]}"#;
1375        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1376        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1377        match req {
1378            EthRequest::Reset(forking) => {
1379                let forking = forking.and_then(|f| f.params);
1380                assert_eq!(
1381                    forking,
1382                    Some(Forking {
1383                        json_rpc_url: Some("http://localhost:8545".to_string()),
1384                        block_number: Some(14000000)
1385                    })
1386                )
1387            }
1388            _ => unreachable!(),
1389        }
1390
1391        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": 14000000}]}"#;
1392        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1393        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1394        match req {
1395            EthRequest::Reset(forking) => {
1396                let forking = forking.and_then(|f| f.params);
1397                assert_eq!(
1398                    forking,
1399                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
1400                )
1401            }
1402            _ => unreachable!(),
1403        }
1404
1405        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": "14000000"}]}"#;
1406        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1407        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1408        match req {
1409            EthRequest::Reset(forking) => {
1410                let forking = forking.and_then(|f| f.params);
1411                assert_eq!(
1412                    forking,
1413                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
1414                )
1415            }
1416            _ => unreachable!(),
1417        }
1418
1419        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545"}]}"#;
1420        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1421        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1422        match req {
1423            EthRequest::Reset(forking) => {
1424                let forking = forking.and_then(|f| f.params);
1425                assert_eq!(
1426                    forking,
1427                    Some(Forking {
1428                        json_rpc_url: Some("http://localhost:8545".to_string()),
1429                        block_number: None
1430                    })
1431                )
1432            }
1433            _ => unreachable!(),
1434        }
1435
1436        let s = r#"{"method": "anvil_reset"}"#;
1437        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1438        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1439        match req {
1440            EthRequest::Reset(forking) => {
1441                assert!(forking.is_none())
1442            }
1443            _ => unreachable!(),
1444        }
1445    }
1446
1447    #[test]
1448    fn test_custom_set_balance() {
1449        let s = r#"{"method": "anvil_setBalance", "params":
1450["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1451        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1452        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1453
1454        let s = r#"{"method": "anvil_setBalance", "params":
1455["0xd84de507f3fada7df80908082d3239466db55a71", 1337]}"#;
1456        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1457        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1458    }
1459
1460    #[test]
1461    fn test_simulate_preserves_transaction_extension_fields() {
1462        let value = serde_json::json!({
1463            "method": "eth_simulateV1",
1464            "params": [{
1465                "blockStateCalls": [{
1466                    "calls": [{
1467                        "to": "0x0000000000000000000000000000000000000001",
1468                        "tempoExtension": "preserved"
1469                    }]
1470                }]
1471            }]
1472        });
1473
1474        let request = serde_json::from_value::<EthRequest>(value).unwrap();
1475        let EthRequest::EthSimulateV1(payload, _) = request else { panic!() };
1476        let transaction = &payload.block_state_calls[0].calls[0];
1477
1478        assert_eq!(transaction.other["tempoExtension"], serde_json::json!("preserved"));
1479    }
1480
1481    #[test]
1482    fn test_custom_set_code() {
1483        let s = r#"{"method": "anvil_setCode", "params":
1484["0xd84de507f3fada7df80908082d3239466db55a71", "0x0123456789abcdef"]}"#;
1485        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1486        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1487
1488        let s = r#"{"method": "anvil_setCode", "params":
1489["0xd84de507f3fada7df80908082d3239466db55a71", "0x"]}"#;
1490        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1491        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1492
1493        let s = r#"{"method": "anvil_setCode", "params":
1494["0xd84de507f3fada7df80908082d3239466db55a71", ""]}"#;
1495        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1496        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1497    }
1498
1499    #[test]
1500    fn test_custom_set_nonce() {
1501        let s = r#"{"method": "anvil_setNonce", "params":
1502["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1503        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1504        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1505        let s = r#"{"method":
1506"hardhat_setNonce", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1507        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1508        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1509        let s = r#"{"method": "evm_setAccountNonce", "params":
1510["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
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_custom_set_storage_at() {
1517        let s = r#"{"method": "anvil_setStorageAt", "params":
1518["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0",
1519"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1520        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1521        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1522
1523        let s = r#"{"method": "hardhat_setStorageAt", "params":
1524["0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
1525"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
1526"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1527        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1528        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1529    }
1530
1531    #[test]
1532    fn test_serde_custom_coinbase() {
1533        let s = r#"{"method": "anvil_setCoinbase", "params":
1534["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#;
1535        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1536        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1537    }
1538
1539    #[test]
1540    fn test_serde_custom_set_next_block_prevrandao() {
1541        let s = r#"{"method": "anvil_setNextBlockPrevRandao", "params": ["0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]}"#;
1542        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1543        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1544    }
1545
1546    #[test]
1547    fn test_serde_custom_set_next_block_parent_beacon_block_root() {
1548        let s = r#"{"method": "anvil_setNextBlockParentBeaconBlockRoot", "params": ["0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]}"#;
1549        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1550        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1551    }
1552
1553    #[test]
1554    fn test_serde_custom_logging() {
1555        let s = r#"{"method": "anvil_setLoggingEnabled", "params": [false]}"#;
1556        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1557        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1558    }
1559
1560    #[test]
1561    fn test_serde_custom_min_gas_price() {
1562        let s = r#"{"method": "anvil_setMinGasPrice", "params": ["0x0"]}"#;
1563        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1564        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1565    }
1566
1567    #[test]
1568    fn test_serde_custom_next_block_base_fee() {
1569        let s = r#"{"method": "anvil_setNextBlockBaseFeePerGas", "params": ["0x0"]}"#;
1570        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1571        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1572    }
1573
1574    #[test]
1575    fn test_serde_set_time() {
1576        let s = r#"{"method": "anvil_setTime", "params": ["0x0"]}"#;
1577        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1578        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1579
1580        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1581        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1582        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1583    }
1584
1585    #[test]
1586    fn test_serde_custom_dump_state() {
1587        let s = r#"{"method": "anvil_dumpState", "params": [true]}"#;
1588        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1589        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1590
1591        let s = r#"{"method": "anvil_dumpState"}"#;
1592        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1593        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1594        match req {
1595            EthRequest::DumpState(param) => {
1596                assert!(param.is_none());
1597            }
1598            _ => unreachable!(),
1599        }
1600    }
1601
1602    #[test]
1603    fn test_serde_custom_load_state() {
1604        let s = r#"{"method": "anvil_loadState", "params": ["0x0001"] }"#;
1605        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1606        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1607    }
1608
1609    #[test]
1610    fn test_serde_custom_snapshot() {
1611        let s = r#"{"method": "anvil_snapshot", "params": [] }"#;
1612        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1613        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1614
1615        let s = r#"{"method": "evm_snapshot", "params": [] }"#;
1616        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1617        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1618    }
1619
1620    #[test]
1621    fn test_serde_custom_revert() {
1622        let s = r#"{"method": "anvil_revert", "params": ["0x0"]}"#;
1623        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1624        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1625    }
1626
1627    #[test]
1628    fn test_serde_custom_increase_time() {
1629        let s = r#"{"method": "anvil_increaseTime", "params": ["0x0"]}"#;
1630        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1631        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1632
1633        let s = r#"{"method": "anvil_increaseTime", "params": [1]}"#;
1634        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1635        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1636
1637        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1638        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1639        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1640
1641        let s = r#"{"method": "evm_increaseTime", "params": ["0x0"]}"#;
1642        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1643        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1644
1645        let s = r#"{"method": "evm_increaseTime", "params": [1]}"#;
1646        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1647        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1648
1649        let s = r#"{"method": "evm_increaseTime", "params": 1}"#;
1650        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1651        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1652    }
1653
1654    #[test]
1655    fn test_serde_custom_next_timestamp() {
1656        let s = r#"{"method": "anvil_setNextBlockTimestamp", "params": [100]}"#;
1657        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1658        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1659        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": [100]}"#;
1660        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1661        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1662        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": ["0x64e0f308"]}"#;
1663        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1664        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1665    }
1666
1667    #[test]
1668    fn test_serde_custom_timestamp_interval() {
1669        let s = r#"{"method": "anvil_setBlockTimestampInterval", "params": [100]}"#;
1670        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1671        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1672    }
1673
1674    #[test]
1675    fn test_serde_custom_remove_timestamp_interval() {
1676        let s = r#"{"method": "anvil_removeBlockTimestampInterval", "params": []}"#;
1677        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1678        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1679    }
1680
1681    #[test]
1682    fn test_serde_custom_evm_mine() {
1683        let s = r#"{"method": "evm_mine", "params": [100]}"#;
1684        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1685        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1686        let s = r#"{"method": "evm_mine", "params": [{
1687            "timestamp": 100,
1688            "blocks": 100
1689        }]}"#;
1690        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1691        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1692        match req {
1693            EthRequest::EvmMine(params) => {
1694                assert_eq!(
1695                    params.unwrap().params.unwrap_or_default(),
1696                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1697                )
1698            }
1699            _ => unreachable!(),
1700        }
1701
1702        let s = r#"{"method": "evm_mine"}"#;
1703        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1704        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1705
1706        match req {
1707            EthRequest::EvmMine(params) => {
1708                assert!(params.is_none())
1709            }
1710            _ => unreachable!(),
1711        }
1712
1713        let s = r#"{"method": "evm_mine", "params": []}"#;
1714        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1715        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1716    }
1717
1718    #[test]
1719    fn test_serde_custom_evm_mine_detailed() {
1720        let s = r#"{"method": "anvil_mine_detailed", "params": [100]}"#;
1721        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1722        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1723        let s = r#"{"method": "anvil_mine_detailed", "params": [{
1724            "timestamp": 100,
1725            "blocks": 100
1726        }]}"#;
1727        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1728        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1729        match req {
1730            EthRequest::EvmMineDetailed(params) => {
1731                assert_eq!(
1732                    params.unwrap().params.unwrap_or_default(),
1733                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1734                )
1735            }
1736            _ => unreachable!(),
1737        }
1738
1739        let s = r#"{"method": "evm_mine_detailed"}"#;
1740        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1741        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1742
1743        match req {
1744            EthRequest::EvmMineDetailed(params) => {
1745                assert!(params.is_none())
1746            }
1747            _ => unreachable!(),
1748        }
1749
1750        let s = r#"{"method": "anvil_mine_detailed", "params": []}"#;
1751        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1752        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1753    }
1754
1755    #[test]
1756    fn test_serde_custom_evm_mine_hex() {
1757        let s = r#"{"method": "evm_mine", "params": ["0x63b6ff08"]}"#;
1758        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1759        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1760        match req {
1761            EthRequest::EvmMine(params) => {
1762                assert_eq!(
1763                    params.unwrap().params.unwrap_or_default(),
1764                    MineOptions::Timestamp(Some(1672937224))
1765                )
1766            }
1767            _ => unreachable!(),
1768        }
1769
1770        let s = r#"{"method": "evm_mine", "params": [{"timestamp": "0x63b6ff08"}]}"#;
1771        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1772        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1773        match req {
1774            EthRequest::EvmMine(params) => {
1775                assert_eq!(
1776                    params.unwrap().params.unwrap_or_default(),
1777                    MineOptions::Options { timestamp: Some(1672937224), blocks: None }
1778                )
1779            }
1780            _ => unreachable!(),
1781        }
1782    }
1783
1784    #[test]
1785    fn test_eth_uncle_count_by_block_hash() {
1786        let s = r#"{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1787        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1788        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1789    }
1790
1791    #[test]
1792    fn test_eth_block_tx_count_by_block_hash() {
1793        let s = r#"{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1794        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1795        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1796    }
1797
1798    #[test]
1799    fn test_eth_get_logs() {
1800        let s = r#"{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}"#;
1801        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1802        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1803    }
1804
1805    #[test]
1806    fn test_eth_new_filter() {
1807        let s = r#"{"method": "eth_newFilter", "params": [{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":73}"#;
1808        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1809        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1810    }
1811
1812    #[test]
1813    fn test_serde_raw_transaction_conditional() {
1814        let s = r#"{"method": "eth_sendRawTransactionConditional", "params":
1815["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"knownAccounts":{}}]}"#;
1816        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1817        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1818    }
1819
1820    #[test]
1821    fn test_eth_new_pending_transaction_filter() {
1822        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[],"id":73}"#;
1823        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1824        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1825        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(None)));
1826
1827        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[null],"id":73}"#;
1828        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1829        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1830        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(None)));
1831
1832        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[false],"id":73}"#;
1833        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1834        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1835        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(Some(false))));
1836
1837        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[true],"id":73}"#;
1838        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1839        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1840        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(Some(true))));
1841    }
1842
1843    #[test]
1844    fn test_serde_eth_unsubscribe() {
1845        let s = r#"{"id": 1, "method": "eth_unsubscribe", "params":
1846["0x9cef478923ff08bf67fde6c64013158d"]}"#;
1847        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1848        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1849    }
1850
1851    #[test]
1852    fn test_serde_eth_subscribe() {
1853        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}"#;
1854        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1855        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1856        assert!(matches!(serde_json::from_str(s).unwrap(), EthRpcCall::PubSub(_)));
1857
1858        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["logs", {"address":
1859"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics":
1860["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}"#;
1861        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1862        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1863
1864        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}"#;
1865        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1866        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1867
1868        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["syncing"]}"#;
1869        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1870        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1871    }
1872
1873    #[test]
1874    fn test_serde_debug_raw_transaction() {
1875        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransaction","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1876        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1877        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1878
1879        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByHash","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1880        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1881        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1882
1883        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockHashAndIndex","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c",1],"id":1}"#;
1884        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1885        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1886
1887        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockNumberAndIndex","params":["0x3ed3a89b",0],"id":1}"#;
1888        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1889        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1890    }
1891
1892    #[test]
1893    fn test_serde_debug_raw_receipts() {
1894        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawReceipts","params":["latest"],"id":1}"#;
1895        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1896        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1897
1898        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawReceipts","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1899        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1900        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1901    }
1902
1903    #[test]
1904    fn test_serde_debug_raw_transactions() {
1905        let s =
1906            r#"{"jsonrpc":"2.0","method":"debug_getRawTransactions","params":["latest"],"id":1}"#;
1907        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1908        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1909
1910        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransactions","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1911        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1912        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1913    }
1914
1915    #[test]
1916    fn test_serde_debug_raw_header() {
1917        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawHeader","params":["latest"],"id":1}"#;
1918        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1919        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1920
1921        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawHeader","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1922        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1923        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1924    }
1925
1926    #[test]
1927    fn test_serde_debug_raw_block() {
1928        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawBlock","params":["latest"],"id":1}"#;
1929        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1930        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1931
1932        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawBlock","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1933        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1934        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1935    }
1936
1937    #[test]
1938    fn test_serde_debug_clear_txpool() {
1939        let s = r#"{"jsonrpc":"2.0","method":"debug_clearTxpool","params":[],"id":1}"#;
1940        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1941        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1942    }
1943
1944    #[test]
1945    fn test_serde_debug_trace_transaction() {
1946        let s = r#"{"method": "debug_traceTransaction", "params":
1947["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1948        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1949        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1950
1951        let s = r#"{"method": "debug_traceTransaction", "params":
1952["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {}]}"#;
1953        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1954        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1955
1956        let s = r#"{"method": "debug_traceTransaction", "params":
1957["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"disableStorage":
1958true}]}"#;
1959        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1960        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1961    }
1962
1963    #[test]
1964    fn test_serde_debug_account_info_at() {
1965        let s = r#"{"method": "debug_accountInfoAt", "params": ["0x1", "0x0", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1966        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1967        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1968
1969        let s = r#"{"method": "debug_accountInfoAt", "params": [{"blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"}, 0, "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1970        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1971        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1972    }
1973
1974    #[test]
1975    fn test_serde_debug_execution_witness() {
1976        let s = r#"{"method": "debug_executionWitness", "params": ["0x1"]}"#;
1977        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1978        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1979
1980        let s = r#"{"method": "debug_executionWitness", "params": ["latest"]}"#;
1981        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1982        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1983    }
1984
1985    #[test]
1986    fn test_serde_trace_transaction_opcode_gas() {
1987        let s = r#"{"method": "trace_transactionOpcodeGas", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1988        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1989        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1990    }
1991
1992    #[test]
1993    fn test_serde_trace_replay_transaction() {
1994        let s = r#"{"method":"trace_replayTransaction","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff",["trace","stateDiff"]]}"#;
1995        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1996        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1997    }
1998
1999    #[test]
2000    fn test_serde_trace_block_opcode_gas() {
2001        let s = r#"{"method": "trace_blockOpcodeGas", "params": ["0x1"]}"#;
2002        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2003        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2004
2005        let s = r#"{"method": "trace_blockOpcodeGas", "params": [{"blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"}]}"#;
2006        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2007        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2008    }
2009
2010    #[test]
2011    fn test_serde_trace_raw_transaction() {
2012        let s = r#"{"method": "trace_rawTransaction", "params": ["0x02f866827a690a65648252089470997970c51812dc3a010c7d01b50e0d17dc79c88203e980c001a0e4de88aefcf87ccb04466e60de66a83192e46aa26177d5ea35efbfd43fd0ecdca00e3148e0e8e0b9a6f9b329efd6e30c4a461920f3a27497be3dbefaba996601da", ["trace"]]}"#;
2013        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2014        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2015
2016        let s = r#"{"method": "trace_rawTransaction", "params": ["0x02f866827a690a65648252089470997970c51812dc3a010c7d01b50e0d17dc79c88203e980c001a0e4de88aefcf87ccb04466e60de66a83192e46aa26177d5ea35efbfd43fd0ecdca00e3148e0e8e0b9a6f9b329efd6e30c4a461920f3a27497be3dbefaba996601da", ["trace", "stateDiff", "vmTrace"], "latest"]}"#;
2017        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2018        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2019    }
2020
2021    #[test]
2022    fn test_serde_debug_trace_call() {
2023        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2024        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2025        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2026
2027        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
2028        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2029        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2030
2031        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
2032        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2033        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2034
2035        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
2036        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2037        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2038
2039        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }, {"disableStorage": true}]}"#;
2040        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2041        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2042
2043        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x1" }, {"txIndex": "0x0"}]}"#;
2044        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2045        let req = serde_json::from_value::<EthRequest>(value).unwrap();
2046        match req {
2047            EthRequest::DebugTraceCall(_, _, opts) => assert_eq!(opts.tx_index, Some(0)),
2048            _ => panic!("expected debug_traceCall"),
2049        }
2050    }
2051
2052    #[test]
2053    fn test_serde_debug_get_modified_accounts_by_number() {
2054        let s = r#"{"method": "debug_getModifiedAccountsByNumber", "params": [0, 1]}"#;
2055        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2056        match serde_json::from_value::<EthRequest>(value).unwrap() {
2057            EthRequest::DebugGetModifiedAccountsByNumber(0, 1) => {}
2058            req => panic!("unexpected request: {req:?}"),
2059        }
2060    }
2061
2062    #[test]
2063    fn test_serde_debug_free_os_memory() {
2064        let s = r#"{"method": "debug_freeOSMemory", "params": []}"#;
2065        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2066        match serde_json::from_value::<EthRequest>(value).unwrap() {
2067            EthRequest::DebugFreeOsMemory(()) => {}
2068            req => panic!("unexpected request: {req:?}"),
2069        }
2070    }
2071
2072    #[test]
2073    fn test_serde_trace_call() {
2074        let s = r#"{"method": "trace_call", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, ["trace", "stateDiff"], "latest"]}"#;
2075        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2076        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2077
2078        let s = r#"{"method": "trace_call", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2079        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2080        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2081    }
2082
2083    #[test]
2084    fn test_serde_trace_call_many() {
2085        let s = r#"{"method": "trace_callMany", "params": [[[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","value":"0x1"}, ["trace"]], [{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","value":"0x2"}, ["trace", "stateDiff"]]]]}"#;
2086        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2087        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2088
2089        let s = r#"{"method": "trace_callMany", "params": [[[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, ["trace"]]], "latest"]}"#;
2090        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2091        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2092    }
2093
2094    #[test]
2095    fn test_serde_trace_get() {
2096        let s = r#"{"method": "trace_get", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", ["0x6", "0xa0"]]}"#;
2097        let req = serde_json::from_str::<EthRequest>(s).unwrap();
2098        let EthRequest::TraceGet(_, indices) = req else { panic!("unexpected request {req:?}") };
2099        assert_eq!(indices.into_iter().map(usize::from).collect::<Vec<_>>(), [6, 160]);
2100
2101        for indices in
2102            [r#"[6, 0]"#, r#"["6"]"#, r#"["0x00"]"#, r#"["0x06"]"#, r#"["0xA"]"#, r#"["0x"]"#]
2103        {
2104            let s = format!(
2105                r#"{{"method": "trace_get", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {indices}]}}"#
2106            );
2107            serde_json::from_str::<EthRequest>(&s).unwrap_err();
2108        }
2109    }
2110
2111    #[test]
2112    fn test_serde_debug_trace_block() {
2113        let s = r#"{"method":"debug_traceBlock","params":["0xc0",{"tracer":"callTracer"}]}"#;
2114        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2115        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2116    }
2117
2118    #[test]
2119    fn test_serde_eth_storage() {
2120        let s = r#"{"method": "eth_getStorageAt", "params":
2121["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"]}"#;
2122        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2123        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2124    }
2125
2126    #[test]
2127    fn test_serde_state_requests_without_block() {
2128        let requests = [
2129            r#"{"method":"eth_getBalance","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2130            r#"{"method":"eth_getCode","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2131            r#"{"method":"eth_getStorageAt","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251","0x0"]}"#,
2132            r#"{"method":"eth_getStorageValues","params":[{"0x295a70b2de5e3953354a6a8344e616ed314d7251":["0x0000000000000000000000000000000000000000000000000000000000000000"]}]}"#,
2133            r#"{"method":"eth_getTransactionCount","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2134            r#"{"method":"eth_getProof","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251",[]]}"#,
2135        ];
2136
2137        for request in requests {
2138            if let EthRequest::EthGetTransactionCount(params) =
2139                serde_json::from_str::<EthRequest>(request).unwrap()
2140            {
2141                let (_, block, nonce_key) = params.into_parts();
2142                assert!(block.is_none());
2143                assert!(nonce_key.is_none());
2144                continue;
2145            }
2146            assert!(matches!(
2147                serde_json::from_str::<EthRequest>(request).unwrap(),
2148                EthRequest::EthGetBalance(_, None)
2149                    | EthRequest::EthGetCodeAt(_, None)
2150                    | EthRequest::EthGetStorageAt(_, _, None)
2151                    | EthRequest::EthGetStorageValues(_, None)
2152                    | EthRequest::EthGetProof(_, _, None)
2153            ));
2154        }
2155    }
2156
2157    #[test]
2158    fn test_serde_transaction_count_nonce_key_is_base_gated() {
2159        let request = r#"{"method":"eth_getTransactionCount","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251","latest","0x7"]}"#;
2160        let result = serde_json::from_str::<EthRequest>(request);
2161
2162        #[cfg(feature = "base")]
2163        {
2164            let EthRequest::EthGetTransactionCount(params) = result.unwrap() else {
2165                panic!("unexpected request variant")
2166            };
2167            let (_, block, nonce_key) = params.into_parts();
2168            assert_eq!(block, Some(BlockId::latest()));
2169            assert_eq!(nonce_key, Some(U256::from(7)));
2170        }
2171        #[cfg(not(feature = "base"))]
2172        assert!(result.is_err());
2173    }
2174
2175    #[test]
2176    fn test_eth_call() {
2177        let req = r#"{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}"#;
2178        let _req = serde_json::from_str::<TransactionRequest>(req).unwrap();
2179
2180        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"},"latest"]}"#;
2181        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2182
2183        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2184        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2185
2186        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
2187        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2188
2189        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
2190        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2191
2192        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
2193        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2194    }
2195
2196    #[test]
2197    fn test_eth_call_many() {
2198        let s = r#"{"method":"eth_callMany","params":[[{"transactions":[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","data":"0xcfae3217"}]}],{"blockNumber":"latest"},{"0x0000000000000000000000000000000000000001":{"balance":"0x1"}}]}"#;
2199        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2200    }
2201
2202    #[test]
2203    fn test_eth_call_bundle() {
2204        let s = r#"{"method":"eth_callBundle","params":[{"txs":["0x1234"],"blockNumber":"0x1","stateBlockNumber":"latest"}]}"#;
2205        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2206    }
2207
2208    #[test]
2209    fn test_serde_eth_balance() {
2210        let s = r#"{"method": "eth_getBalance", "params":
2211["0x295a70b2de5e3953354a6a8344e616ed314d7251", "latest"]}"#;
2212        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2213
2214        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2215    }
2216
2217    #[test]
2218    fn test_serde_eth_block_by_number() {
2219        let s = r#"{"method": "eth_getBlockByNumber", "params": ["0x0", true]}"#;
2220        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2221        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2222        let s = r#"{"method": "eth_getBlockByNumber", "params": ["latest", true]}"#;
2223        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2224        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2225        let s = r#"{"method": "eth_getBlockByNumber", "params": ["earliest", true]}"#;
2226        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2227        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2228        let s = r#"{"method": "eth_getBlockByNumber", "params": ["pending", true]}"#;
2229        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2230        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2231
2232        // this case deviates from the spec, but we're supporting this for legacy reasons: <https://github.com/foundry-rs/foundry/issues/1868>
2233        let s = r#"{"method": "eth_getBlockByNumber", "params": [0, true]}"#;
2234        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2235        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2236    }
2237
2238    #[test]
2239    fn test_eth_sign() {
2240        let s = r#"{"method": "eth_sign", "params":
2241["0xd84de507f3fada7df80908082d3239466db55a71", "0x00"]}"#;
2242        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2243        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2244        let s = r#"{"method": "personal_sign", "params":
2245["0x00", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
2246        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2247        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2248    }
2249
2250    #[test]
2251    fn test_eth_sign_typed_data() {
2252        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!"}}]}"#;
2253        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2254        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2255    }
2256
2257    #[test]
2258    fn test_remove_pool_transactions() {
2259        let s = r#"{"method": "anvil_removePoolTransactions",  "params":["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
2260        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2261        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2262    }
2263
2264    #[test]
2265    fn test_serde_anvil_reorg() {
2266        // TransactionData::JSON
2267        let s = r#"
2268        {
2269            "method": "anvil_reorg",
2270            "params": [
2271                5,
2272                [
2273                    [
2274                        {
2275                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2276                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2277                            "value": 100
2278                        },
2279                        1
2280                    ],
2281                    [
2282                        {
2283                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2284                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2285                            "value": 200
2286                        },
2287                        2
2288                    ]
2289                ]
2290            ]
2291        }
2292        "#;
2293        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2294        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2295        // TransactionData::Raw
2296        let s = r#"
2297        {
2298            "method": "anvil_reorg",
2299            "params": [
2300                5,
2301                [
2302                    [
2303                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
2304                        1
2305                    ]
2306                ]
2307            ]
2308        }
2309        "#;
2310        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2311        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2312        // TransactionData::Raw and TransactionData::JSON
2313        let s = r#"
2314        {
2315            "method": "anvil_reorg",
2316            "params": [
2317                5,
2318                [
2319                    [
2320                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
2321                        1
2322                    ],
2323                    [
2324                        {
2325                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2326                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2327                            "value": 200
2328                        },
2329                        2
2330                    ]
2331                ]
2332            ]
2333        }
2334        "#;
2335        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2336        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2337    }
2338}