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    /// Pauses or resumes automatic block production, keeping the block time schedule
579    #[serde(rename = "anvil_setMiningPaused", with = "sequence")]
580    SetMiningPaused(bool),
581
582    /// Returns true if automatic block production is paused
583    #[serde(rename = "anvil_getMiningPaused", with = "empty_params")]
584    GetMiningPaused(()),
585
586    /// Removes transactions from the pool
587    #[serde(rename = "anvil_dropTransaction", alias = "hardhat_dropTransaction", with = "sequence")]
588    DropTransaction(B256),
589
590    /// Removes transactions from the pool
591    #[serde(
592        rename = "anvil_dropAllTransactions",
593        alias = "hardhat_dropAllTransactions",
594        with = "empty_params"
595    )]
596    DropAllTransactions(),
597
598    /// Reset the fork to a fresh forked state, and optionally update the fork config
599    #[serde(rename = "anvil_reset", alias = "hardhat_reset")]
600    Reset(#[serde(default)] Option<Params<Option<Forking>>>),
601
602    /// Sets the backend rpc url
603    #[serde(rename = "anvil_setRpcUrl", with = "sequence")]
604    SetRpcUrl(String),
605
606    /// Modifies the balance of an account.
607    #[serde(
608        rename = "anvil_setBalance",
609        alias = "hardhat_setBalance",
610        alias = "tenderly_setBalance"
611    )]
612    SetBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
613
614    /// Increases the balance of an account.
615    #[serde(
616        rename = "anvil_addBalance",
617        alias = "hardhat_addBalance",
618        alias = "tenderly_addBalance"
619    )]
620    AddBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
621
622    /// Modifies the ERC20 balance of an account.
623    #[serde(
624        rename = "anvil_dealERC20",
625        alias = "hardhat_dealERC20",
626        alias = "anvil_setERC20Balance"
627    )]
628    DealERC20(Address, Address, #[serde(deserialize_with = "deserialize_number")] U256),
629
630    /// Modifies the TIP-20 balance of an account.
631    #[serde(rename = "anvil_dealTIP20")]
632    DealTIP20(Address, Address, #[serde(deserialize_with = "deserialize_number")] U256),
633
634    /// Sets the ERC20 allowance for a spender
635    #[serde(rename = "anvil_setERC20Allowance")]
636    SetERC20Allowance(
637        Address,
638        Address,
639        Address,
640        #[serde(deserialize_with = "deserialize_number")] U256,
641    ),
642
643    /// Sets the code of a contract
644    #[serde(rename = "anvil_setCode", alias = "hardhat_setCode")]
645    SetCode(Address, Bytes),
646
647    /// Sets the nonce of an address
648    #[serde(rename = "anvil_setNonce", alias = "hardhat_setNonce", alias = "evm_setAccountNonce")]
649    SetNonce(Address, #[serde(deserialize_with = "deserialize_number")] U256),
650
651    /// Writes a single slot of the account's storage
652    #[serde(rename = "anvil_setStorageAt", alias = "hardhat_setStorageAt")]
653    SetStorageAt(
654        Address,
655        /// slot
656        U256,
657        /// value
658        B256,
659    ),
660
661    /// Sets the coinbase address
662    #[serde(rename = "anvil_setCoinbase", alias = "hardhat_setCoinbase", with = "sequence")]
663    SetCoinbase(Address),
664
665    /// Sets the `prevrandao` value of the next block
666    #[serde(rename = "anvil_setNextBlockPrevRandao", with = "sequence")]
667    SetNextBlockPrevRandao(B256),
668
669    /// Sets the parent beacon block root of the next block
670    #[serde(rename = "anvil_setNextBlockParentBeaconBlockRoot", with = "sequence")]
671    SetNextBlockParentBeaconBlockRoot(B256),
672
673    /// Sets the chain id
674    #[serde(rename = "anvil_setChainId", deserialize_with = "deserialize_u64_seq")]
675    SetChainId(u64),
676
677    /// Enable or disable logging
678    #[serde(
679        rename = "anvil_setLoggingEnabled",
680        alias = "hardhat_setLoggingEnabled",
681        with = "sequence"
682    )]
683    SetLogging(bool),
684
685    /// Set the minimum gas price for the node
686    #[serde(
687        rename = "anvil_setMinGasPrice",
688        alias = "hardhat_setMinGasPrice",
689        deserialize_with = "deserialize_number_seq"
690    )]
691    SetMinGasPrice(U256),
692
693    /// Sets the base fee of the next block
694    #[serde(
695        rename = "anvil_setNextBlockBaseFeePerGas",
696        alias = "hardhat_setNextBlockBaseFeePerGas",
697        deserialize_with = "deserialize_number_seq"
698    )]
699    SetNextBlockBaseFeePerGas(U256),
700
701    /// Sets the specific timestamp
702    /// Accepts timestamp (Unix epoch) with millisecond precision and returns the number of seconds
703    /// between the given timestamp and the current time.
704    #[serde(
705        rename = "anvil_setTime",
706        alias = "evm_setTime",
707        deserialize_with = "deserialize_number_seq"
708    )]
709    EvmSetTime(U256),
710
711    /// Serializes the current state (including contracts code, contract's storage, accounts
712    /// properties, etc.) into a saveable data blob
713    #[serde(rename = "anvil_dumpState", alias = "hardhat_dumpState")]
714    DumpState(#[serde(default)] Option<Params<Option<bool>>>),
715
716    /// Adds state previously dumped with `DumpState` to the current chain
717    #[serde(rename = "anvil_loadState", alias = "hardhat_loadState", with = "sequence")]
718    LoadState(Bytes),
719
720    /// Retrieves the Anvil node configuration params
721    #[serde(rename = "anvil_nodeInfo", with = "empty_params")]
722    NodeInfo(()),
723
724    /// Retrieves the Anvil node metadata.
725    #[serde(rename = "anvil_metadata", alias = "hardhat_metadata", with = "empty_params")]
726    AnvilMetadata(()),
727
728    // Ganache compatible calls
729    /// Snapshot the state of the blockchain at the current block.
730    ///
731    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_snapshot>
732    #[serde(rename = "anvil_snapshot", alias = "evm_snapshot", with = "empty_params")]
733    EvmSnapshot(()),
734
735    /// Revert the state of the blockchain to a previous snapshot.
736    /// Takes a single parameter, which is the snapshot id to revert to.
737    ///
738    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_revert>
739    #[serde(
740        rename = "anvil_revert",
741        alias = "evm_revert",
742        deserialize_with = "deserialize_number_seq"
743    )]
744    EvmRevert(U256),
745
746    /// Jump forward in time by the given amount of time, in seconds.
747    #[serde(
748        rename = "anvil_increaseTime",
749        alias = "evm_increaseTime",
750        deserialize_with = "deserialize_number_seq"
751    )]
752    EvmIncreaseTime(U256),
753
754    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
755    #[serde(
756        rename = "anvil_setNextBlockTimestamp",
757        alias = "evm_setNextBlockTimestamp",
758        deserialize_with = "deserialize_number_seq"
759    )]
760    EvmSetNextBlockTimeStamp(U256),
761
762    /// Set the exact gas limit that you want in the next block
763    #[serde(
764        rename = "anvil_setBlockGasLimit",
765        alias = "evm_setBlockGasLimit",
766        deserialize_with = "deserialize_number_seq"
767    )]
768    EvmSetBlockGasLimit(U256),
769
770    /// Similar to `evm_increaseTime` but takes sets a block timestamp `interval`.
771    ///
772    /// The timestamp of the next block will be computed as `lastBlock_timestamp + interval`.
773    #[serde(rename = "anvil_setBlockTimestampInterval", deserialize_with = "deserialize_u64_seq")]
774    EvmSetBlockTimeStampInterval(u64),
775
776    /// Removes a `anvil_setBlockTimestampInterval` if it exists
777    #[serde(rename = "anvil_removeBlockTimestampInterval", with = "empty_params")]
778    EvmRemoveBlockTimeStampInterval(()),
779
780    /// Mine a single block
781    #[serde(rename = "evm_mine")]
782    EvmMine(#[serde(default)] Option<Params<Option<MineOptions>>>),
783
784    /// Mine a single block and return detailed data
785    ///
786    /// This behaves exactly as `EvmMine` but returns different output, for compatibility reasons
787    /// this is a separate call since `evm_mine` is not an anvil original.
788    #[serde(rename = "anvil_mine_detailed", alias = "evm_mine_detailed")]
789    EvmMineDetailed(#[serde(default)] Option<Params<Option<MineOptions>>>),
790
791    /// Execute a transaction regardless of signature status
792    #[serde(rename = "eth_sendUnsignedTransaction", with = "sequence")]
793    EthSendUnsignedTransaction(Box<WithOtherFields<TransactionRequest>>),
794
795    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
796    /// well as the ones that are being scheduled for future execution only.
797    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status>
798    #[serde(rename = "txpool_status", with = "empty_params")]
799    TxPoolStatus(()),
800
801    /// Returns a summary of all the transactions currently pending for inclusion in the next
802    /// block(s), as well as the ones that are being scheduled for future execution only.
803    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect>
804    #[serde(rename = "txpool_inspect", with = "empty_params")]
805    TxPoolInspect(()),
806
807    /// Returns the details of all transactions currently pending for inclusion in the next
808    /// block(s), as well as the ones that are being scheduled for future execution only.
809    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content>
810    #[serde(rename = "txpool_content", with = "empty_params")]
811    TxPoolContent(()),
812
813    /// Returns the details of all transactions currently pending for inclusion in the next
814    /// block(s), as well as the ones that are being scheduled for future execution only, filtered
815    /// by sender.
816    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom>
817    #[serde(rename = "txpool_contentFrom", with = "sequence")]
818    TxPoolContentFrom(Address),
819
820    /// Otterscan's `ots_getApiLevel` endpoint
821    /// Otterscan currently requires this endpoint, even though it's not part of the ots_*
822    /// <https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71>
823    /// Related upstream issue: <https://github.com/otterscan/otterscan/issues/1081>
824    #[serde(rename = "erigon_getHeaderByNumber")]
825    ErigonGetHeaderByNumber(
826        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq")] BlockNumber,
827    ),
828
829    /// Otterscan's `ots_getApiLevel` endpoint
830    /// Used as a simple API versioning scheme for the ots_* namespace
831    #[serde(rename = "ots_getApiLevel", with = "empty_params")]
832    OtsGetApiLevel(()),
833
834    /// Otterscan's `ots_getInternalOperations` endpoint
835    /// Traces internal ETH transfers, contracts creation (CREATE/CREATE2) and self-destructs for a
836    /// certain transaction.
837    #[serde(rename = "ots_getInternalOperations", with = "sequence")]
838    OtsGetInternalOperations(B256),
839
840    /// Otterscan's `ots_hasCode` endpoint
841    /// Check if an ETH address contains code at a certain block number.
842    #[serde(rename = "ots_hasCode")]
843    OtsHasCode(
844        Address,
845        #[serde(deserialize_with = "lenient_block_number::lenient_block_number", default)]
846        BlockNumber,
847    ),
848
849    /// Otterscan's `ots_traceTransaction` endpoint
850    /// Trace a transaction and generate a trace call tree.
851    #[serde(rename = "ots_traceTransaction", with = "sequence")]
852    OtsTraceTransaction(B256),
853
854    /// Otterscan's `ots_getTransactionError` endpoint
855    /// Given a transaction hash, returns its raw revert reason.
856    #[serde(rename = "ots_getTransactionError", with = "sequence")]
857    OtsGetTransactionError(B256),
858
859    /// Otterscan's `ots_getBlockDetails` endpoint
860    /// Given a block number, return its data. Similar to the standard eth_getBlockByNumber/Hash
861    /// method, but can be optimized by excluding unnecessary data such as transactions and
862    /// logBloom
863    #[serde(rename = "ots_getBlockDetails")]
864    OtsGetBlockDetails(
865        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq", default)]
866        BlockNumber,
867    ),
868
869    /// Otterscan's `ots_getBlockDetails` endpoint
870    /// Same as `ots_getBlockDetails`, but receiving a block hash instead of number
871    #[serde(rename = "ots_getBlockDetailsByHash", with = "sequence")]
872    OtsGetBlockDetailsByHash(B256),
873
874    /// Otterscan's `ots_getBlockTransactions` endpoint
875    /// Gets paginated transaction data for a certain block. Return data is similar to
876    /// eth_getBlockBy* + eth_getTransactionReceipt.
877    #[serde(rename = "ots_getBlockTransactions")]
878    OtsGetBlockTransactions(u64, usize, usize),
879
880    /// Otterscan's `ots_searchTransactionsBefore` endpoint
881    /// Address history navigation. searches backwards from certain point in time.
882    #[serde(rename = "ots_searchTransactionsBefore")]
883    OtsSearchTransactionsBefore(Address, u64, usize),
884
885    /// Otterscan's `ots_searchTransactionsAfter` endpoint
886    /// Address history navigation. searches forward from certain point in time.
887    #[serde(rename = "ots_searchTransactionsAfter")]
888    OtsSearchTransactionsAfter(Address, u64, usize),
889
890    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
891    /// Given a sender address and a nonce, returns the tx hash or null if not found. It returns
892    /// only the tx hash on success, you can use the standard eth_getTransactionByHash after that
893    /// to get the full transaction data.
894    #[serde(rename = "ots_getTransactionBySenderAndNonce")]
895    OtsGetTransactionBySenderAndNonce(
896        Address,
897        #[serde(deserialize_with = "deserialize_number")] U256,
898    ),
899
900    /// Returns the transaction by sender and nonce
901    /// Returns the full transaction data.
902    #[serde(rename = "eth_getTransactionBySenderAndNonce")]
903    EthGetTransactionBySenderAndNonce(
904        Address,
905        #[serde(deserialize_with = "deserialize_number")] U256,
906    ),
907
908    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
909    /// Given an ETH contract address, returns the tx hash and the direct address who created the
910    /// contract.
911    #[serde(rename = "ots_getContractCreator", with = "sequence")]
912    OtsGetContractCreator(Address),
913
914    /// Removes transactions from the pool by sender origin.
915    #[serde(rename = "anvil_removePoolTransactions", with = "sequence")]
916    RemovePoolTransactions(Address),
917
918    /// Reorg the chain
919    #[serde(rename = "anvil_reorg")]
920    Reorg(ReorgOptions),
921
922    /// Rollback the chain
923    #[serde(rename = "anvil_rollback", deserialize_with = "deserialize_u64_seq_opt")]
924    Rollback(Option<u64>),
925
926    /// Sets the fee token for a user (Tempo-only)
927    #[serde(rename = "anvil_setFeeToken")]
928    SetFeeToken(Address, Address),
929
930    /// Sets the fee token for a validator (Tempo-only)
931    #[serde(rename = "anvil_setValidatorFeeToken")]
932    SetValidatorFeeToken(Address, Address),
933
934    /// Mints FeeAMM liquidity for a token pair (Tempo-only)
935    #[serde(rename = "anvil_setFeeAmmLiquidity")]
936    SetFeeAmmLiquidity(
937        /// user_token
938        Address,
939        /// validator_token
940        Address,
941        /// amount
942        #[serde(deserialize_with = "deserialize_number")]
943        U256,
944    ),
945
946    /// Returns a Tempo finalization certificate and its native block.
947    #[serde(rename = "consensus_getFinalization", with = "sequence")]
948    ConsensusGetFinalization(TempoConsensusQuery),
949
950    /// Returns the latest local Tempo consensus state.
951    #[serde(rename = "consensus_getLatest", with = "empty_params")]
952    ConsensusGetLatest(()),
953
954    /// Returns the public development consensus identity (Tempo-only).
955    #[serde(rename = "anvil_tempoConsensusIdentity", with = "empty_params")]
956    TempoConsensusIdentity(()),
957
958    /// Schedules a new development consensus identity (Tempo-only).
959    #[serde(rename = "anvil_tempoRotateConsensusIdentity", with = "empty_params")]
960    TempoRotateConsensusIdentity(()),
961}
962
963/// Native Tempo consensus selector: `"latest"` or `{"height": N}` with a numeric height.
964#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Deserialize)]
965#[serde(rename_all = "camelCase")]
966pub enum TempoConsensusQuery {
967    /// The latest locally certified block.
968    Latest,
969    /// A specific block height.
970    Height(u64),
971}
972
973/// Represents ethereum JSON-RPC API
974#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
975#[serde(tag = "method", content = "params")]
976pub enum EthPubSub {
977    /// Subscribe to an eth subscription
978    #[serde(rename = "eth_subscribe")]
979    EthSubscribe(SubscriptionKind, #[serde(default)] Box<SubscriptionParams>),
980
981    /// Unsubscribe from an eth subscription
982    #[serde(rename = "eth_unsubscribe", with = "sequence")]
983    EthUnSubscribe(SubscriptionId),
984}
985
986/// Container type for either a request or a pub sub
987#[derive(Clone, Debug)]
988pub enum EthRpcCall {
989    Request(Box<EthRequest>),
990    PubSub(EthPubSub),
991}
992
993impl<'de> serde::Deserialize<'de> for EthRpcCall {
994    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
995    where
996        D: serde::Deserializer<'de>,
997    {
998        let value = serde_json::Value::deserialize(deserializer)?;
999        match value.get("method").and_then(serde_json::Value::as_str) {
1000            Some("eth_subscribe" | "eth_unsubscribe") => serde_json::from_value(value)
1001                .map(Self::PubSub)
1002                .map_err(<D::Error as serde::de::Error>::custom),
1003            _ => serde_json::from_value(value)
1004                .map(Box::new)
1005                .map(Self::Request)
1006                .map_err(<D::Error as serde::de::Error>::custom),
1007        }
1008    }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013    use super::*;
1014
1015    #[test]
1016    fn test_web3_client_version() {
1017        let s = r#"{"method": "web3_clientVersion", "params":[]}"#;
1018        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1019        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1020    }
1021
1022    #[test]
1023    fn test_web3_sha3() {
1024        let s = r#"{"method": "web3_sha3", "params":["0x68656c6c6f20776f726c64"]}"#;
1025        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1026        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1027    }
1028
1029    #[test]
1030    fn unknown_rpc_call_preserves_method_error() {
1031        let err = serde_json::from_str::<EthRpcCall>(r#"{"method":"no_such_method","params":[]}"#)
1032            .unwrap_err();
1033
1034        assert!(err.to_string().contains("unknown variant"));
1035    }
1036
1037    #[test]
1038    fn test_eth_accounts() {
1039        let s = r#"{"method": "eth_accounts", "params":[]}"#;
1040        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1041        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1042    }
1043
1044    #[test]
1045    fn test_eth_network_id() {
1046        let s = r#"{"method": "eth_networkId", "params":[]}"#;
1047        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1048        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1049    }
1050
1051    #[test]
1052    fn test_eth_get_proof() {
1053        let s = r#"{"method":"eth_getProof","params":["0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842",["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"],"latest"]}"#;
1054        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1055        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1056    }
1057
1058    #[test]
1059    fn test_eth_chain_id() {
1060        let s = r#"{"method": "eth_chainId", "params":[]}"#;
1061        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1062        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1063    }
1064
1065    #[test]
1066    fn test_net_listening() {
1067        let s = r#"{"method": "net_listening", "params":[]}"#;
1068        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1069        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1070    }
1071
1072    #[test]
1073    fn test_eth_block_number() {
1074        let s = r#"{"method": "eth_blockNumber", "params":[]}"#;
1075        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1076        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1077    }
1078
1079    #[test]
1080    fn test_eth_pending_transactions() {
1081        let s = r#"{"method": "eth_pendingTransactions", "params":[]}"#;
1082        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1083        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1084    }
1085
1086    #[test]
1087    fn test_eth_create_access_list_with_state_override() {
1088        let s = r#"{"method":"eth_createAccessList","params":[{"to":"0x0000000000000000000000000000000000000001"},"latest",{"0x0000000000000000000000000000000000000001":{"code":"0x60005400"}}]}"#;
1089        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1090        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1091    }
1092
1093    #[test]
1094    fn test_eth_get_header_by_hash() {
1095        let s = r#"{"method": "eth_getHeaderByHash", "params":["0x12e65af7b09d4e08ec0a7786ee606b1b6b710d3f9c39f73d7e065527e0e839d3"]}"#;
1096        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1097        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1098    }
1099
1100    #[test]
1101    fn test_txpool_content_from() {
1102        let address = "0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842";
1103        let s = format!(r#"{{"method": "txpool_contentFrom", "params":["{address}"]}}"#);
1104        let value: serde_json::Value = serde_json::from_str(&s).unwrap();
1105        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1106        match req {
1107            EthRequest::TxPoolContentFrom(from) => {
1108                assert_eq!(from, address.parse::<Address>().unwrap());
1109            }
1110            _ => unreachable!(),
1111        }
1112    }
1113
1114    #[test]
1115    fn test_eth_get_header_by_number() {
1116        let s = r#"{"method": "eth_getHeaderByNumber", "params":["latest"]}"#;
1117        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1118        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1119    }
1120
1121    #[test]
1122    fn test_eth_max_priority_fee() {
1123        let s = r#"{"method": "eth_maxPriorityFeePerGas", "params":[]}"#;
1124        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1125        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1126    }
1127
1128    #[test]
1129    fn test_eth_send_raw_transaction_sync() {
1130        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef"]}"#;
1131        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1132        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1133        match req {
1134            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1135                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1136                assert_eq!(timeout, None);
1137            }
1138            _ => unreachable!(),
1139        }
1140
1141        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef", null]}"#;
1142        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1143        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1144        match req {
1145            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1146                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1147                assert_eq!(timeout, None);
1148            }
1149            _ => unreachable!(),
1150        }
1151
1152        let s = r#"{"method": "eth_sendRawTransactionSync", "params":["0xdeadbeef", 1]}"#;
1153        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1154        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1155        match req {
1156            EthRequest::EthSendRawTransactionSync(tx, timeout) => {
1157                assert_eq!(tx, Bytes::from_static(&[0xde, 0xad, 0xbe, 0xef]));
1158                assert_eq!(timeout, Some(1));
1159            }
1160            _ => unreachable!(),
1161        }
1162    }
1163
1164    #[test]
1165    fn test_eth_base_fee() {
1166        let s = r#"{"method": "eth_baseFee", "params":[]}"#;
1167        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1168        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1169    }
1170
1171    #[test]
1172    fn test_eth_syncing() {
1173        let s = r#"{"method": "eth_syncing", "params":[]}"#;
1174        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1175        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1176    }
1177
1178    #[test]
1179    fn test_custom_impersonate_account() {
1180        let s = r#"{"method": "anvil_impersonateAccount", "params":
1181["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1182        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1183        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1184    }
1185
1186    #[test]
1187    fn test_custom_stop_impersonate_account() {
1188        let s = r#"{"method": "anvil_stopImpersonatingAccount",  "params":
1189["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
1190        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1191        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1192    }
1193
1194    #[test]
1195    fn test_custom_auto_impersonate_account() {
1196        let s = r#"{"method": "anvil_autoImpersonateAccount",  "params": [true]}"#;
1197        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1198        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1199    }
1200
1201    #[test]
1202    fn test_custom_get_automine() {
1203        let s = r#"{"method": "anvil_getAutomine", "params": []}"#;
1204        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1205        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1206    }
1207
1208    #[test]
1209    fn test_custom_get_last_block_wall_time() {
1210        let s = r#"{"method": "anvil_getLastBlockWallTime", "params": []}"#;
1211        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1212        assert!(matches!(
1213            serde_json::from_value::<EthRequest>(value).unwrap(),
1214            EthRequest::GetLastBlockWallTime(())
1215        ));
1216    }
1217
1218    #[test]
1219    fn test_custom_mine() {
1220        let s = r#"{"method": "anvil_mine", "params": []}"#;
1221        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1222        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1223        match req {
1224            EthRequest::Mine(num, time) => {
1225                assert!(num.is_none());
1226                assert!(time.is_none());
1227            }
1228            _ => unreachable!(),
1229        }
1230        let s = r#"{"method": "anvil_mine", "params":
1231["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1232        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1233        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1234        match req {
1235            EthRequest::Mine(num, time) => {
1236                assert!(num.is_some());
1237                assert!(time.is_none());
1238            }
1239            _ => unreachable!(),
1240        }
1241        let s = r#"{"method": "anvil_mine", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1242        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1243        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1244        match req {
1245            EthRequest::Mine(num, time) => {
1246                assert!(num.is_some());
1247                assert!(time.is_some());
1248            }
1249            _ => unreachable!(),
1250        }
1251    }
1252
1253    #[test]
1254    fn test_custom_auto_mine() {
1255        let s = r#"{"method": "anvil_setAutomine", "params": [false]}"#;
1256        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1257        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1258        let s = r#"{"method": "evm_setAutomine", "params": [false]}"#;
1259        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1260        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1261    }
1262
1263    #[test]
1264    fn test_custom_interval_mining() {
1265        let s = r#"{"method": "anvil_setIntervalMining", "params": [100]}"#;
1266        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1267        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1268        let s = r#"{"method": "evm_setIntervalMining", "params": [100]}"#;
1269        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1270        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1271    }
1272
1273    #[test]
1274    fn test_set_mining_paused() {
1275        let s = r#"{"method": "anvil_setMiningPaused", "params": [true]}"#;
1276        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1277        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1278        assert!(matches!(req, EthRequest::SetMiningPaused(true)));
1279    }
1280
1281    #[test]
1282    fn test_get_mining_paused() {
1283        let s = r#"{"method": "anvil_getMiningPaused", "params": []}"#;
1284        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1285        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1286        assert!(matches!(req, EthRequest::GetMiningPaused(())));
1287    }
1288
1289    #[test]
1290    fn test_numeric_params_accept_hex_and_decimal_strings() {
1291        // Standard JSON-RPC clients (web3.js / ethers / viem) encode numeric params as hex
1292        // strings. These methods keep their internal `u64` types, but use a U64-aware
1293        // deserializer for RPC params.
1294        let parse = |s: &str| {
1295            let value: serde_json::Value = serde_json::from_str(s).unwrap();
1296            serde_json::from_value::<EthRequest>(value)
1297        };
1298
1299        match parse(r#"{"method": "anvil_setIntervalMining", "params": [100]}"#).unwrap() {
1300            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1301            req => panic!("unexpected request: {req:?}"),
1302        }
1303        match parse(r#"{"method": "anvil_setIntervalMining", "params": 100}"#).unwrap() {
1304            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1305            req => panic!("unexpected request: {req:?}"),
1306        }
1307        match parse(r#"{"method": "anvil_setIntervalMining", "params": ["0x64"]}"#).unwrap() {
1308            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1309            req => panic!("unexpected request: {req:?}"),
1310        }
1311        match parse(r#"{"method": "anvil_setIntervalMining", "params": "0x64"}"#).unwrap() {
1312            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1313            req => panic!("unexpected request: {req:?}"),
1314        }
1315        match parse(r#"{"method": "anvil_setIntervalMining", "params": ["100"]}"#).unwrap() {
1316            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1317            req => panic!("unexpected request: {req:?}"),
1318        }
1319        match parse(r#"{"method": "anvil_setIntervalMining", "params": "100"}"#).unwrap() {
1320            EthRequest::SetIntervalMining(interval) => assert_eq!(interval, 100),
1321            req => panic!("unexpected request: {req:?}"),
1322        }
1323        match parse(r#"{"method": "anvil_setChainId", "params": ["0x539"]}"#).unwrap() {
1324            EthRequest::SetChainId(chain_id) => assert_eq!(chain_id, 1337),
1325            req => panic!("unexpected request: {req:?}"),
1326        }
1327        match parse(r#"{"method": "anvil_setBlockTimestampInterval", "params": ["0xa"]}"#).unwrap()
1328        {
1329            EthRequest::EvmSetBlockTimeStampInterval(interval) => assert_eq!(interval, 10),
1330            req => panic!("unexpected request: {req:?}"),
1331        }
1332        match parse(r#"{"method": "anvil_rollback", "params": ["0x5"]}"#).unwrap() {
1333            EthRequest::Rollback(depth) => assert_eq!(depth, Some(5)),
1334            req => panic!("unexpected request: {req:?}"),
1335        }
1336        match parse(r#"{"method": "anvil_rollback", "params": []}"#).unwrap() {
1337            EthRequest::Rollback(depth) => assert_eq!(depth, None),
1338            req => panic!("unexpected request: {req:?}"),
1339        }
1340        match parse(r#"{"method": "anvil_rollback", "params": [null]}"#).unwrap() {
1341            EthRequest::Rollback(depth) => assert_eq!(depth, None),
1342            req => panic!("unexpected request: {req:?}"),
1343        }
1344
1345        assert!(
1346            parse(r#"{"method": "anvil_setIntervalMining", "params": ["0x10000000000000000"]}"#)
1347                .is_err()
1348        );
1349    }
1350
1351    #[test]
1352    fn test_custom_drop_tx() {
1353        let s = r#"{"method": "anvil_dropTransaction", "params":
1354["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1355        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1356        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1357    }
1358
1359    #[test]
1360    fn test_custom_reset() {
1361        let s = r#"{"method": "anvil_reset", "params": [{"forking": {"jsonRpcUrl": "https://ethereumpublicnode.com",
1362        "blockNumber": "18441649"
1363      }
1364    }]}"#;
1365        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1366        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1367        match req {
1368            EthRequest::Reset(forking) => {
1369                let forking = forking.and_then(|f| f.params);
1370                assert_eq!(
1371                    forking,
1372                    Some(Forking {
1373                        json_rpc_url: Some("https://ethereumpublicnode.com".into()),
1374                        block_number: Some(18441649)
1375                    })
1376                )
1377            }
1378            _ => unreachable!(),
1379        }
1380
1381        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
1382                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>",
1383                "blockNumber": 11095000
1384        }}]}"#;
1385        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1386        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1387        match req {
1388            EthRequest::Reset(forking) => {
1389                let forking = forking.and_then(|f| f.params);
1390                assert_eq!(
1391                    forking,
1392                    Some(Forking {
1393                        json_rpc_url: Some(
1394                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
1395                        ),
1396                        block_number: Some(11095000)
1397                    })
1398                )
1399            }
1400            _ => unreachable!(),
1401        }
1402
1403        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
1404                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>"
1405        }}]}"#;
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 {
1414                        json_rpc_url: Some(
1415                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
1416                        ),
1417                        block_number: None
1418                    })
1419                )
1420            }
1421            _ => unreachable!(),
1422        }
1423
1424        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545", "blockNumber": 14000000}]}"#;
1425        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1426        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1427        match req {
1428            EthRequest::Reset(forking) => {
1429                let forking = forking.and_then(|f| f.params);
1430                assert_eq!(
1431                    forking,
1432                    Some(Forking {
1433                        json_rpc_url: Some("http://localhost:8545".to_string()),
1434                        block_number: Some(14000000)
1435                    })
1436                )
1437            }
1438            _ => unreachable!(),
1439        }
1440
1441        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": 14000000}]}"#;
1442        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1443        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1444        match req {
1445            EthRequest::Reset(forking) => {
1446                let forking = forking.and_then(|f| f.params);
1447                assert_eq!(
1448                    forking,
1449                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
1450                )
1451            }
1452            _ => unreachable!(),
1453        }
1454
1455        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": "14000000"}]}"#;
1456        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1457        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1458        match req {
1459            EthRequest::Reset(forking) => {
1460                let forking = forking.and_then(|f| f.params);
1461                assert_eq!(
1462                    forking,
1463                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
1464                )
1465            }
1466            _ => unreachable!(),
1467        }
1468
1469        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545"}]}"#;
1470        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1471        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1472        match req {
1473            EthRequest::Reset(forking) => {
1474                let forking = forking.and_then(|f| f.params);
1475                assert_eq!(
1476                    forking,
1477                    Some(Forking {
1478                        json_rpc_url: Some("http://localhost:8545".to_string()),
1479                        block_number: None
1480                    })
1481                )
1482            }
1483            _ => unreachable!(),
1484        }
1485
1486        let s = r#"{"method": "anvil_reset"}"#;
1487        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1488        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1489        match req {
1490            EthRequest::Reset(forking) => {
1491                assert!(forking.is_none())
1492            }
1493            _ => unreachable!(),
1494        }
1495    }
1496
1497    #[test]
1498    fn test_custom_set_balance() {
1499        let s = r#"{"method": "anvil_setBalance", "params":
1500["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1501        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1502        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1503
1504        let s = r#"{"method": "anvil_setBalance", "params":
1505["0xd84de507f3fada7df80908082d3239466db55a71", 1337]}"#;
1506        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1507        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1508    }
1509
1510    #[test]
1511    fn test_simulate_preserves_transaction_extension_fields() {
1512        let value = serde_json::json!({
1513            "method": "eth_simulateV1",
1514            "params": [{
1515                "blockStateCalls": [{
1516                    "calls": [{
1517                        "to": "0x0000000000000000000000000000000000000001",
1518                        "tempoExtension": "preserved"
1519                    }]
1520                }]
1521            }]
1522        });
1523
1524        let request = serde_json::from_value::<EthRequest>(value).unwrap();
1525        let EthRequest::EthSimulateV1(payload, _) = request else { panic!() };
1526        let transaction = &payload.block_state_calls[0].calls[0];
1527
1528        assert_eq!(transaction.other["tempoExtension"], serde_json::json!("preserved"));
1529    }
1530
1531    #[test]
1532    fn test_custom_set_code() {
1533        let s = r#"{"method": "anvil_setCode", "params":
1534["0xd84de507f3fada7df80908082d3239466db55a71", "0x0123456789abcdef"]}"#;
1535        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1536        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1537
1538        let s = r#"{"method": "anvil_setCode", "params":
1539["0xd84de507f3fada7df80908082d3239466db55a71", "0x"]}"#;
1540        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1541        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1542
1543        let s = r#"{"method": "anvil_setCode", "params":
1544["0xd84de507f3fada7df80908082d3239466db55a71", ""]}"#;
1545        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1546        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1547    }
1548
1549    #[test]
1550    fn test_custom_set_nonce() {
1551        let s = r#"{"method": "anvil_setNonce", "params":
1552["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1553        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1554        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1555        let s = r#"{"method":
1556"hardhat_setNonce", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1557        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1558        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1559        let s = r#"{"method": "evm_setAccountNonce", "params":
1560["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1561        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1562        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1563    }
1564
1565    #[test]
1566    fn test_serde_custom_set_storage_at() {
1567        let s = r#"{"method": "anvil_setStorageAt", "params":
1568["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0",
1569"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1570        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1571        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1572
1573        let s = r#"{"method": "hardhat_setStorageAt", "params":
1574["0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
1575"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
1576"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1577        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1578        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1579    }
1580
1581    #[test]
1582    fn test_serde_custom_coinbase() {
1583        let s = r#"{"method": "anvil_setCoinbase", "params":
1584["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#;
1585        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1586        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1587    }
1588
1589    #[test]
1590    fn test_serde_custom_set_next_block_prevrandao() {
1591        let s = r#"{"method": "anvil_setNextBlockPrevRandao", "params": ["0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]}"#;
1592        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1593        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1594    }
1595
1596    #[test]
1597    fn test_serde_custom_set_next_block_parent_beacon_block_root() {
1598        let s = r#"{"method": "anvil_setNextBlockParentBeaconBlockRoot", "params": ["0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]}"#;
1599        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1600        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1601    }
1602
1603    #[test]
1604    fn test_serde_custom_logging() {
1605        let s = r#"{"method": "anvil_setLoggingEnabled", "params": [false]}"#;
1606        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1607        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1608    }
1609
1610    #[test]
1611    fn test_serde_custom_min_gas_price() {
1612        let s = r#"{"method": "anvil_setMinGasPrice", "params": ["0x0"]}"#;
1613        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1614        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1615    }
1616
1617    #[test]
1618    fn test_serde_custom_next_block_base_fee() {
1619        let s = r#"{"method": "anvil_setNextBlockBaseFeePerGas", "params": ["0x0"]}"#;
1620        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1621        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1622    }
1623
1624    #[test]
1625    fn test_serde_set_time() {
1626        let s = r#"{"method": "anvil_setTime", "params": ["0x0"]}"#;
1627        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1628        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1629
1630        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1631        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1632        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1633    }
1634
1635    #[test]
1636    fn test_serde_custom_dump_state() {
1637        let s = r#"{"method": "anvil_dumpState", "params": [true]}"#;
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": "anvil_dumpState"}"#;
1642        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1643        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1644        match req {
1645            EthRequest::DumpState(param) => {
1646                assert!(param.is_none());
1647            }
1648            _ => unreachable!(),
1649        }
1650    }
1651
1652    #[test]
1653    fn test_serde_custom_load_state() {
1654        let s = r#"{"method": "anvil_loadState", "params": ["0x0001"] }"#;
1655        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1656        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1657    }
1658
1659    #[test]
1660    fn test_serde_custom_snapshot() {
1661        let s = r#"{"method": "anvil_snapshot", "params": [] }"#;
1662        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1663        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1664
1665        let s = r#"{"method": "evm_snapshot", "params": [] }"#;
1666        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1667        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1668    }
1669
1670    #[test]
1671    fn test_serde_custom_revert() {
1672        let s = r#"{"method": "anvil_revert", "params": ["0x0"]}"#;
1673        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1674        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1675    }
1676
1677    #[test]
1678    fn test_serde_custom_increase_time() {
1679        let s = r#"{"method": "anvil_increaseTime", "params": ["0x0"]}"#;
1680        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1681        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1682
1683        let s = r#"{"method": "anvil_increaseTime", "params": [1]}"#;
1684        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1685        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1686
1687        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1688        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1689        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1690
1691        let s = r#"{"method": "evm_increaseTime", "params": ["0x0"]}"#;
1692        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1693        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1694
1695        let s = r#"{"method": "evm_increaseTime", "params": [1]}"#;
1696        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1697        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1698
1699        let s = r#"{"method": "evm_increaseTime", "params": 1}"#;
1700        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1701        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1702    }
1703
1704    #[test]
1705    fn test_serde_custom_next_timestamp() {
1706        let s = r#"{"method": "anvil_setNextBlockTimestamp", "params": [100]}"#;
1707        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1708        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1709        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": [100]}"#;
1710        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1711        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1712        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": ["0x64e0f308"]}"#;
1713        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1714        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1715    }
1716
1717    #[test]
1718    fn test_serde_custom_timestamp_interval() {
1719        let s = r#"{"method": "anvil_setBlockTimestampInterval", "params": [100]}"#;
1720        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1721        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1722    }
1723
1724    #[test]
1725    fn test_serde_custom_remove_timestamp_interval() {
1726        let s = r#"{"method": "anvil_removeBlockTimestampInterval", "params": []}"#;
1727        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1728        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1729    }
1730
1731    #[test]
1732    fn test_serde_custom_evm_mine() {
1733        let s = r#"{"method": "evm_mine", "params": [100]}"#;
1734        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1735        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1736        let s = r#"{"method": "evm_mine", "params": [{
1737            "timestamp": 100,
1738            "blocks": 100
1739        }]}"#;
1740        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1741        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1742        match req {
1743            EthRequest::EvmMine(params) => {
1744                assert_eq!(
1745                    params.unwrap().params.unwrap_or_default(),
1746                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1747                )
1748            }
1749            _ => unreachable!(),
1750        }
1751
1752        let s = r#"{"method": "evm_mine"}"#;
1753        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1754        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1755
1756        match req {
1757            EthRequest::EvmMine(params) => {
1758                assert!(params.is_none())
1759            }
1760            _ => unreachable!(),
1761        }
1762
1763        let s = r#"{"method": "evm_mine", "params": []}"#;
1764        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1765        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1766    }
1767
1768    #[test]
1769    fn test_serde_custom_evm_mine_detailed() {
1770        let s = r#"{"method": "anvil_mine_detailed", "params": [100]}"#;
1771        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1772        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1773        let s = r#"{"method": "anvil_mine_detailed", "params": [{
1774            "timestamp": 100,
1775            "blocks": 100
1776        }]}"#;
1777        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1778        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1779        match req {
1780            EthRequest::EvmMineDetailed(params) => {
1781                assert_eq!(
1782                    params.unwrap().params.unwrap_or_default(),
1783                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1784                )
1785            }
1786            _ => unreachable!(),
1787        }
1788
1789        let s = r#"{"method": "evm_mine_detailed"}"#;
1790        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1791        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1792
1793        match req {
1794            EthRequest::EvmMineDetailed(params) => {
1795                assert!(params.is_none())
1796            }
1797            _ => unreachable!(),
1798        }
1799
1800        let s = r#"{"method": "anvil_mine_detailed", "params": []}"#;
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_serde_custom_evm_mine_hex() {
1807        let s = r#"{"method": "evm_mine", "params": ["0x63b6ff08"]}"#;
1808        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1809        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1810        match req {
1811            EthRequest::EvmMine(params) => {
1812                assert_eq!(
1813                    params.unwrap().params.unwrap_or_default(),
1814                    MineOptions::Timestamp(Some(1672937224))
1815                )
1816            }
1817            _ => unreachable!(),
1818        }
1819
1820        let s = r#"{"method": "evm_mine", "params": [{"timestamp": "0x63b6ff08"}]}"#;
1821        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1822        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1823        match req {
1824            EthRequest::EvmMine(params) => {
1825                assert_eq!(
1826                    params.unwrap().params.unwrap_or_default(),
1827                    MineOptions::Options { timestamp: Some(1672937224), blocks: None }
1828                )
1829            }
1830            _ => unreachable!(),
1831        }
1832    }
1833
1834    #[test]
1835    fn test_eth_uncle_count_by_block_hash() {
1836        let s = r#"{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1837        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1838        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1839    }
1840
1841    #[test]
1842    fn test_eth_block_tx_count_by_block_hash() {
1843        let s = r#"{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1844        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1845        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1846    }
1847
1848    #[test]
1849    fn test_eth_get_logs() {
1850        let s = r#"{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}"#;
1851        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1852        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1853    }
1854
1855    #[test]
1856    fn test_eth_new_filter() {
1857        let s = r#"{"method": "eth_newFilter", "params": [{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":73}"#;
1858        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1859        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1860    }
1861
1862    #[test]
1863    fn test_serde_raw_transaction_conditional() {
1864        let s = r#"{"method": "eth_sendRawTransactionConditional", "params":
1865["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"knownAccounts":{}}]}"#;
1866        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1867        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1868    }
1869
1870    #[test]
1871    fn test_eth_new_pending_transaction_filter() {
1872        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[],"id":73}"#;
1873        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1874        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1875        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(None)));
1876
1877        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[null],"id":73}"#;
1878        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1879        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1880        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(None)));
1881
1882        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[false],"id":73}"#;
1883        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1884        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1885        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(Some(false))));
1886
1887        let s = r#"{"method": "eth_newPendingTransactionFilter", "params":[true],"id":73}"#;
1888        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1889        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1890        assert!(matches!(req, EthRequest::EthNewPendingTransactionFilter(Some(true))));
1891    }
1892
1893    #[test]
1894    fn test_serde_eth_unsubscribe() {
1895        let s = r#"{"id": 1, "method": "eth_unsubscribe", "params":
1896["0x9cef478923ff08bf67fde6c64013158d"]}"#;
1897        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1898        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1899    }
1900
1901    #[test]
1902    fn test_serde_eth_subscribe() {
1903        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}"#;
1904        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1905        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1906        assert!(matches!(serde_json::from_str(s).unwrap(), EthRpcCall::PubSub(_)));
1907
1908        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["logs", {"address":
1909"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics":
1910["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}"#;
1911        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1912        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1913
1914        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}"#;
1915        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1916        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1917
1918        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["syncing"]}"#;
1919        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1920        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1921    }
1922
1923    #[test]
1924    fn test_serde_debug_raw_transaction() {
1925        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransaction","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1926        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1927        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1928
1929        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByHash","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1930        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1931        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1932
1933        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockHashAndIndex","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c",1],"id":1}"#;
1934        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1935        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1936
1937        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockNumberAndIndex","params":["0x3ed3a89b",0],"id":1}"#;
1938        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1939        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1940    }
1941
1942    #[test]
1943    fn test_serde_debug_raw_receipts() {
1944        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawReceipts","params":["latest"],"id":1}"#;
1945        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1946        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1947
1948        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawReceipts","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1949        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1950        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1951    }
1952
1953    #[test]
1954    fn test_serde_debug_raw_transactions() {
1955        let s =
1956            r#"{"jsonrpc":"2.0","method":"debug_getRawTransactions","params":["latest"],"id":1}"#;
1957        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1958        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1959
1960        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransactions","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1961        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1962        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1963    }
1964
1965    #[test]
1966    fn test_serde_debug_raw_header() {
1967        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawHeader","params":["latest"],"id":1}"#;
1968        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1969        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1970
1971        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawHeader","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1972        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1973        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1974    }
1975
1976    #[test]
1977    fn test_serde_debug_raw_block() {
1978        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawBlock","params":["latest"],"id":1}"#;
1979        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1980        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1981
1982        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawBlock","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1983        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1984        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1985    }
1986
1987    #[test]
1988    fn test_serde_debug_clear_txpool() {
1989        let s = r#"{"jsonrpc":"2.0","method":"debug_clearTxpool","params":[],"id":1}"#;
1990        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1991        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1992    }
1993
1994    #[test]
1995    fn test_serde_debug_trace_transaction() {
1996        let s = r#"{"method": "debug_traceTransaction", "params":
1997["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1998        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1999        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2000
2001        let s = r#"{"method": "debug_traceTransaction", "params":
2002["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {}]}"#;
2003        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2004        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2005
2006        let s = r#"{"method": "debug_traceTransaction", "params":
2007["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"disableStorage":
2008true}]}"#;
2009        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2010        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2011    }
2012
2013    #[test]
2014    fn test_serde_debug_account_info_at() {
2015        let s = r#"{"method": "debug_accountInfoAt", "params": ["0x1", "0x0", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
2016        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2017        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2018
2019        let s = r#"{"method": "debug_accountInfoAt", "params": [{"blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"}, 0, "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
2020        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2021        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2022    }
2023
2024    #[test]
2025    fn test_serde_debug_execution_witness() {
2026        let s = r#"{"method": "debug_executionWitness", "params": ["0x1"]}"#;
2027        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2028        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2029
2030        let s = r#"{"method": "debug_executionWitness", "params": ["latest"]}"#;
2031        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2032        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2033    }
2034
2035    #[test]
2036    fn test_serde_trace_transaction_opcode_gas() {
2037        let s = r#"{"method": "trace_transactionOpcodeGas", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
2038        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2039        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2040    }
2041
2042    #[test]
2043    fn test_serde_trace_replay_transaction() {
2044        let s = r#"{"method":"trace_replayTransaction","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff",["trace","stateDiff"]]}"#;
2045        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2046        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2047    }
2048
2049    #[test]
2050    fn test_serde_trace_block_opcode_gas() {
2051        let s = r#"{"method": "trace_blockOpcodeGas", "params": ["0x1"]}"#;
2052        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2053        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2054
2055        let s = r#"{"method": "trace_blockOpcodeGas", "params": [{"blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"}]}"#;
2056        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2057        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2058    }
2059
2060    #[test]
2061    fn test_serde_trace_raw_transaction() {
2062        let s = r#"{"method": "trace_rawTransaction", "params": ["0x02f866827a690a65648252089470997970c51812dc3a010c7d01b50e0d17dc79c88203e980c001a0e4de88aefcf87ccb04466e60de66a83192e46aa26177d5ea35efbfd43fd0ecdca00e3148e0e8e0b9a6f9b329efd6e30c4a461920f3a27497be3dbefaba996601da", ["trace"]]}"#;
2063        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2064        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2065
2066        let s = r#"{"method": "trace_rawTransaction", "params": ["0x02f866827a690a65648252089470997970c51812dc3a010c7d01b50e0d17dc79c88203e980c001a0e4de88aefcf87ccb04466e60de66a83192e46aa26177d5ea35efbfd43fd0ecdca00e3148e0e8e0b9a6f9b329efd6e30c4a461920f3a27497be3dbefaba996601da", ["trace", "stateDiff", "vmTrace"], "latest"]}"#;
2067        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2068        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2069    }
2070
2071    #[test]
2072    fn test_serde_debug_trace_call() {
2073        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2074        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2075        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2076
2077        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
2078        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2079        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2080
2081        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
2082        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2083        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2084
2085        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
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": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }, {"disableStorage": true}]}"#;
2090        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2091        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2092
2093        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x1" }, {"txIndex": "0x0"}]}"#;
2094        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2095        let req = serde_json::from_value::<EthRequest>(value).unwrap();
2096        match req {
2097            EthRequest::DebugTraceCall(_, _, opts) => assert_eq!(opts.tx_index, Some(0)),
2098            _ => panic!("expected debug_traceCall"),
2099        }
2100    }
2101
2102    #[test]
2103    fn test_serde_debug_get_modified_accounts_by_number() {
2104        let s = r#"{"method": "debug_getModifiedAccountsByNumber", "params": [0, 1]}"#;
2105        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2106        match serde_json::from_value::<EthRequest>(value).unwrap() {
2107            EthRequest::DebugGetModifiedAccountsByNumber(0, 1) => {}
2108            req => panic!("unexpected request: {req:?}"),
2109        }
2110    }
2111
2112    #[test]
2113    fn test_serde_debug_free_os_memory() {
2114        let s = r#"{"method": "debug_freeOSMemory", "params": []}"#;
2115        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2116        match serde_json::from_value::<EthRequest>(value).unwrap() {
2117            EthRequest::DebugFreeOsMemory(()) => {}
2118            req => panic!("unexpected request: {req:?}"),
2119        }
2120    }
2121
2122    #[test]
2123    fn test_serde_trace_call() {
2124        let s = r#"{"method": "trace_call", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, ["trace", "stateDiff"], "latest"]}"#;
2125        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2126        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2127
2128        let s = r#"{"method": "trace_call", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2129        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2130        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2131    }
2132
2133    #[test]
2134    fn test_serde_trace_call_many() {
2135        let s = r#"{"method": "trace_callMany", "params": [[[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","value":"0x1"}, ["trace"]], [{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","value":"0x2"}, ["trace", "stateDiff"]]]]}"#;
2136        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2137        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2138
2139        let s = r#"{"method": "trace_callMany", "params": [[[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, ["trace"]]], "latest"]}"#;
2140        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2141        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2142    }
2143
2144    #[test]
2145    fn test_serde_trace_get() {
2146        let s = r#"{"method": "trace_get", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", ["0x6", "0xa0"]]}"#;
2147        let req = serde_json::from_str::<EthRequest>(s).unwrap();
2148        let EthRequest::TraceGet(_, indices) = req else { panic!("unexpected request {req:?}") };
2149        assert_eq!(indices.into_iter().map(usize::from).collect::<Vec<_>>(), [6, 160]);
2150
2151        for indices in
2152            [r#"[6, 0]"#, r#"["6"]"#, r#"["0x00"]"#, r#"["0x06"]"#, r#"["0xA"]"#, r#"["0x"]"#]
2153        {
2154            let s = format!(
2155                r#"{{"method": "trace_get", "params": ["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {indices}]}}"#
2156            );
2157            serde_json::from_str::<EthRequest>(&s).unwrap_err();
2158        }
2159    }
2160
2161    #[test]
2162    fn test_serde_debug_trace_block() {
2163        let s = r#"{"method":"debug_traceBlock","params":["0xc0",{"tracer":"callTracer"}]}"#;
2164        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2165        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2166    }
2167
2168    #[test]
2169    fn test_serde_eth_storage() {
2170        let s = r#"{"method": "eth_getStorageAt", "params":
2171["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"]}"#;
2172        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2173        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2174    }
2175
2176    #[test]
2177    fn test_serde_state_requests_without_block() {
2178        let requests = [
2179            r#"{"method":"eth_getBalance","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2180            r#"{"method":"eth_getCode","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2181            r#"{"method":"eth_getStorageAt","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251","0x0"]}"#,
2182            r#"{"method":"eth_getStorageValues","params":[{"0x295a70b2de5e3953354a6a8344e616ed314d7251":["0x0000000000000000000000000000000000000000000000000000000000000000"]}]}"#,
2183            r#"{"method":"eth_getTransactionCount","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#,
2184            r#"{"method":"eth_getProof","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251",[]]}"#,
2185        ];
2186
2187        for request in requests {
2188            if let EthRequest::EthGetTransactionCount(params) =
2189                serde_json::from_str::<EthRequest>(request).unwrap()
2190            {
2191                let (_, block, nonce_key) = params.into_parts();
2192                assert!(block.is_none());
2193                assert!(nonce_key.is_none());
2194                continue;
2195            }
2196            assert!(matches!(
2197                serde_json::from_str::<EthRequest>(request).unwrap(),
2198                EthRequest::EthGetBalance(_, None)
2199                    | EthRequest::EthGetCodeAt(_, None)
2200                    | EthRequest::EthGetStorageAt(_, _, None)
2201                    | EthRequest::EthGetStorageValues(_, None)
2202                    | EthRequest::EthGetProof(_, _, None)
2203            ));
2204        }
2205    }
2206
2207    #[test]
2208    fn test_serde_transaction_count_nonce_key_is_base_gated() {
2209        let request = r#"{"method":"eth_getTransactionCount","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251","latest","0x7"]}"#;
2210        let result = serde_json::from_str::<EthRequest>(request);
2211
2212        #[cfg(feature = "base")]
2213        {
2214            let EthRequest::EthGetTransactionCount(params) = result.unwrap() else {
2215                panic!("unexpected request variant")
2216            };
2217            let (_, block, nonce_key) = params.into_parts();
2218            assert_eq!(block, Some(BlockId::latest()));
2219            assert_eq!(nonce_key, Some(U256::from(7)));
2220        }
2221        #[cfg(not(feature = "base"))]
2222        assert!(result.is_err());
2223    }
2224
2225    #[test]
2226    fn test_eth_call() {
2227        let req = r#"{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}"#;
2228        let _req = serde_json::from_str::<TransactionRequest>(req).unwrap();
2229
2230        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"},"latest"]}"#;
2231        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2232
2233        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
2234        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2235
2236        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
2237        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2238
2239        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
2240        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2241
2242        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
2243        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2244    }
2245
2246    #[test]
2247    fn test_eth_call_many() {
2248        let s = r#"{"method":"eth_callMany","params":[[{"transactions":[{"from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d","data":"0xcfae3217"}]}],{"blockNumber":"latest"},{"0x0000000000000000000000000000000000000001":{"balance":"0x1"}}]}"#;
2249        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2250    }
2251
2252    #[test]
2253    fn test_eth_call_bundle() {
2254        let s = r#"{"method":"eth_callBundle","params":[{"txs":["0x1234"],"blockNumber":"0x1","stateBlockNumber":"latest"}]}"#;
2255        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
2256    }
2257
2258    #[test]
2259    fn test_serde_eth_balance() {
2260        let s = r#"{"method": "eth_getBalance", "params":
2261["0x295a70b2de5e3953354a6a8344e616ed314d7251", "latest"]}"#;
2262        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2263
2264        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2265    }
2266
2267    #[test]
2268    fn test_serde_eth_block_by_number() {
2269        let s = r#"{"method": "eth_getBlockByNumber", "params": ["0x0", true]}"#;
2270        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2271        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2272        let s = r#"{"method": "eth_getBlockByNumber", "params": ["latest", true]}"#;
2273        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2274        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2275        let s = r#"{"method": "eth_getBlockByNumber", "params": ["earliest", true]}"#;
2276        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2277        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2278        let s = r#"{"method": "eth_getBlockByNumber", "params": ["pending", true]}"#;
2279        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2280        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2281
2282        // this case deviates from the spec, but we're supporting this for legacy reasons: <https://github.com/foundry-rs/foundry/issues/1868>
2283        let s = r#"{"method": "eth_getBlockByNumber", "params": [0, true]}"#;
2284        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2285        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2286    }
2287
2288    #[test]
2289    fn test_eth_sign() {
2290        let s = r#"{"method": "eth_sign", "params":
2291["0xd84de507f3fada7df80908082d3239466db55a71", "0x00"]}"#;
2292        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2293        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2294        let s = r#"{"method": "personal_sign", "params":
2295["0x00", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
2296        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2297        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2298    }
2299
2300    #[test]
2301    fn test_eth_sign_typed_data() {
2302        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!"}}]}"#;
2303        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2304        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2305    }
2306
2307    #[test]
2308    fn test_remove_pool_transactions() {
2309        let s = r#"{"method": "anvil_removePoolTransactions",  "params":["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
2310        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2311        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2312    }
2313
2314    #[test]
2315    fn test_serde_anvil_reorg() {
2316        // TransactionData::JSON
2317        let s = r#"
2318        {
2319            "method": "anvil_reorg",
2320            "params": [
2321                5,
2322                [
2323                    [
2324                        {
2325                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2326                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2327                            "value": 100
2328                        },
2329                        1
2330                    ],
2331                    [
2332                        {
2333                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2334                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2335                            "value": 200
2336                        },
2337                        2
2338                    ]
2339                ]
2340            ]
2341        }
2342        "#;
2343        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2344        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2345        // TransactionData::Raw
2346        let s = r#"
2347        {
2348            "method": "anvil_reorg",
2349            "params": [
2350                5,
2351                [
2352                    [
2353                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
2354                        1
2355                    ]
2356                ]
2357            ]
2358        }
2359        "#;
2360        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2361        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2362        // TransactionData::Raw and TransactionData::JSON
2363        let s = r#"
2364        {
2365            "method": "anvil_reorg",
2366            "params": [
2367                5,
2368                [
2369                    [
2370                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
2371                        1
2372                    ],
2373                    [
2374                        {
2375                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
2376                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
2377                            "value": 200
2378                        },
2379                        2
2380                    ]
2381                ]
2382            ]
2383        }
2384        "#;
2385        let value: serde_json::Value = serde_json::from_str(s).unwrap();
2386        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
2387    }
2388
2389    #[test]
2390    fn tempo_consensus_requests() {
2391        for request in [
2392            r#"{"method":"consensus_getFinalization","params":["latest"]}"#,
2393            r#"{"method":"consensus_getFinalization","params":[{"height":0}]}"#,
2394            r#"{"method":"consensus_getFinalization","params":[{"height":18446744073709551615}]}"#,
2395            r#"{"method":"consensus_getLatest","params":[]}"#,
2396            r#"{"method":"anvil_tempoConsensusIdentity","params":[]}"#,
2397            r#"{"method":"anvil_tempoRotateConsensusIdentity","params":[]}"#,
2398        ] {
2399            serde_json::from_str::<EthRequest>(request).unwrap();
2400        }
2401        for request in [
2402            r#"{"method":"consensus_getFinalization","params":["Latest"]}"#,
2403            r#"{"method":"consensus_getFinalization","params":["pending"]}"#,
2404            r#"{"method":"consensus_getFinalization","params":[{"height":"0x1"}]}"#,
2405            r#"{"method":"consensus_getFinalization","params":[{"height":-1}]}"#,
2406            r#"{"method":"consensus_getFinalization","params":[{"height":18446744073709551616}]}"#,
2407            r#"{"method":"consensus_getFinalization","params":[]}"#,
2408            r#"{"method":"consensus_getFinalization","params":["latest",1]}"#,
2409            r#"{"method":"consensus_getLatest","params":[1]}"#,
2410            r#"{"method":"anvil_tempoRotateConsensusIdentity","params":[1]}"#,
2411        ] {
2412            assert!(serde_json::from_str::<EthRequest>(request).is_err(), "{request}");
2413        }
2414    }
2415}