anvil_core/eth/
mod.rs

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