Skip to main content

alloy_provider/ext/
anvil.rs

1//! This module extends the Ethereum JSON-RPC provider with the Anvil namespace's RPC methods.
2
3use crate::{PendingTransactionBuilder, Provider};
4use alloy_consensus::Blob;
5use alloy_network::{Network, TransactionBuilder};
6use alloy_primitives::{Address, Bytes, TxHash, B256, U128, U256, U64};
7use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo, ReorgOptions};
8use alloy_transport::{TransportError, TransportResult};
9use futures::try_join;
10
11/// Anvil namespace rpc interface that gives access to several non-standard RPC methods.
12#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
13#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
14pub trait AnvilApi<N: Network>: Send + Sync {
15    // Not implemented:
16    // - anvil_enable_traces: Not implemented in the Anvil RPC API.
17    // - anvil_set_block: Not implemented / wired correctly in the Anvil RPC API.
18
19    /// Send transactions impersonating specific account and contract addresses.
20    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
21
22    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
23    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
24
25    /// If set to `true`, impersonates all accounts.
26    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
27
28    /// Impersonates the `from` address in the given transaction request, optionally funds the
29    /// sender, sends the transaction, and optionally stops impersonating after execution based
30    /// on the provided config.
31    async fn anvil_send_impersonated_transaction_with_config(
32        &self,
33        request: N::TransactionRequest,
34        config: ImpersonateConfig,
35    ) -> TransportResult<PendingTransactionBuilder<N>>;
36
37    /// Returns true if auto mining is enabled, and false.
38    async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
39
40    /// Enables or disables, based on the single boolean argument, the automatic mining of new
41    /// blocks with each new transaction submitted to the network.
42    async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
43
44    /// Mines a series of blocks.
45    async fn anvil_mine(
46        &self,
47        num_blocks: Option<u64>,
48        interval: Option<u64>,
49    ) -> TransportResult<()>;
50
51    /// Sets the mining behavior to interval with the given interval (seconds).
52    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
53
54    /// Removes transactions from the pool.
55    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
56
57    /// Removes all transactions from the pool.
58    async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
59
60    /// Reset the fork to a fresh forked state, and optionally update the fork config.
61    ///
62    /// If `forking` is `None` then this will disable forking entirely.
63    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
64
65    /// Sets the chain ID.
66    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
67
68    /// Modifies the balance of an account.
69    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
70
71    /// Sets the code of a contract.
72    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
73
74    /// Sets the nonce of an address.
75    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
76
77    /// Writes a single slot of the account's storage.
78    async fn anvil_set_storage_at(
79        &self,
80        address: Address,
81        slot: U256,
82        val: B256,
83    ) -> TransportResult<bool>;
84
85    /// Enable or disable logging.
86    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
87
88    /// Set the minimum gas price for the node.
89    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
90
91    /// Sets the base fee of the next block.
92    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
93
94    /// Sets the coinbase address.
95    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
96
97    /// Create a buffer that represents all state on the chain, which can be loaded to separate
98    /// process by calling `anvil_loadState`
99    async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
100
101    /// Append chain state buffer to current chain. Will overwrite any conflicting addresses or
102    /// storage.
103    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
104
105    /// Retrieves the Anvil node configuration params.
106    async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
107
108    /// Retrieves metadata about the Anvil instance.
109    async fn anvil_metadata(&self) -> TransportResult<Metadata>;
110
111    /// Removes all transactions from the pool for a specific address.
112    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
113
114    /// Snapshot the state of the blockchain at the current block.
115    async fn anvil_snapshot(&self) -> TransportResult<U256>;
116
117    /// Revert the state of the blockchain to a previous snapshot.
118    /// Takes a single parameter, which is the snapshot id to revert to.
119    async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
120
121    /// Jump forward in time by the given amount of time, in seconds.
122    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
123
124    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block.
125    async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
126
127    /// Sets the specific timestamp and returns the number of seconds between the given timestamp
128    /// and the current time.
129    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
130
131    /// Set the next block gas limit.
132    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
133
134    /// Sets an interval for the block timestamp.
135    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
136
137    /// Unsets the interval for the block timestamp.
138    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
139
140    /// Mine blocks, instantly.
141    /// This will mine the blocks regardless of the configured mining mode.
142    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
143
144    /// Mine blocks, instantly and return the mined blocks.
145    /// This will mine the blocks regardless of the configured mining mode.
146    async fn anvil_mine_detailed(
147        &self,
148        opts: Option<MineOptions>,
149    ) -> TransportResult<Vec<N::BlockResponse>>;
150
151    /// Sets the backend rpc url.
152    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
153
154    /// Reorg the chain
155    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
156
157    /// Rollback the chain
158    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
159
160    /// Retrieves a blob by its versioned hash.
161    async fn anvil_get_blob_by_versioned_hash(
162        &self,
163        versioned_hash: B256,
164    ) -> TransportResult<Option<Blob>>;
165
166    /// Retrieves blobs by transaction hash.
167    async fn anvil_get_blobs_by_tx_hash(
168        &self,
169        tx_hash: TxHash,
170    ) -> TransportResult<Option<Vec<Blob>>>;
171
172    /// Execute a transaction regardless of signature status.
173    async fn eth_send_unsigned_transaction(
174        &self,
175        request: N::TransactionRequest,
176    ) -> TransportResult<TxHash>;
177
178    /// Executes a transaction and waits for it to be mined, returning the receipt.
179    async fn eth_send_transaction_sync(
180        &self,
181        request: N::TransactionRequest,
182    ) -> TransportResult<N::ReceiptResponse>;
183
184    /// Sends a raw transaction and waits for it to be mined, returning the receipt.
185    async fn eth_send_raw_transaction_sync(
186        &self,
187        request: Bytes,
188    ) -> TransportResult<N::ReceiptResponse>;
189
190    /// Sets impersonated transaction
191    async fn anvil_send_impersonated_transaction(
192        &self,
193        request: N::TransactionRequest,
194    ) -> TransportResult<TxHash>;
195
196    /// Modifies the ERC20 balance of an account.
197    async fn anvil_deal_erc20(
198        &self,
199        address: Address,
200        token_address: Address,
201        balance: U256,
202    ) -> TransportResult<()>;
203
204    /// Modifies the ERC20 allowance of an account.
205    async fn anvil_set_erc20_allowance(
206        &self,
207        owner: Address,
208        spender: Address,
209        token: Address,
210        allowance: U256,
211    ) -> TransportResult<()>;
212}
213
214#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
215#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
216impl<N, P> AnvilApi<N> for P
217where
218    N: Network,
219    P: Provider<N>,
220{
221    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
222        self.client().request("anvil_impersonateAccount", (address,)).await
223    }
224
225    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
226        self.client().request("anvil_stopImpersonatingAccount", (address,)).await
227    }
228
229    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
230        self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
231    }
232
233    async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
234        self.client().request_noparams("anvil_getAutomine").await
235    }
236
237    async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
238        self.client().request("anvil_setAutomine", (enabled,)).await
239    }
240
241    async fn anvil_mine(
242        &self,
243        num_blocks: Option<u64>,
244        interval: Option<u64>,
245    ) -> TransportResult<()> {
246        self.client()
247            .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
248            .await
249    }
250
251    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
252        self.client().request("anvil_setIntervalMining", (secs,)).await
253    }
254
255    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
256        self.client().request("anvil_dropTransaction", (tx_hash,)).await
257    }
258
259    async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
260        self.client().request_noparams("anvil_dropAllTransactions").await
261    }
262
263    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
264        self.client().request("anvil_reset", (forking,)).await
265    }
266
267    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
268        self.client().request("anvil_setChainId", (chain_id,)).await
269    }
270
271    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
272        self.client().request("anvil_setBalance", (address, balance)).await
273    }
274
275    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
276        self.client().request("anvil_setCode", (address, code)).await
277    }
278
279    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
280        self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
281    }
282
283    async fn anvil_set_storage_at(
284        &self,
285        address: Address,
286        slot: U256,
287        val: B256,
288    ) -> TransportResult<bool> {
289        self.client().request("anvil_setStorageAt", (address, slot, val)).await
290    }
291
292    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
293        self.client().request("anvil_setLoggingEnabled", (enable,)).await
294    }
295
296    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
297        self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
298    }
299
300    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
301        self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
302    }
303
304    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
305        self.client().request("anvil_setCoinbase", (address,)).await
306    }
307
308    async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
309        self.client().request_noparams("anvil_dumpState").await
310    }
311
312    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
313        self.client().request("anvil_loadState", (buf,)).await
314    }
315
316    async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
317        self.client().request_noparams("anvil_nodeInfo").await
318    }
319
320    async fn anvil_metadata(&self) -> TransportResult<Metadata> {
321        self.client().request_noparams("anvil_metadata").await
322    }
323
324    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
325        self.client().request("anvil_removePoolTransactions", (address,)).await
326    }
327
328    async fn anvil_snapshot(&self) -> TransportResult<U256> {
329        self.client().request_noparams("evm_snapshot").await
330    }
331
332    async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
333        self.client().request("evm_revert", (id,)).await
334    }
335
336    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
337        self.client().request("evm_increaseTime", (U64::from(seconds),)).await
338    }
339
340    async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
341        self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
342    }
343
344    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
345        self.client().request("evm_setTime", (timestamp,)).await
346    }
347
348    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
349        self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
350    }
351
352    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
353        self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
354    }
355
356    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
357        self.client().request_noparams("anvil_removeBlockTimestampInterval").await
358    }
359
360    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
361        self.client().request("evm_mine", (opts,)).await
362    }
363
364    async fn anvil_mine_detailed(
365        &self,
366        opts: Option<MineOptions>,
367    ) -> TransportResult<Vec<N::BlockResponse>> {
368        self.client().request("evm_mine_detailed", (opts,)).await
369    }
370
371    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
372        self.client().request("anvil_setRpcUrl", (url,)).await
373    }
374
375    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
376        self.client().request("anvil_reorg", options).await
377    }
378
379    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
380        self.client().request("anvil_rollback", (depth,)).await
381    }
382
383    async fn anvil_get_blob_by_versioned_hash(&self, hash: B256) -> TransportResult<Option<Blob>> {
384        self.client().request("anvil_getBlobByHash", (hash,)).await
385    }
386
387    async fn anvil_get_blobs_by_tx_hash(&self, hash: TxHash) -> TransportResult<Option<Vec<Blob>>> {
388        self.client().request("anvil_getBlobsByTransactionHash", (hash,)).await
389    }
390
391    async fn eth_send_unsigned_transaction(
392        &self,
393        request: N::TransactionRequest,
394    ) -> TransportResult<TxHash> {
395        self.client().request("eth_sendUnsignedTransaction", (request,)).await
396    }
397
398    async fn eth_send_transaction_sync(
399        &self,
400        request: N::TransactionRequest,
401    ) -> TransportResult<N::ReceiptResponse> {
402        self.client().request("eth_sendTransactionSync", (request,)).await
403    }
404
405    async fn eth_send_raw_transaction_sync(
406        &self,
407        request: Bytes,
408    ) -> TransportResult<N::ReceiptResponse> {
409        self.client().request("eth_sendRawTransactionSync", (request,)).await
410    }
411
412    async fn anvil_send_impersonated_transaction(
413        &self,
414        request: N::TransactionRequest,
415    ) -> TransportResult<TxHash> {
416        self.client().request("eth_sendTransaction", (request,)).await
417    }
418
419    async fn anvil_deal_erc20(
420        &self,
421        address: Address,
422        token_address: Address,
423        balance: U256,
424    ) -> TransportResult<()> {
425        self.client().request("anvil_dealERC20", (address, token_address, balance)).await
426    }
427
428    async fn anvil_set_erc20_allowance(
429        &self,
430        owner: Address,
431        spender: Address,
432        token: Address,
433        allowance: U256,
434    ) -> TransportResult<()> {
435        self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
436    }
437
438    async fn anvil_send_impersonated_transaction_with_config(
439        &self,
440        request: N::TransactionRequest,
441        config: ImpersonateConfig,
442    ) -> TransportResult<PendingTransactionBuilder<N>> {
443        let from = request.from().ok_or_else(|| {
444            TransportError::from(alloy_transport::TransportErrorKind::Custom(
445                "TransactionRequest must have a `from` address set.".to_string().into(),
446            ))
447        })?;
448
449        let impersonate_future = self.anvil_impersonate_account(from);
450
451        if let Some(amount) = config.fund_amount {
452            let fund_future = self.anvil_set_balance(from, amount);
453            try_join!(fund_future, impersonate_future)?;
454        } else {
455            impersonate_future.await?;
456        }
457
458        let tx_hash = self.anvil_send_impersonated_transaction(request).await;
459
460        if config.stop_impersonate {
461            let stop_result = self.anvil_stop_impersonating_account(from).await;
462            if tx_hash.is_ok() {
463                stop_result?;
464            }
465        }
466
467        let pending = PendingTransactionBuilder::new(self.root().clone(), tx_hash?);
468        Ok(pending)
469    }
470}
471
472/// Configuration for impersonated transactions, including optional funding and whether to stop
473/// impersonation.
474#[derive(Debug, Clone)]
475pub struct ImpersonateConfig {
476    /// Optional amount of ETH to fund the impersonated account.
477    pub fund_amount: Option<U256>,
478    /// Whether to stop impersonating after the transaction is sent.
479    pub stop_impersonate: bool,
480}
481
482impl Default for ImpersonateConfig {
483    fn default() -> Self {
484        Self { fund_amount: None, stop_impersonate: true }
485    }
486}
487
488impl ImpersonateConfig {
489    /// Set the impersonation to continue after the transaction.
490    pub const fn keep_impersonate(mut self) -> Self {
491        self.stop_impersonate = false;
492        self
493    }
494
495    /// Set the impersonation to stop after the transaction.
496    pub const fn stop_impersonate(mut self) -> Self {
497        self.stop_impersonate = true;
498        self
499    }
500
501    /// Set the funding amount for the impersonated account.
502    pub const fn fund(mut self, amount: U256) -> Self {
503        self.fund_amount = Some(amount);
504        self
505    }
506
507    /// Clear the funding amount.
508    pub const fn no_fund(mut self) -> Self {
509        self.fund_amount = None;
510        self
511    }
512}
513
514#[cfg(test)]
515mod tests {
516    use super::*;
517    use crate::{
518        fillers::{ChainIdFiller, GasFiller},
519        ProviderBuilder,
520    };
521    use alloy_consensus::{BlockHeader, SidecarBuilder, SimpleCoder};
522    use alloy_eips::BlockNumberOrTag;
523    use alloy_network::{AnyNetwork, TransactionBuilder, TransactionBuilder4844};
524    use alloy_network_primitives::BlockResponse as _;
525    use alloy_primitives::{address, B256};
526    use alloy_rpc_types_eth::TransactionRequest;
527    use alloy_sol_types::{sol, SolCall};
528    use alloy_transport::mock::Asserter;
529
530    const FORK_URL: &str = "https://ethereum.reth.rs/rpc";
531
532    #[tokio::test]
533    async fn test_anvil_impersonate_account_stop_impersonating_account() {
534        let provider = ProviderBuilder::new()
535            .disable_recommended_fillers()
536            .with_simple_nonce_management()
537            .filler(GasFiller::default())
538            .filler(ChainIdFiller::default())
539            .connect_anvil();
540
541        let impersonate = Address::random();
542        let to = Address::random();
543        let val = U256::from(1337);
544        let funding = U256::from(1e18 as u64);
545
546        provider.anvil_set_balance(impersonate, funding).await.unwrap();
547
548        let balance = provider.get_balance(impersonate).await.unwrap();
549        assert_eq!(balance, funding);
550
551        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
552
553        let res = provider.send_transaction(tx.clone()).await;
554        res.unwrap_err();
555
556        provider.anvil_impersonate_account(impersonate).await.unwrap();
557        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
558
559        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
560        assert_eq!(res.from, impersonate);
561
562        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
563        assert_eq!(nonce, 1);
564
565        let balance = provider.get_balance(to).await.unwrap();
566        assert_eq!(balance, val);
567
568        provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
569        let res = provider.send_transaction(tx).await;
570        res.unwrap_err();
571    }
572
573    #[tokio::test]
574    async fn test_anvil_impersonated_send_with_config() {
575        let provider = ProviderBuilder::new()
576            .disable_recommended_fillers()
577            .with_simple_nonce_management()
578            .filler(GasFiller::default())
579            .filler(ChainIdFiller::default())
580            .connect_anvil();
581
582        let impersonate = Address::random();
583        let to = Address::random();
584        let val = U256::from(1337);
585        let funding = U256::from(1e18 as u64);
586
587        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
588
589        let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
590
591        let pending = provider
592            .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
593            .await
594            .expect("impersonated send failed");
595        let receipt = pending.get_receipt().await.unwrap();
596        assert_eq!(receipt.from, impersonate);
597
598        let recipient_balance = provider.get_balance(to).await.unwrap();
599        assert_eq!(recipient_balance, val);
600    }
601
602    #[tokio::test]
603    async fn test_anvil_impersonated_send_stops_on_send_error() {
604        let asserter = Asserter::new();
605        let provider = ProviderBuilder::new().connect_mocked_client(asserter.clone());
606
607        asserter.push_success(&());
608        asserter.push_failure_msg("send failed");
609        asserter.push_success(&());
610
611        let tx = TransactionRequest::default().with_from(Address::random());
612        let err = provider
613            .anvil_send_impersonated_transaction_with_config(tx, ImpersonateConfig::default())
614            .await
615            .unwrap_err();
616
617        assert!(err.to_string().contains("send failed"));
618        assert!(asserter.read_q().is_empty(), "stop impersonation response should be consumed");
619    }
620
621    #[tokio::test]
622    async fn test_anvil_auto_impersonate_account() {
623        let provider = ProviderBuilder::new()
624            .disable_recommended_fillers()
625            .with_simple_nonce_management()
626            .filler(GasFiller::default())
627            .filler(ChainIdFiller::default())
628            .connect_anvil();
629
630        let impersonate = Address::random();
631        let to = Address::random();
632        let val = U256::from(1337);
633        let funding = U256::from(1e18 as u64);
634
635        provider.anvil_set_balance(impersonate, funding).await.unwrap();
636
637        let balance = provider.get_balance(impersonate).await.unwrap();
638        assert_eq!(balance, funding);
639
640        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
641
642        let res = provider.send_transaction(tx.clone()).await;
643        res.unwrap_err();
644
645        provider.anvil_auto_impersonate_account(true).await.unwrap();
646
647        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
648        assert_eq!(res.from, impersonate);
649
650        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
651        assert_eq!(nonce, 1);
652
653        let balance = provider.get_balance(to).await.unwrap();
654        assert_eq!(balance, val);
655
656        provider.anvil_auto_impersonate_account(false).await.unwrap();
657        let res = provider.send_transaction(tx).await;
658        res.unwrap_err();
659
660        provider.anvil_impersonate_account(impersonate).await.unwrap();
661        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
662    }
663
664    #[tokio::test]
665    async fn test_anvil_get_auto_mine_set_auto_mine() {
666        let provider = ProviderBuilder::new().connect_anvil();
667
668        provider.anvil_set_auto_mine(false).await.unwrap();
669
670        let enabled = provider.anvil_get_auto_mine().await.unwrap();
671        assert!(!enabled);
672
673        provider.anvil_set_auto_mine(true).await.unwrap();
674
675        let enabled = provider.anvil_get_auto_mine().await.unwrap();
676        assert!(enabled);
677    }
678
679    #[tokio::test]
680    async fn test_anvil_mine() {
681        let provider = ProviderBuilder::new().connect_anvil();
682
683        let start_num = provider.get_block_number().await.unwrap();
684
685        provider.anvil_mine(Some(10), None).await.unwrap();
686
687        let num = provider.get_block_number().await.unwrap();
688
689        assert_eq!(num, start_num + 10);
690    }
691
692    #[tokio::test]
693    async fn test_anvil_set_interval_mining() {
694        let provider = ProviderBuilder::new().connect_anvil();
695
696        provider.anvil_set_interval_mining(1).await.unwrap();
697
698        let start_num = provider.get_block_number().await.unwrap();
699
700        tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
701
702        let num = provider.get_block_number().await.unwrap();
703
704        assert_eq!(num, start_num + 1);
705    }
706
707    #[tokio::test]
708    async fn test_anvil_drop_transaction() {
709        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
710
711        provider.anvil_set_auto_mine(false).await.unwrap();
712
713        let alice = provider.get_accounts().await.unwrap()[0];
714        let bob = provider.get_accounts().await.unwrap()[1];
715        let chain_id = provider.get_chain_id().await.unwrap();
716
717        let tx = TransactionRequest::default()
718            .with_from(alice)
719            .with_to(bob)
720            .with_nonce(0)
721            .with_chain_id(chain_id)
722            .with_value(U256::from(100))
723            .with_gas_limit(21_000)
724            .with_max_priority_fee_per_gas(1_000_000_000)
725            .with_max_fee_per_gas(20_000_000_000);
726
727        let tx_hash =
728            provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
729
730        let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
731
732        assert_eq!(res, Some(tx_hash));
733    }
734
735    #[tokio::test]
736    async fn test_anvil_drop_all_transactions() {
737        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
738
739        provider.anvil_set_auto_mine(false).await.unwrap();
740
741        let alice = provider.get_accounts().await.unwrap()[0];
742        let bob = provider.get_accounts().await.unwrap()[1];
743        let chain_id = provider.get_chain_id().await.unwrap();
744
745        let tx = TransactionRequest::default()
746            .with_from(alice)
747            .with_to(bob)
748            .with_nonce(0)
749            .with_chain_id(chain_id)
750            .with_value(U256::from(100))
751            .with_gas_limit(21_000)
752            .with_max_priority_fee_per_gas(1_000_000_000)
753            .with_max_fee_per_gas(20_000_000_000);
754
755        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
756
757        let tx = tx.clone().with_nonce(1);
758
759        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
760
761        provider.anvil_drop_all_transactions().await.unwrap();
762    }
763
764    #[tokio::test]
765    async fn test_anvil_reset() {
766        let provider = ProviderBuilder::new().connect_anvil();
767
768        let alice = Address::random();
769        let balance = U256::from(1e18 as u64);
770        provider.anvil_set_balance(alice, balance).await.unwrap();
771
772        let current_balance = provider.get_balance(alice).await.unwrap();
773        assert_eq!(current_balance, balance);
774
775        provider.anvil_reset(None).await.unwrap();
776
777        let reset_balance = provider.get_balance(alice).await.unwrap();
778        assert_eq!(reset_balance, U256::ZERO);
779    }
780
781    #[tokio::test]
782    async fn test_anvil_set_chain_id() {
783        let provider = ProviderBuilder::new().connect_anvil();
784
785        let chain_id = 1337;
786        provider.anvil_set_chain_id(chain_id).await.unwrap();
787
788        let new_chain_id = provider.get_chain_id().await.unwrap();
789        assert_eq!(new_chain_id, chain_id);
790    }
791
792    #[tokio::test]
793    async fn test_anvil_set_balance() {
794        let provider = ProviderBuilder::new().connect_anvil();
795
796        let address = Address::random();
797        let balance = U256::from(1337);
798        provider.anvil_set_balance(address, balance).await.unwrap();
799
800        let new_balance = provider.get_balance(address).await.unwrap();
801        assert_eq!(new_balance, balance);
802    }
803
804    #[tokio::test]
805    async fn test_anvil_set_code() {
806        let provider = ProviderBuilder::new().connect_anvil();
807
808        let address = Address::random();
809        provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
810
811        let code = provider.get_code_at(address).await.unwrap();
812        assert_eq!(code, Bytes::from("0xbeef"));
813    }
814
815    #[tokio::test]
816    async fn test_anvil_set_nonce() {
817        let provider = ProviderBuilder::new().connect_anvil();
818
819        let address = Address::random();
820        let nonce = 1337;
821        provider.anvil_set_nonce(address, nonce).await.unwrap();
822
823        let new_nonce = provider.get_transaction_count(address).await.unwrap();
824        assert_eq!(new_nonce, nonce);
825    }
826
827    #[tokio::test]
828    async fn test_anvil_set_storage_at() {
829        let provider = ProviderBuilder::new().connect_anvil();
830
831        let address = Address::random();
832        let slot = U256::from(1337);
833        let val = B256::from(U256::from(1337));
834        provider.anvil_set_storage_at(address, slot, val).await.unwrap();
835
836        let storage = provider.get_storage_at(address, slot).await.unwrap();
837        assert_eq!(B256::from(storage), val);
838    }
839
840    #[tokio::test]
841    async fn test_anvil_set_logging() {
842        let provider = ProviderBuilder::new().connect_anvil();
843
844        provider.anvil_set_logging(true).await.unwrap();
845    }
846
847    #[tokio::test]
848    async fn test_anvil_set_min_gas_price() {
849        let provider = ProviderBuilder::new().connect_anvil();
850
851        let gas = U256::from(1337);
852
853        if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
854            assert_eq!(
855                e.to_string(),
856                "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
857            );
858        }
859    }
860
861    #[tokio::test]
862    async fn test_anvil_set_next_block_base_fee_per_gas() {
863        let provider = ProviderBuilder::new().connect_anvil();
864
865        let basefee = 1337;
866        provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
867
868        provider.evm_mine(None).await.unwrap();
869
870        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
871
872        assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
873    }
874
875    #[tokio::test]
876    async fn test_anvil_set_coinbase() {
877        let provider = ProviderBuilder::new().connect_anvil();
878
879        let coinbase = Address::random();
880        provider.anvil_set_coinbase(coinbase).await.unwrap();
881
882        provider.evm_mine(None).await.unwrap();
883
884        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
885        assert_eq!(block.header.beneficiary, coinbase);
886    }
887
888    #[tokio::test]
889    async fn test_anvil_dump_state_load_state() {
890        let provider = ProviderBuilder::new().connect_anvil();
891
892        let state = provider.anvil_dump_state().await.unwrap();
893
894        assert!(!state.is_empty());
895
896        let res = provider.anvil_load_state(state).await.unwrap();
897
898        assert!(res);
899    }
900
901    #[tokio::test]
902    async fn test_anvil_node_info() {
903        let provider = ProviderBuilder::new().connect_anvil();
904
905        let latest_block =
906            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
907
908        provider.evm_mine(None).await.unwrap();
909
910        let node_info = provider.anvil_node_info().await.unwrap();
911
912        assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
913    }
914
915    #[tokio::test]
916    async fn test_anvil_metadata() {
917        let provider = ProviderBuilder::new().connect_anvil();
918
919        let client_version = provider.get_client_version().await.unwrap();
920        let chain_id = provider.get_chain_id().await.unwrap();
921
922        let metadata = provider.anvil_metadata().await.unwrap();
923
924        assert_eq!(metadata.client_version, client_version);
925        assert_eq!(metadata.chain_id, chain_id);
926    }
927
928    #[tokio::test]
929    async fn test_anvil_remove_pool_transactions() {
930        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
931
932        provider.anvil_set_auto_mine(false).await.unwrap();
933
934        let alice = provider.get_accounts().await.unwrap()[0];
935        let bob = provider.get_accounts().await.unwrap()[1];
936        let chain_id = provider.get_chain_id().await.unwrap();
937
938        let tx = TransactionRequest::default()
939            .with_from(alice)
940            .with_to(bob)
941            .with_nonce(0)
942            .with_chain_id(chain_id)
943            .with_value(U256::from(100))
944            .with_gas_limit(21_000)
945            .with_max_priority_fee_per_gas(1_000_000_000)
946            .with_max_fee_per_gas(20_000_000_000);
947
948        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
949
950        let tx = tx.clone().with_nonce(1);
951
952        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
953
954        provider.anvil_remove_pool_transactions(alice).await.unwrap();
955    }
956
957    #[tokio::test]
958    async fn test_anvil_snapshot_revert() {
959        let provider = ProviderBuilder::new().connect_anvil();
960
961        let snapshot_id = provider.anvil_snapshot().await.unwrap();
962
963        let alice = provider.get_accounts().await.unwrap()[0];
964        let bob = provider.get_accounts().await.unwrap()[1];
965        let chain_id = provider.get_chain_id().await.unwrap();
966
967        let tx = TransactionRequest::default()
968            .with_from(alice)
969            .with_to(bob)
970            .with_nonce(0)
971            .with_chain_id(chain_id)
972            .with_value(U256::from(100))
973            .with_gas_limit(21_000)
974            .with_max_priority_fee_per_gas(1_000_000_000)
975            .with_max_fee_per_gas(20_000_000_000);
976
977        provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
978
979        let tx = tx.clone().with_nonce(1);
980
981        provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
982
983        let tx_count = provider.get_transaction_count(alice).await.unwrap();
984        assert_eq!(tx_count, 2);
985
986        let res = provider.anvil_revert(snapshot_id).await.unwrap();
987        assert!(res);
988
989        let tx_count = provider.get_transaction_count(alice).await.unwrap();
990        assert_eq!(tx_count, 0);
991    }
992
993    #[tokio::test]
994    async fn test_anvil_increase_time() {
995        let provider = ProviderBuilder::new().connect_anvil();
996
997        let timestamp = provider
998            .get_block_by_number(BlockNumberOrTag::Latest)
999            .await
1000            .unwrap()
1001            .unwrap()
1002            .header
1003            .timestamp;
1004
1005        let seconds = provider.anvil_increase_time(1337).await.unwrap();
1006
1007        assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
1008    }
1009
1010    #[tokio::test]
1011    async fn test_anvil_set_next_block_timestamp() {
1012        let provider = ProviderBuilder::new().connect_anvil();
1013
1014        let timestamp = provider
1015            .get_block_by_number(BlockNumberOrTag::Latest)
1016            .await
1017            .unwrap()
1018            .unwrap()
1019            .header
1020            .timestamp;
1021
1022        provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
1023
1024        provider.evm_mine(None).await.unwrap();
1025
1026        let latest_block =
1027            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1028        assert_eq!(latest_block.header.timestamp, timestamp + 1337);
1029    }
1030
1031    #[tokio::test]
1032    async fn test_anvil_set_time() {
1033        let provider = ProviderBuilder::new().connect_anvil();
1034
1035        provider.anvil_set_time(0).await.unwrap();
1036
1037        let seconds = provider.anvil_set_time(1001).await.unwrap();
1038
1039        assert_eq!(seconds, 1001);
1040    }
1041
1042    #[tokio::test]
1043    async fn test_anvil_set_block_gas_limit() {
1044        let provider = ProviderBuilder::new().connect_anvil();
1045
1046        let block_gas_limit = 1337;
1047        assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1048
1049        provider.evm_mine(None).await.unwrap();
1050
1051        let latest_block =
1052            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1053        assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1054    }
1055
1056    #[tokio::test]
1057    async fn test_anvil_block_timestamp_interval() {
1058        let provider = ProviderBuilder::new().connect_anvil();
1059
1060        provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1061
1062        let start_timestamp = provider
1063            .get_block_by_number(BlockNumberOrTag::Latest)
1064            .await
1065            .unwrap()
1066            .unwrap()
1067            .header
1068            .timestamp;
1069
1070        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1071
1072        provider.evm_mine(None).await.unwrap();
1073
1074        let latest_block =
1075            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1076
1077        assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1078
1079        provider.anvil_remove_block_timestamp_interval().await.unwrap();
1080
1081        provider.evm_mine(None).await.unwrap();
1082
1083        let start_timestamp = provider
1084            .get_block_by_number(BlockNumberOrTag::Latest)
1085            .await
1086            .unwrap()
1087            .unwrap()
1088            .header
1089            .timestamp;
1090
1091        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1092
1093        let latest_block =
1094            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1095
1096        assert_eq!(latest_block.header.timestamp, start_timestamp);
1097    }
1098
1099    #[tokio::test]
1100    async fn test_evm_mine_single_block() {
1101        let provider = ProviderBuilder::new().connect_anvil();
1102
1103        let start_num = provider.get_block_number().await.unwrap();
1104
1105        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1106            provider.evm_mine(None).await.unwrap();
1107            let num = provider.get_block_number().await.unwrap();
1108            assert_eq!(num, start_num + idx as u64 + 1);
1109        }
1110
1111        let num = provider.get_block_number().await.unwrap();
1112        assert_eq!(num, start_num + 10);
1113    }
1114
1115    #[tokio::test]
1116    async fn test_evm_mine_with_configuration() {
1117        let provider = ProviderBuilder::new().connect_anvil();
1118
1119        let start_num = provider.get_block_number().await.unwrap();
1120
1121        provider
1122            .evm_mine(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1123            .await
1124            .unwrap();
1125
1126        let num = provider.get_block_number().await.unwrap();
1127        assert_eq!(num, start_num + 10);
1128    }
1129
1130    #[tokio::test]
1131    async fn test_anvil_mine_detailed_single_block() {
1132        let provider = ProviderBuilder::new().connect_anvil();
1133
1134        let start_num = provider.get_block_number().await.unwrap();
1135
1136        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1137            provider.anvil_mine_detailed(None).await.unwrap();
1138            let num = provider.get_block_number().await.unwrap();
1139            assert_eq!(num, start_num + idx as u64 + 1);
1140        }
1141
1142        let num = provider.get_block_number().await.unwrap();
1143        assert_eq!(num, start_num + 10);
1144    }
1145
1146    #[tokio::test]
1147    async fn test_anvil_mine_detailed_with_configuration() {
1148        let provider = ProviderBuilder::new().connect_anvil();
1149
1150        let start_num = provider.get_block_number().await.unwrap();
1151
1152        let blocks = provider
1153            .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1154            .await
1155            .unwrap();
1156
1157        let num = provider.get_block_number().await.unwrap();
1158        assert_eq!(num, start_num + 10);
1159
1160        for (idx, block) in blocks.iter().enumerate() {
1161            assert_eq!(block.header().number(), start_num + idx as u64 + 1);
1162        }
1163    }
1164
1165    #[tokio::test]
1166    async fn test_anvil_mine_detailed_with_any_network() {
1167        let provider = ProviderBuilder::new().network::<AnyNetwork>().connect_anvil();
1168
1169        let start_num = provider.get_block_number().await.unwrap();
1170
1171        let blocks = provider
1172            .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(2) }))
1173            .await
1174            .unwrap();
1175
1176        assert_eq!(blocks.len(), 2);
1177        for (idx, block) in blocks.iter().enumerate() {
1178            assert_eq!(block.header().number(), start_num + idx as u64 + 1);
1179        }
1180    }
1181
1182    #[tokio::test]
1183    async fn test_anvil_set_rpc_url() {
1184        let provider = ProviderBuilder::new().connect_anvil();
1185
1186        let url = "https://example.com".to_string();
1187        provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1188    }
1189
1190    #[tokio::test]
1191    async fn test_anvil_reorg() {
1192        let provider = ProviderBuilder::new().connect_anvil();
1193
1194        // Mine two blocks
1195        provider.anvil_mine(Some(2), None).await.unwrap();
1196
1197        let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1198        provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1199
1200        let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1201
1202        assert_eq!(reorged_block.header.number, new_block.header.number);
1203        assert_ne!(reorged_block.header.hash, new_block.header.hash);
1204    }
1205
1206    #[tokio::test]
1207    #[ignore]
1208    async fn test_anvil_rollback() {
1209        let provider = ProviderBuilder::new().connect_anvil();
1210
1211        // Mine two blocks
1212        provider.anvil_mine(Some(2), None).await.unwrap();
1213
1214        let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1215
1216        provider.anvil_rollback(Some(1)).await.unwrap();
1217
1218        let new_head =
1219            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1220
1221        assert_eq!(target_height, new_head);
1222    }
1223
1224    #[tokio::test]
1225    async fn test_eth_send_unsigned_transaction() {
1226        let provider = ProviderBuilder::new().connect_anvil();
1227
1228        let alice = Address::random();
1229        let bob = Address::random();
1230        let chain_id = provider.get_chain_id().await.unwrap();
1231
1232        provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1233
1234        let tx = TransactionRequest::default()
1235            .with_from(alice)
1236            .with_to(bob)
1237            .with_nonce(0)
1238            .with_chain_id(chain_id)
1239            .with_value(U256::from(100))
1240            .with_gas_limit(21_000)
1241            .with_max_priority_fee_per_gas(1_000_000_000)
1242            .with_max_fee_per_gas(20_000_000_000);
1243
1244        let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1245
1246        provider.evm_mine(None).await.unwrap();
1247
1248        let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1249        assert_eq!(res.from, alice);
1250        assert_eq!(res.to, Some(bob));
1251    }
1252
1253    #[tokio::test]
1254    async fn test_anvil_get_blob_by_versioned_hash() {
1255        std::thread::Builder::new()
1256            .stack_size(16 * 1024 * 1024)
1257            .spawn(|| {
1258                let rt = tokio::runtime::Runtime::new().unwrap();
1259                rt.block_on(async {
1260                    let provider = ProviderBuilder::new()
1261                        .connect_anvil_with_wallet_and_config(|anvil| {
1262                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1263                        })
1264                        .unwrap();
1265
1266                    let accounts = provider.get_accounts().await.unwrap();
1267                    let alice = accounts[0];
1268                    let bob = accounts[1];
1269                    let sidecar: SidecarBuilder<SimpleCoder> =
1270                        SidecarBuilder::from_slice(b"Blobs are fun!");
1271                    let sidecar = sidecar.build_4844().unwrap();
1272
1273                    let tx = TransactionRequest::default()
1274                        .with_from(alice)
1275                        .with_to(bob)
1276                        .with_blob_sidecar_4844(sidecar.clone());
1277
1278                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1279                    let _receipt = pending_tx.get_receipt().await.unwrap();
1280                    let hash = sidecar.versioned_hash_for_blob(0).unwrap();
1281
1282                    let blob =
1283                        provider.anvil_get_blob_by_versioned_hash(hash).await.unwrap().unwrap();
1284
1285                    assert_eq!(blob, sidecar.blobs[0]);
1286                });
1287            })
1288            .unwrap()
1289            .join()
1290            .unwrap();
1291    }
1292
1293    #[tokio::test]
1294    async fn test_anvil_get_blobs_by_tx_hash() {
1295        std::thread::Builder::new()
1296            .stack_size(16 * 1024 * 1024)
1297            .spawn(|| {
1298                let rt = tokio::runtime::Runtime::new().unwrap();
1299                rt.block_on(async {
1300                    let provider = ProviderBuilder::new()
1301                        .connect_anvil_with_wallet_and_config(|anvil| {
1302                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1303                        })
1304                        .unwrap();
1305
1306                    let accounts = provider.get_accounts().await.unwrap();
1307                    let alice = accounts[0];
1308                    let bob = accounts[1];
1309                    let sidecar: SidecarBuilder<SimpleCoder> =
1310                        SidecarBuilder::from_slice(b"Blobs are fun!");
1311                    let sidecar = sidecar.build_4844().unwrap();
1312
1313                    let tx = TransactionRequest::default()
1314                        .with_from(alice)
1315                        .with_to(bob)
1316                        .with_blob_sidecar_4844(sidecar.clone());
1317
1318                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1319                    let receipt = pending_tx.get_receipt().await.unwrap();
1320                    let tx_hash = receipt.transaction_hash;
1321
1322                    let blobs =
1323                        provider.anvil_get_blobs_by_tx_hash(tx_hash).await.unwrap().unwrap();
1324
1325                    assert_eq!(blobs, sidecar.blobs);
1326                });
1327            })
1328            .unwrap()
1329            .join()
1330            .unwrap();
1331    }
1332
1333    #[tokio::test]
1334    async fn test_anvil_deal_erc20() {
1335        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1336
1337        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1338        let user = Address::random();
1339        let amount = U256::from(1e18 as u64);
1340
1341        provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1342
1343        sol! {
1344            function balanceOf(address owner) view returns (uint256);
1345        }
1346
1347        let balance_of_call = balanceOfCall::new((user,));
1348        let input = balanceOfCall::abi_encode(&balance_of_call);
1349
1350        let result = provider
1351            .call(TransactionRequest::default().with_to(dai).with_input(input))
1352            .await
1353            .unwrap();
1354        let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1355
1356        assert_eq!(balance, amount);
1357    }
1358
1359    #[tokio::test]
1360    async fn test_anvil_set_erc20_allowance() {
1361        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1362
1363        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1364        let owner = Address::random();
1365        let spender = Address::random();
1366        let amount = U256::from(1e18 as u64);
1367
1368        provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1369
1370        sol! {
1371            function allowance(address owner, address spender) view returns (uint256);
1372        }
1373
1374        let allowance_call = allowanceCall::new((owner, spender));
1375        let input = allowanceCall::abi_encode(&allowance_call);
1376
1377        let result = provider
1378            .call(TransactionRequest::default().with_to(dai).with_input(input))
1379            .await
1380            .unwrap();
1381        let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1382
1383        assert_eq!(allowance, amount);
1384    }
1385}