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
325    /// Registers a signature/address pair for faking `ecrecover` results
326    #[serde(rename = "anvil_impersonateSignature", with = "sequence")]
327    ImpersonateSignature(Bytes, Address),
328
329    /// Returns true if automatic mining is enabled, and false.
330    #[serde(rename = "anvil_getAutomine", alias = "hardhat_getAutomine", with = "empty_params")]
331    GetAutoMine(()),
332    /// Mines a series of blocks
333    #[serde(rename = "anvil_mine", alias = "hardhat_mine")]
334    Mine(
335        /// Number of blocks to mine, if not set `1` block is mined
336        #[serde(default, deserialize_with = "deserialize_number_opt")]
337        Option<U256>,
338        /// The time interval between each block in seconds, defaults to `1` seconds
339        /// The interval is applied only to blocks mined in the given method invocation, not to
340        /// blocks mined afterwards. Set this to `0` to instantly mine _all_ blocks
341        #[serde(default, deserialize_with = "deserialize_number_opt")]
342        Option<U256>,
343    ),
344
345    /// Enables or disables, based on the single boolean argument, the automatic mining of new
346    /// blocks with each new transaction submitted to the network.
347    #[serde(rename = "anvil_setAutomine", alias = "evm_setAutomine", with = "sequence")]
348    SetAutomine(bool),
349
350    /// Sets the mining behavior to interval with the given interval (seconds)
351    #[serde(rename = "anvil_setIntervalMining", alias = "evm_setIntervalMining", with = "sequence")]
352    SetIntervalMining(u64),
353
354    /// Gets the current mining behavior
355    #[serde(rename = "anvil_getIntervalMining", with = "empty_params")]
356    GetIntervalMining(()),
357
358    /// Removes transactions from the pool
359    #[serde(rename = "anvil_dropTransaction", alias = "hardhat_dropTransaction", with = "sequence")]
360    DropTransaction(B256),
361
362    /// Removes transactions from the pool
363    #[serde(
364        rename = "anvil_dropAllTransactions",
365        alias = "hardhat_dropAllTransactions",
366        with = "empty_params"
367    )]
368    DropAllTransactions(),
369
370    /// Reset the fork to a fresh forked state, and optionally update the fork config
371    #[serde(rename = "anvil_reset", alias = "hardhat_reset")]
372    Reset(#[serde(default)] Option<Params<Option<Forking>>>),
373
374    /// Sets the backend rpc url
375    #[serde(rename = "anvil_setRpcUrl", with = "sequence")]
376    SetRpcUrl(String),
377
378    /// Modifies the balance of an account.
379    #[serde(
380        rename = "anvil_setBalance",
381        alias = "hardhat_setBalance",
382        alias = "tenderly_setBalance"
383    )]
384    SetBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
385
386    /// Increases the balance of an account.
387    #[serde(
388        rename = "anvil_addBalance",
389        alias = "hardhat_addBalance",
390        alias = "tenderly_addBalance"
391    )]
392    AddBalance(Address, #[serde(deserialize_with = "deserialize_number")] U256),
393
394    /// Modifies the ERC20 balance of an account.
395    #[serde(
396        rename = "anvil_dealERC20",
397        alias = "hardhat_dealERC20",
398        alias = "anvil_setERC20Balance"
399    )]
400    DealERC20(Address, Address, #[serde(deserialize_with = "deserialize_number")] U256),
401
402    /// Sets the ERC20 allowance for a spender
403    #[serde(rename = "anvil_setERC20Allowance")]
404    SetERC20Allowance(
405        Address,
406        Address,
407        Address,
408        #[serde(deserialize_with = "deserialize_number")] U256,
409    ),
410
411    /// Sets the code of a contract
412    #[serde(rename = "anvil_setCode", alias = "hardhat_setCode")]
413    SetCode(Address, Bytes),
414
415    /// Sets the nonce of an address
416    #[serde(rename = "anvil_setNonce", alias = "hardhat_setNonce", alias = "evm_setAccountNonce")]
417    SetNonce(Address, #[serde(deserialize_with = "deserialize_number")] U256),
418
419    /// Writes a single slot of the account's storage
420    #[serde(rename = "anvil_setStorageAt", alias = "hardhat_setStorageAt")]
421    SetStorageAt(
422        Address,
423        /// slot
424        U256,
425        /// value
426        B256,
427    ),
428
429    /// Sets the coinbase address
430    #[serde(rename = "anvil_setCoinbase", alias = "hardhat_setCoinbase", with = "sequence")]
431    SetCoinbase(Address),
432
433    /// Sets the chain id
434    #[serde(rename = "anvil_setChainId", with = "sequence")]
435    SetChainId(u64),
436
437    /// Enable or disable logging
438    #[serde(
439        rename = "anvil_setLoggingEnabled",
440        alias = "hardhat_setLoggingEnabled",
441        with = "sequence"
442    )]
443    SetLogging(bool),
444
445    /// Set the minimum gas price for the node
446    #[serde(
447        rename = "anvil_setMinGasPrice",
448        alias = "hardhat_setMinGasPrice",
449        deserialize_with = "deserialize_number_seq"
450    )]
451    SetMinGasPrice(U256),
452
453    /// Sets the base fee of the next block
454    #[serde(
455        rename = "anvil_setNextBlockBaseFeePerGas",
456        alias = "hardhat_setNextBlockBaseFeePerGas",
457        deserialize_with = "deserialize_number_seq"
458    )]
459    SetNextBlockBaseFeePerGas(U256),
460
461    /// Sets the specific timestamp
462    /// Accepts timestamp (Unix epoch) with millisecond precision and returns the number of seconds
463    /// between the given timestamp and the current time.
464    #[serde(
465        rename = "anvil_setTime",
466        alias = "evm_setTime",
467        deserialize_with = "deserialize_number_seq"
468    )]
469    EvmSetTime(U256),
470
471    /// Serializes the current state (including contracts code, contract's storage, accounts
472    /// properties, etc.) into a saveable data blob
473    #[serde(rename = "anvil_dumpState", alias = "hardhat_dumpState")]
474    DumpState(#[serde(default)] Option<Params<Option<bool>>>),
475
476    /// Adds state previously dumped with `DumpState` to the current chain
477    #[serde(rename = "anvil_loadState", alias = "hardhat_loadState", with = "sequence")]
478    LoadState(Bytes),
479
480    /// Retrieves the Anvil node configuration params
481    #[serde(rename = "anvil_nodeInfo", with = "empty_params")]
482    NodeInfo(()),
483
484    /// Retrieves the Anvil node metadata.
485    #[serde(rename = "anvil_metadata", alias = "hardhat_metadata", with = "empty_params")]
486    AnvilMetadata(()),
487
488    // Ganache compatible calls
489    /// Snapshot the state of the blockchain at the current block.
490    ///
491    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_snapshot>
492    #[serde(rename = "anvil_snapshot", alias = "evm_snapshot", with = "empty_params")]
493    EvmSnapshot(()),
494
495    /// Revert the state of the blockchain to a previous snapshot.
496    /// Takes a single parameter, which is the snapshot id to revert to.
497    ///
498    /// Ref <https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_revert>
499    #[serde(
500        rename = "anvil_revert",
501        alias = "evm_revert",
502        deserialize_with = "deserialize_number_seq"
503    )]
504    EvmRevert(U256),
505
506    /// Jump forward in time by the given amount of time, in seconds.
507    #[serde(
508        rename = "anvil_increaseTime",
509        alias = "evm_increaseTime",
510        deserialize_with = "deserialize_number_seq"
511    )]
512    EvmIncreaseTime(U256),
513
514    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
515    #[serde(
516        rename = "anvil_setNextBlockTimestamp",
517        alias = "evm_setNextBlockTimestamp",
518        deserialize_with = "deserialize_number_seq"
519    )]
520    EvmSetNextBlockTimeStamp(U256),
521
522    /// Set the exact gas limit that you want in the next block
523    #[serde(
524        rename = "anvil_setBlockGasLimit",
525        alias = "evm_setBlockGasLimit",
526        deserialize_with = "deserialize_number_seq"
527    )]
528    EvmSetBlockGasLimit(U256),
529
530    /// Similar to `evm_increaseTime` but takes sets a block timestamp `interval`.
531    ///
532    /// The timestamp of the next block will be computed as `lastBlock_timestamp + interval`.
533    #[serde(rename = "anvil_setBlockTimestampInterval", with = "sequence")]
534    EvmSetBlockTimeStampInterval(u64),
535
536    /// Removes a `anvil_setBlockTimestampInterval` if it exists
537    #[serde(rename = "anvil_removeBlockTimestampInterval", with = "empty_params")]
538    EvmRemoveBlockTimeStampInterval(()),
539
540    /// Mine a single block
541    #[serde(rename = "evm_mine")]
542    EvmMine(#[serde(default)] Option<Params<Option<MineOptions>>>),
543
544    /// Mine a single block and return detailed data
545    ///
546    /// This behaves exactly as `EvmMine` but returns different output, for compatibility reasons
547    /// this is a separate call since `evm_mine` is not an anvil original.
548    #[serde(rename = "anvil_mine_detailed", alias = "evm_mine_detailed")]
549    EvmMineDetailed(#[serde(default)] Option<Params<Option<MineOptions>>>),
550
551    /// Execute a transaction regardless of signature status
552    #[serde(rename = "eth_sendUnsignedTransaction", with = "sequence")]
553    EthSendUnsignedTransaction(Box<WithOtherFields<TransactionRequest>>),
554
555    /// Turn on call traces for transactions that are returned to the user when they execute a
556    /// transaction (instead of just txhash/receipt)
557    #[serde(rename = "anvil_enableTraces", with = "empty_params")]
558    EnableTraces(()),
559
560    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
561    /// well as the ones that are being scheduled for future execution only.
562    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status>
563    #[serde(rename = "txpool_status", with = "empty_params")]
564    TxPoolStatus(()),
565
566    /// Returns a summary of all the transactions currently pending for inclusion in the next
567    /// block(s), as well as the ones that are being scheduled for future execution only.
568    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect>
569    #[serde(rename = "txpool_inspect", with = "empty_params")]
570    TxPoolInspect(()),
571
572    /// Returns the details of all transactions currently pending for inclusion in the next
573    /// block(s), as well as the ones that are being scheduled for future execution only.
574    /// Ref: <https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content>
575    #[serde(rename = "txpool_content", with = "empty_params")]
576    TxPoolContent(()),
577
578    /// Otterscan's `ots_getApiLevel` endpoint
579    /// Otterscan currently requires this endpoint, even though it's not part of the ots_*
580    /// <https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71>
581    /// Related upstream issue: <https://github.com/otterscan/otterscan/issues/1081>
582    #[serde(rename = "erigon_getHeaderByNumber")]
583    ErigonGetHeaderByNumber(
584        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq")] BlockNumber,
585    ),
586
587    /// Otterscan's `ots_getApiLevel` endpoint
588    /// Used as a simple API versioning scheme for the ots_* namespace
589    #[serde(rename = "ots_getApiLevel", with = "empty_params")]
590    OtsGetApiLevel(()),
591
592    /// Otterscan's `ots_getInternalOperations` endpoint
593    /// Traces internal ETH transfers, contracts creation (CREATE/CREATE2) and self-destructs for a
594    /// certain transaction.
595    #[serde(rename = "ots_getInternalOperations", with = "sequence")]
596    OtsGetInternalOperations(B256),
597
598    /// Otterscan's `ots_hasCode` endpoint
599    /// Check if an ETH address contains code at a certain block number.
600    #[serde(rename = "ots_hasCode")]
601    OtsHasCode(
602        Address,
603        #[serde(deserialize_with = "lenient_block_number::lenient_block_number", default)]
604        BlockNumber,
605    ),
606
607    /// Otterscan's `ots_traceTransaction` endpoint
608    /// Trace a transaction and generate a trace call tree.
609    #[serde(rename = "ots_traceTransaction", with = "sequence")]
610    OtsTraceTransaction(B256),
611
612    /// Otterscan's `ots_getTransactionError` endpoint
613    /// Given a transaction hash, returns its raw revert reason.
614    #[serde(rename = "ots_getTransactionError", with = "sequence")]
615    OtsGetTransactionError(B256),
616
617    /// Otterscan's `ots_getBlockDetails` endpoint
618    /// Given a block number, return its data. Similar to the standard eth_getBlockByNumber/Hash
619    /// method, but can be optimized by excluding unnecessary data such as transactions and
620    /// logBloom
621    #[serde(rename = "ots_getBlockDetails")]
622    OtsGetBlockDetails(
623        #[serde(deserialize_with = "lenient_block_number::lenient_block_number_seq", default)]
624        BlockNumber,
625    ),
626
627    /// Otterscan's `ots_getBlockDetails` endpoint
628    /// Same as `ots_getBlockDetails`, but receiving a block hash instead of number
629    #[serde(rename = "ots_getBlockDetailsByHash", with = "sequence")]
630    OtsGetBlockDetailsByHash(B256),
631
632    /// Otterscan's `ots_getBlockTransactions` endpoint
633    /// Gets paginated transaction data for a certain block. Return data is similar to
634    /// eth_getBlockBy* + eth_getTransactionReceipt.
635    #[serde(rename = "ots_getBlockTransactions")]
636    OtsGetBlockTransactions(u64, usize, usize),
637
638    /// Otterscan's `ots_searchTransactionsBefore` endpoint
639    /// Address history navigation. searches backwards from certain point in time.
640    #[serde(rename = "ots_searchTransactionsBefore")]
641    OtsSearchTransactionsBefore(Address, u64, usize),
642
643    /// Otterscan's `ots_searchTransactionsAfter` endpoint
644    /// Address history navigation. searches forward from certain point in time.
645    #[serde(rename = "ots_searchTransactionsAfter")]
646    OtsSearchTransactionsAfter(Address, u64, usize),
647
648    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
649    /// Given a sender address and a nonce, returns the tx hash or null if not found. It returns
650    /// only the tx hash on success, you can use the standard eth_getTransactionByHash after that
651    /// to get the full transaction data.
652    #[serde(rename = "ots_getTransactionBySenderAndNonce")]
653    OtsGetTransactionBySenderAndNonce(
654        Address,
655        #[serde(deserialize_with = "deserialize_number")] U256,
656    ),
657
658    /// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
659    /// Given an ETH contract address, returns the tx hash and the direct address who created the
660    /// contract.
661    #[serde(rename = "ots_getContractCreator", with = "sequence")]
662    OtsGetContractCreator(Address),
663
664    /// Removes transactions from the pool by sender origin.
665    #[serde(rename = "anvil_removePoolTransactions", with = "sequence")]
666    RemovePoolTransactions(Address),
667
668    /// Reorg the chain
669    #[serde(rename = "anvil_reorg")]
670    Reorg(ReorgOptions),
671
672    /// Rollback the chain
673    #[serde(rename = "anvil_rollback", with = "sequence")]
674    Rollback(Option<u64>),
675
676    /// Wallet
677    #[serde(rename = "wallet_getCapabilities", with = "empty_params")]
678    WalletGetCapabilities(()),
679
680    /// Wallet send_tx
681    #[serde(
682        rename = "wallet_sendTransaction",
683        alias = "odyssey_sendTransaction",
684        with = "sequence"
685    )]
686    WalletSendTransaction(Box<WithOtherFields<TransactionRequest>>),
687
688    /// Add an address to the [`DelegationCapability`] of the wallet
689    ///
690    /// [`DelegationCapability`]: wallet::DelegationCapability
691    #[serde(rename = "anvil_addCapability", with = "sequence")]
692    AnvilAddCapability(Address),
693
694    /// Set the executor (sponsor) wallet
695    #[serde(rename = "anvil_setExecutor", with = "sequence")]
696    AnvilSetExecutor(String),
697}
698
699/// Represents ethereum JSON-RPC API
700#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
701#[serde(tag = "method", content = "params")]
702pub enum EthPubSub {
703    /// Subscribe to an eth subscription
704    #[serde(rename = "eth_subscribe")]
705    EthSubscribe(SubscriptionKind, #[serde(default)] Box<SubscriptionParams>),
706
707    /// Unsubscribe from an eth subscription
708    #[serde(rename = "eth_unsubscribe", with = "sequence")]
709    EthUnSubscribe(SubscriptionId),
710}
711
712/// Container type for either a request or a pub sub
713#[derive(Clone, Debug, serde::Deserialize)]
714#[serde(untagged)]
715pub enum EthRpcCall {
716    Request(Box<EthRequest>),
717    PubSub(EthPubSub),
718}
719
720#[cfg(test)]
721mod tests {
722    use super::*;
723
724    #[test]
725    fn test_web3_client_version() {
726        let s = r#"{"method": "web3_clientVersion", "params":[]}"#;
727        let value: serde_json::Value = serde_json::from_str(s).unwrap();
728        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
729    }
730
731    #[test]
732    fn test_web3_sha3() {
733        let s = r#"{"method": "web3_sha3", "params":["0x68656c6c6f20776f726c64"]}"#;
734        let value: serde_json::Value = serde_json::from_str(s).unwrap();
735        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
736    }
737
738    #[test]
739    fn test_eth_accounts() {
740        let s = r#"{"method": "eth_accounts", "params":[]}"#;
741        let value: serde_json::Value = serde_json::from_str(s).unwrap();
742        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
743    }
744
745    #[test]
746    fn test_eth_network_id() {
747        let s = r#"{"method": "eth_networkId", "params":[]}"#;
748        let value: serde_json::Value = serde_json::from_str(s).unwrap();
749        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
750    }
751
752    #[test]
753    fn test_eth_get_proof() {
754        let s = r#"{"method":"eth_getProof","params":["0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842",["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"],"latest"]}"#;
755        let value: serde_json::Value = serde_json::from_str(s).unwrap();
756        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
757    }
758
759    #[test]
760    fn test_eth_chain_id() {
761        let s = r#"{"method": "eth_chainId", "params":[]}"#;
762        let value: serde_json::Value = serde_json::from_str(s).unwrap();
763        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
764    }
765
766    #[test]
767    fn test_net_listening() {
768        let s = r#"{"method": "net_listening", "params":[]}"#;
769        let value: serde_json::Value = serde_json::from_str(s).unwrap();
770        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
771    }
772
773    #[test]
774    fn test_eth_block_number() {
775        let s = r#"{"method": "eth_blockNumber", "params":[]}"#;
776        let value: serde_json::Value = serde_json::from_str(s).unwrap();
777        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
778    }
779
780    #[test]
781    fn test_eth_max_priority_fee() {
782        let s = r#"{"method": "eth_maxPriorityFeePerGas", "params":[]}"#;
783        let value: serde_json::Value = serde_json::from_str(s).unwrap();
784        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
785    }
786
787    #[test]
788    fn test_eth_syncing() {
789        let s = r#"{"method": "eth_syncing", "params":[]}"#;
790        let value: serde_json::Value = serde_json::from_str(s).unwrap();
791        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
792    }
793
794    #[test]
795    fn test_custom_impersonate_account() {
796        let s = r#"{"method": "anvil_impersonateAccount", "params":
797["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
798        let value: serde_json::Value = serde_json::from_str(s).unwrap();
799        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
800    }
801
802    #[test]
803    fn test_custom_stop_impersonate_account() {
804        let s = r#"{"method": "anvil_stopImpersonatingAccount",  "params":
805["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
806        let value: serde_json::Value = serde_json::from_str(s).unwrap();
807        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
808    }
809
810    #[test]
811    fn test_custom_auto_impersonate_account() {
812        let s = r#"{"method": "anvil_autoImpersonateAccount",  "params": [true]}"#;
813        let value: serde_json::Value = serde_json::from_str(s).unwrap();
814        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
815    }
816
817    #[test]
818    fn test_custom_get_automine() {
819        let s = r#"{"method": "anvil_getAutomine", "params": []}"#;
820        let value: serde_json::Value = serde_json::from_str(s).unwrap();
821        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
822    }
823
824    #[test]
825    fn test_custom_mine() {
826        let s = r#"{"method": "anvil_mine", "params": []}"#;
827        let value: serde_json::Value = serde_json::from_str(s).unwrap();
828        let req = serde_json::from_value::<EthRequest>(value).unwrap();
829        match req {
830            EthRequest::Mine(num, time) => {
831                assert!(num.is_none());
832                assert!(time.is_none());
833            }
834            _ => unreachable!(),
835        }
836        let s = r#"{"method": "anvil_mine", "params":
837["0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
838        let value: serde_json::Value = serde_json::from_str(s).unwrap();
839        let req = serde_json::from_value::<EthRequest>(value).unwrap();
840        match req {
841            EthRequest::Mine(num, time) => {
842                assert!(num.is_some());
843                assert!(time.is_none());
844            }
845            _ => unreachable!(),
846        }
847        let s = r#"{"method": "anvil_mine", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
848        let value: serde_json::Value = serde_json::from_str(s).unwrap();
849        let req = serde_json::from_value::<EthRequest>(value).unwrap();
850        match req {
851            EthRequest::Mine(num, time) => {
852                assert!(num.is_some());
853                assert!(time.is_some());
854            }
855            _ => unreachable!(),
856        }
857    }
858
859    #[test]
860    fn test_custom_auto_mine() {
861        let s = r#"{"method": "anvil_setAutomine", "params": [false]}"#;
862        let value: serde_json::Value = serde_json::from_str(s).unwrap();
863        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
864        let s = r#"{"method": "evm_setAutomine", "params": [false]}"#;
865        let value: serde_json::Value = serde_json::from_str(s).unwrap();
866        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
867    }
868
869    #[test]
870    fn test_custom_interval_mining() {
871        let s = r#"{"method": "anvil_setIntervalMining", "params": [100]}"#;
872        let value: serde_json::Value = serde_json::from_str(s).unwrap();
873        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
874        let s = r#"{"method": "evm_setIntervalMining", "params": [100]}"#;
875        let value: serde_json::Value = serde_json::from_str(s).unwrap();
876        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
877    }
878
879    #[test]
880    fn test_custom_drop_tx() {
881        let s = r#"{"method": "anvil_dropTransaction", "params":
882["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
883        let value: serde_json::Value = serde_json::from_str(s).unwrap();
884        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
885    }
886
887    #[test]
888    fn test_custom_reset() {
889        let s = r#"{"method": "anvil_reset", "params": [{"forking": {"jsonRpcUrl": "https://ethereumpublicnode.com",
890        "blockNumber": "18441649"
891      }
892    }]}"#;
893        let value: serde_json::Value = serde_json::from_str(s).unwrap();
894        let req = serde_json::from_value::<EthRequest>(value).unwrap();
895        match req {
896            EthRequest::Reset(forking) => {
897                let forking = forking.and_then(|f| f.params);
898                assert_eq!(
899                    forking,
900                    Some(Forking {
901                        json_rpc_url: Some("https://ethereumpublicnode.com".into()),
902                        block_number: Some(18441649)
903                    })
904                )
905            }
906            _ => unreachable!(),
907        }
908
909        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
910                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>",
911                "blockNumber": 11095000
912        }}]}"#;
913        let value: serde_json::Value = serde_json::from_str(s).unwrap();
914        let req = serde_json::from_value::<EthRequest>(value).unwrap();
915        match req {
916            EthRequest::Reset(forking) => {
917                let forking = forking.and_then(|f| f.params);
918                assert_eq!(
919                    forking,
920                    Some(Forking {
921                        json_rpc_url: Some(
922                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
923                        ),
924                        block_number: Some(11095000)
925                    })
926                )
927            }
928            _ => unreachable!(),
929        }
930
931        let s = r#"{"method": "anvil_reset", "params": [ { "forking": {
932                "jsonRpcUrl": "https://eth-mainnet.alchemyapi.io/v2/<key>"
933        }}]}"#;
934        let value: serde_json::Value = serde_json::from_str(s).unwrap();
935        let req = serde_json::from_value::<EthRequest>(value).unwrap();
936        match req {
937            EthRequest::Reset(forking) => {
938                let forking = forking.and_then(|f| f.params);
939                assert_eq!(
940                    forking,
941                    Some(Forking {
942                        json_rpc_url: Some(
943                            "https://eth-mainnet.alchemyapi.io/v2/<key>".to_string()
944                        ),
945                        block_number: None
946                    })
947                )
948            }
949            _ => unreachable!(),
950        }
951
952        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545", "blockNumber": 14000000}]}"#;
953        let value: serde_json::Value = serde_json::from_str(s).unwrap();
954        let req = serde_json::from_value::<EthRequest>(value).unwrap();
955        match req {
956            EthRequest::Reset(forking) => {
957                let forking = forking.and_then(|f| f.params);
958                assert_eq!(
959                    forking,
960                    Some(Forking {
961                        json_rpc_url: Some("http://localhost:8545".to_string()),
962                        block_number: Some(14000000)
963                    })
964                )
965            }
966            _ => unreachable!(),
967        }
968
969        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": 14000000}]}"#;
970        let value: serde_json::Value = serde_json::from_str(s).unwrap();
971        let req = serde_json::from_value::<EthRequest>(value).unwrap();
972        match req {
973            EthRequest::Reset(forking) => {
974                let forking = forking.and_then(|f| f.params);
975                assert_eq!(
976                    forking,
977                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
978                )
979            }
980            _ => unreachable!(),
981        }
982
983        let s = r#"{"method":"anvil_reset","params":[{ "blockNumber": "14000000"}]}"#;
984        let value: serde_json::Value = serde_json::from_str(s).unwrap();
985        let req = serde_json::from_value::<EthRequest>(value).unwrap();
986        match req {
987            EthRequest::Reset(forking) => {
988                let forking = forking.and_then(|f| f.params);
989                assert_eq!(
990                    forking,
991                    Some(Forking { json_rpc_url: None, block_number: Some(14000000) })
992                )
993            }
994            _ => unreachable!(),
995        }
996
997        let s = r#"{"method":"anvil_reset","params":[{"jsonRpcUrl": "http://localhost:8545"}]}"#;
998        let value: serde_json::Value = serde_json::from_str(s).unwrap();
999        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1000        match req {
1001            EthRequest::Reset(forking) => {
1002                let forking = forking.and_then(|f| f.params);
1003                assert_eq!(
1004                    forking,
1005                    Some(Forking {
1006                        json_rpc_url: Some("http://localhost:8545".to_string()),
1007                        block_number: None
1008                    })
1009                )
1010            }
1011            _ => unreachable!(),
1012        }
1013
1014        let s = r#"{"method": "anvil_reset"}"#;
1015        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1016        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1017        match req {
1018            EthRequest::Reset(forking) => {
1019                assert!(forking.is_none())
1020            }
1021            _ => unreachable!(),
1022        }
1023    }
1024
1025    #[test]
1026    fn test_custom_set_balance() {
1027        let s = r#"{"method": "anvil_setBalance", "params":
1028["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1029        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1030        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1031
1032        let s = r#"{"method": "anvil_setBalance", "params":
1033["0xd84de507f3fada7df80908082d3239466db55a71", 1337]}"#;
1034        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1035        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1036    }
1037
1038    #[test]
1039    fn test_custom_set_code() {
1040        let s = r#"{"method": "anvil_setCode", "params":
1041["0xd84de507f3fada7df80908082d3239466db55a71", "0x0123456789abcdef"]}"#;
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", "0x"]}"#;
1047        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1048        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1049
1050        let s = r#"{"method": "anvil_setCode", "params":
1051["0xd84de507f3fada7df80908082d3239466db55a71", ""]}"#;
1052        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1053        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1054    }
1055
1056    #[test]
1057    fn test_custom_set_nonce() {
1058        let s = r#"{"method": "anvil_setNonce", "params":
1059["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1060        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1061        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1062        let s = r#"{"method":
1063"hardhat_setNonce", "params": ["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1064        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1065        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1066        let s = r#"{"method": "evm_setAccountNonce", "params":
1067["0xd84de507f3fada7df80908082d3239466db55a71", "0x0"]}"#;
1068        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1069        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1070    }
1071
1072    #[test]
1073    fn test_serde_custom_set_storage_at() {
1074        let s = r#"{"method": "anvil_setStorageAt", "params":
1075["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0",
1076"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1077        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1078        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1079
1080        let s = r#"{"method": "hardhat_setStorageAt", "params":
1081["0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
1082"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
1083"0x0000000000000000000000000000000000000000000000000000000000003039"]}"#;
1084        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1085        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1086    }
1087
1088    #[test]
1089    fn test_serde_custom_coinbase() {
1090        let s = r#"{"method": "anvil_setCoinbase", "params":
1091["0x295a70b2de5e3953354a6a8344e616ed314d7251"]}"#;
1092        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1093        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1094    }
1095
1096    #[test]
1097    fn test_serde_custom_logging() {
1098        let s = r#"{"method": "anvil_setLoggingEnabled", "params": [false]}"#;
1099        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1100        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1101    }
1102
1103    #[test]
1104    fn test_serde_custom_min_gas_price() {
1105        let s = r#"{"method": "anvil_setMinGasPrice", "params": ["0x0"]}"#;
1106        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1107        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1108    }
1109
1110    #[test]
1111    fn test_serde_custom_next_block_base_fee() {
1112        let s = r#"{"method": "anvil_setNextBlockBaseFeePerGas", "params": ["0x0"]}"#;
1113        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1114        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1115    }
1116
1117    #[test]
1118    fn test_serde_set_time() {
1119        let s = r#"{"method": "anvil_setTime", "params": ["0x0"]}"#;
1120        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1121        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1122
1123        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1124        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1125        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1126    }
1127
1128    #[test]
1129    fn test_serde_custom_dump_state() {
1130        let s = r#"{"method": "anvil_dumpState", "params": [true]}"#;
1131        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1132        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1133
1134        let s = r#"{"method": "anvil_dumpState"}"#;
1135        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1136        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1137        match req {
1138            EthRequest::DumpState(param) => {
1139                assert!(param.is_none());
1140            }
1141            _ => unreachable!(),
1142        }
1143    }
1144
1145    #[test]
1146    fn test_serde_custom_load_state() {
1147        let s = r#"{"method": "anvil_loadState", "params": ["0x0001"] }"#;
1148        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1149        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1150    }
1151
1152    #[test]
1153    fn test_serde_custom_snapshot() {
1154        let s = r#"{"method": "anvil_snapshot", "params": [] }"#;
1155        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1156        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1157
1158        let s = r#"{"method": "evm_snapshot", "params": [] }"#;
1159        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1160        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1161    }
1162
1163    #[test]
1164    fn test_serde_custom_revert() {
1165        let s = r#"{"method": "anvil_revert", "params": ["0x0"]}"#;
1166        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1167        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1168    }
1169
1170    #[test]
1171    fn test_serde_custom_increase_time() {
1172        let s = r#"{"method": "anvil_increaseTime", "params": ["0x0"]}"#;
1173        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1174        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1175
1176        let s = r#"{"method": "anvil_increaseTime", "params": [1]}"#;
1177        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1178        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1179
1180        let s = r#"{"method": "anvil_increaseTime", "params": 1}"#;
1181        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1182        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1183
1184        let s = r#"{"method": "evm_increaseTime", "params": ["0x0"]}"#;
1185        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1186        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1187
1188        let s = r#"{"method": "evm_increaseTime", "params": [1]}"#;
1189        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1190        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1191
1192        let s = r#"{"method": "evm_increaseTime", "params": 1}"#;
1193        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1194        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1195    }
1196
1197    #[test]
1198    fn test_serde_custom_next_timestamp() {
1199        let s = r#"{"method": "anvil_setNextBlockTimestamp", "params": [100]}"#;
1200        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1201        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1202        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": [100]}"#;
1203        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1204        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1205        let s = r#"{"method": "evm_setNextBlockTimestamp", "params": ["0x64e0f308"]}"#;
1206        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1207        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1208    }
1209
1210    #[test]
1211    fn test_serde_custom_timestamp_interval() {
1212        let s = r#"{"method": "anvil_setBlockTimestampInterval", "params": [100]}"#;
1213        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1214        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1215    }
1216
1217    #[test]
1218    fn test_serde_custom_remove_timestamp_interval() {
1219        let s = r#"{"method": "anvil_removeBlockTimestampInterval", "params": []}"#;
1220        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1221        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1222    }
1223
1224    #[test]
1225    fn test_serde_custom_evm_mine() {
1226        let s = r#"{"method": "evm_mine", "params": [100]}"#;
1227        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1228        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1229        let s = r#"{"method": "evm_mine", "params": [{
1230            "timestamp": 100,
1231            "blocks": 100
1232        }]}"#;
1233        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1234        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1235        match req {
1236            EthRequest::EvmMine(params) => {
1237                assert_eq!(
1238                    params.unwrap().params.unwrap_or_default(),
1239                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1240                )
1241            }
1242            _ => unreachable!(),
1243        }
1244
1245        let s = r#"{"method": "evm_mine"}"#;
1246        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1247        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1248
1249        match req {
1250            EthRequest::EvmMine(params) => {
1251                assert!(params.is_none())
1252            }
1253            _ => unreachable!(),
1254        }
1255
1256        let s = r#"{"method": "evm_mine", "params": []}"#;
1257        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1258        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1259    }
1260
1261    #[test]
1262    fn test_serde_custom_evm_mine_detailed() {
1263        let s = r#"{"method": "anvil_mine_detailed", "params": [100]}"#;
1264        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1265        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1266        let s = r#"{"method": "anvil_mine_detailed", "params": [{
1267            "timestamp": 100,
1268            "blocks": 100
1269        }]}"#;
1270        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1271        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1272        match req {
1273            EthRequest::EvmMineDetailed(params) => {
1274                assert_eq!(
1275                    params.unwrap().params.unwrap_or_default(),
1276                    MineOptions::Options { timestamp: Some(100), blocks: Some(100) }
1277                )
1278            }
1279            _ => unreachable!(),
1280        }
1281
1282        let s = r#"{"method": "evm_mine_detailed"}"#;
1283        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1284        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1285
1286        match req {
1287            EthRequest::EvmMineDetailed(params) => {
1288                assert!(params.is_none())
1289            }
1290            _ => unreachable!(),
1291        }
1292
1293        let s = r#"{"method": "anvil_mine_detailed", "params": []}"#;
1294        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1295        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1296    }
1297
1298    #[test]
1299    fn test_serde_custom_evm_mine_hex() {
1300        let s = r#"{"method": "evm_mine", "params": ["0x63b6ff08"]}"#;
1301        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1302        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1303        match req {
1304            EthRequest::EvmMine(params) => {
1305                assert_eq!(
1306                    params.unwrap().params.unwrap_or_default(),
1307                    MineOptions::Timestamp(Some(1672937224))
1308                )
1309            }
1310            _ => unreachable!(),
1311        }
1312
1313        let s = r#"{"method": "evm_mine", "params": [{"timestamp": "0x63b6ff08"}]}"#;
1314        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1315        let req = serde_json::from_value::<EthRequest>(value).unwrap();
1316        match req {
1317            EthRequest::EvmMine(params) => {
1318                assert_eq!(
1319                    params.unwrap().params.unwrap_or_default(),
1320                    MineOptions::Options { timestamp: Some(1672937224), blocks: None }
1321                )
1322            }
1323            _ => unreachable!(),
1324        }
1325    }
1326
1327    #[test]
1328    fn test_eth_uncle_count_by_block_hash() {
1329        let s = r#"{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1330        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1331        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1332    }
1333
1334    #[test]
1335    fn test_eth_block_tx_count_by_block_hash() {
1336        let s = r#"{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff"]}"#;
1337        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1338        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1339    }
1340
1341    #[test]
1342    fn test_eth_get_logs() {
1343        let s = r#"{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}"#;
1344        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1345        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1346    }
1347
1348    #[test]
1349    fn test_eth_new_filter() {
1350        let s = r#"{"method": "eth_newFilter", "params": [{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":73}"#;
1351        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1352        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1353    }
1354
1355    #[test]
1356    fn test_serde_eth_unsubscribe() {
1357        let s = r#"{"id": 1, "method": "eth_unsubscribe", "params":
1358["0x9cef478923ff08bf67fde6c64013158d"]}"#;
1359        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1360        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1361    }
1362
1363    #[test]
1364    fn test_serde_eth_subscribe() {
1365        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}"#;
1366        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1367        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1368
1369        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["logs", {"address":
1370"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics":
1371["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}"#;
1372        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1373        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1374
1375        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}"#;
1376        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1377        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1378
1379        let s = r#"{"id": 1, "method": "eth_subscribe", "params": ["syncing"]}"#;
1380        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1381        let _req = serde_json::from_value::<EthPubSub>(value).unwrap();
1382    }
1383
1384    #[test]
1385    fn test_serde_debug_raw_transaction() {
1386        let s = r#"{"jsonrpc":"2.0","method":"debug_getRawTransaction","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1387        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1388        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1389
1390        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByHash","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c"],"id":1}"#;
1391        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1392        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1393
1394        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockHashAndIndex","params":["0x3ed3a89bc10115a321aee238c02de214009f8532a65368e5df5eaf732ee7167c",1],"id":1}"#;
1395        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1396        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1397
1398        let s = r#"{"jsonrpc":"2.0","method":"eth_getRawTransactionByBlockNumberAndIndex","params":["0x3ed3a89b",0],"id":1}"#;
1399        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1400        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1401    }
1402
1403    #[test]
1404    fn test_serde_debug_trace_transaction() {
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", {}]}"#;
1412        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1413        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1414
1415        let s = r#"{"method": "debug_traceTransaction", "params":
1416["0x4a3b0fce2cb9707b0baa68640cf2fe858c8bb4121b2a8cb904ff369d38a560ff", {"disableStorage":
1417true}]}"#;
1418        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1419        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1420    }
1421
1422    #[test]
1423    fn test_serde_debug_trace_call() {
1424        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
1425        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1426        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1427
1428        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
1429        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1430        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1431
1432        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
1433        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1434        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1435
1436        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
1437        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1438        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1439
1440        let s = r#"{"method": "debug_traceCall", "params": [{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }, {"disableStorage": true}]}"#;
1441        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1442        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1443    }
1444
1445    #[test]
1446    fn test_serde_eth_storage() {
1447        let s = r#"{"method": "eth_getStorageAt", "params":
1448["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"]}"#;
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_eth_call() {
1455        let req = r#"{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}"#;
1456        let _req = serde_json::from_str::<TransactionRequest>(req).unwrap();
1457
1458        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"},"latest"]}"#;
1459        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1460
1461        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}]}"#;
1462        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1463
1464        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "latest" }]}"#;
1465        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1466
1467        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockNumber": "0x0" }]}"#;
1468        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1469
1470        let s = r#"{"method": "eth_call", "params":[{"data":"0xcfae3217","from":"0xd84de507f3fada7df80908082d3239466db55a71","to":"0xcbe828fdc46e3b1c351ec90b1a5e7d9742c0398d"}, { "blockHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" }]}"#;
1471        let _req = serde_json::from_str::<EthRequest>(s).unwrap();
1472    }
1473
1474    #[test]
1475    fn test_serde_eth_balance() {
1476        let s = r#"{"method": "eth_getBalance", "params":
1477["0x295a70b2de5e3953354a6a8344e616ed314d7251", "latest"]}"#;
1478        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1479
1480        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1481    }
1482
1483    #[test]
1484    fn test_serde_eth_block_by_number() {
1485        let s = r#"{"method": "eth_getBlockByNumber", "params": ["0x0", true]}"#;
1486        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1487        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1488        let s = r#"{"method": "eth_getBlockByNumber", "params": ["latest", true]}"#;
1489        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1490        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1491        let s = r#"{"method": "eth_getBlockByNumber", "params": ["earliest", true]}"#;
1492        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1493        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1494        let s = r#"{"method": "eth_getBlockByNumber", "params": ["pending", 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        // this case deviates from the spec, but we're supporting this for legacy reasons: <https://github.com/foundry-rs/foundry/issues/1868>
1499        let s = r#"{"method": "eth_getBlockByNumber", "params": [0, true]}"#;
1500        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1501        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1502    }
1503
1504    #[test]
1505    fn test_eth_sign() {
1506        let s = r#"{"method": "eth_sign", "params":
1507["0xd84de507f3fada7df80908082d3239466db55a71", "0x00"]}"#;
1508        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1509        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1510        let s = r#"{"method": "personal_sign", "params":
1511["0x00", "0xd84de507f3fada7df80908082d3239466db55a71"]}"#;
1512        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1513        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1514    }
1515
1516    #[test]
1517    fn test_eth_sign_typed_data() {
1518        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!"}}]}"#;
1519        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1520        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1521    }
1522
1523    #[test]
1524    fn test_remove_pool_transactions() {
1525        let s = r#"{"method": "anvil_removePoolTransactions",  "params":["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}"#;
1526        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1527        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1528    }
1529
1530    #[test]
1531    fn test_serde_anvil_reorg() {
1532        // TransactionData::JSON
1533        let s = r#"
1534        {
1535            "method": "anvil_reorg",
1536            "params": [
1537                5,
1538                [
1539                    [
1540                        {
1541                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1542                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1543                            "value": 100
1544                        },
1545                        1
1546                    ],
1547                    [
1548                        {
1549                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1550                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1551                            "value": 200
1552                        },
1553                        2
1554                    ]
1555                ]
1556            ]
1557        }
1558        "#;
1559        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1560        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1561        // TransactionData::Raw
1562        let s = r#"
1563        {
1564            "method": "anvil_reorg",
1565            "params": [
1566                5,
1567                [
1568                    [
1569                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
1570                        1
1571                    ]
1572                ]
1573            ]
1574        }
1575        "#;
1576        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1577        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1578        // TransactionData::Raw and TransactionData::JSON
1579        let s = r#"
1580        {
1581            "method": "anvil_reorg",
1582            "params": [
1583                5,
1584                [
1585                    [
1586                        "0x19d55c67e1ba8f1bbdfed75f8ad524ebf087e4ecb848a2d19881d7a5e3d2c54e1732cb1b462da3b3fdb05bdf4c4d3c8e3c9fcebdc2ab5fa5d59a3f752888f27e1b",
1587                        1
1588                    ],
1589                    [
1590                        {
1591                            "from": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
1592                            "to": "0x1199bc69f16FDD6690DC40339EC445FaE1b6DD11",
1593                            "value": 200
1594                        },
1595                        2
1596                    ]
1597                ]
1598            ]
1599        }
1600        "#;
1601        let value: serde_json::Value = serde_json::from_str(s).unwrap();
1602        let _req = serde_json::from_value::<EthRequest>(value).unwrap();
1603    }
1604}