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