1use crate::{
2 fillers::{
3 CachedNonceManager, ChainIdFiller, FillerControlFlow, GasFiller, JoinFill, NonceFiller,
4 NonceManager, RecommendedFillers, SimpleNonceManager, TxFiller, WalletFiller,
5 },
6 layers::{CallBatchLayer, ChainLayer},
7 provider::SendableTx,
8 Provider, RootProvider,
9};
10use alloy_chains::NamedChain;
11use alloy_network::{Ethereum, IntoWallet, Network};
12use alloy_primitives::ChainId;
13use alloy_rpc_client::{ClientBuilder, RpcClient};
14use alloy_transport::{TransportConnect, TransportError, TransportResult};
15use std::marker::PhantomData;
16
17pub trait ProviderLayer<P: Provider<N>, N: Network = Ethereum> {
21 type Provider: Provider<N>;
23
24 fn layer(&self, inner: P) -> Self::Provider;
26}
27
28#[derive(Clone, Copy, Debug)]
30pub struct Identity;
31
32impl<N> TxFiller<N> for Identity
33where
34 N: Network,
35{
36 type Fillable = ();
37
38 fn status(&self, _tx: &<N as Network>::TransactionRequest) -> FillerControlFlow {
39 FillerControlFlow::Finished
40 }
41
42 fn fill_sync(&self, _tx: &mut SendableTx<N>) {}
43
44 async fn prepare<P>(
45 &self,
46 _provider: &P,
47 _tx: &N::TransactionRequest,
48 ) -> TransportResult<Self::Fillable> {
49 Ok(())
50 }
51
52 async fn fill(
53 &self,
54 _to_fill: Self::Fillable,
55 tx: SendableTx<N>,
56 ) -> TransportResult<SendableTx<N>> {
57 Ok(tx)
58 }
59}
60
61impl<P, N> ProviderLayer<P, N> for Identity
62where
63 N: Network,
64 P: Provider<N>,
65{
66 type Provider = P;
67
68 fn layer(&self, inner: P) -> Self::Provider {
69 inner
70 }
71}
72
73#[derive(Debug)]
75pub struct Stack<Inner, Outer> {
76 inner: Inner,
77 outer: Outer,
78}
79
80impl<Inner, Outer> Stack<Inner, Outer> {
81 pub const fn new(inner: Inner, outer: Outer) -> Self {
83 Self { inner, outer }
84 }
85}
86
87impl<P, N, Inner, Outer> ProviderLayer<P, N> for Stack<Inner, Outer>
88where
89 N: Network,
90 P: Provider<N>,
91 Inner: ProviderLayer<P, N>,
92 Outer: ProviderLayer<Inner::Provider, N>,
93{
94 type Provider = Outer::Provider;
95
96 fn layer(&self, provider: P) -> Self::Provider {
97 let inner = self.inner.layer(provider);
98
99 self.outer.layer(inner)
100 }
101}
102
103#[derive(Debug)]
117pub struct ProviderBuilder<L, F, N = Ethereum> {
118 layer: L,
119 filler: F,
120 network: PhantomData<fn() -> N>,
121}
122
123impl
124 ProviderBuilder<
125 Identity,
126 JoinFill<Identity, <Ethereum as RecommendedFillers>::RecommendedFillers>,
127 Ethereum,
128 >
129{
130 pub fn new() -> Self {
140 ProviderBuilder::default().with_recommended_fillers()
141 }
142
143 pub fn disable_recommended_fillers(self) -> ProviderBuilder<Identity, Identity, Ethereum> {
148 ProviderBuilder { layer: self.layer, filler: Identity, network: self.network }
149 }
150}
151
152impl<N> Default for ProviderBuilder<Identity, Identity, N> {
153 fn default() -> Self {
154 Self { layer: Identity, filler: Identity, network: PhantomData }
155 }
156}
157
158impl ProviderBuilder<Identity, Identity, Ethereum> {
159 pub fn new_with_network<Net: RecommendedFillers>(
162 ) -> ProviderBuilder<Identity, JoinFill<Identity, Net::RecommendedFillers>, Net> {
163 ProviderBuilder {
164 layer: Identity,
165 filler: JoinFill::new(Identity, Net::recommended_fillers()),
166 network: PhantomData,
167 }
168 }
169}
170
171impl<L, N: Network> ProviderBuilder<L, Identity, N> {
172 pub fn with_recommended_fillers(
175 self,
176 ) -> ProviderBuilder<L, JoinFill<Identity, N::RecommendedFillers>, N>
177 where
178 N: RecommendedFillers,
179 {
180 self.filler(N::recommended_fillers())
181 }
182}
183
184impl<L, F, N> ProviderBuilder<L, F, N> {
185 pub fn layer<Inner>(self, layer: Inner) -> ProviderBuilder<Stack<Inner, L>, F, N> {
197 ProviderBuilder {
198 layer: Stack::new(layer, self.layer),
199 filler: self.filler,
200 network: PhantomData,
201 }
202 }
203
204 pub fn filler<F2>(self, filler: F2) -> ProviderBuilder<L, JoinFill<F, F2>, N> {
208 ProviderBuilder {
209 layer: self.layer,
210 filler: JoinFill::new(self.filler, filler),
211 network: PhantomData,
212 }
213 }
214
215 pub fn network<Net: Network>(self) -> ProviderBuilder<L, F, Net> {
224 ProviderBuilder { layer: self.layer, filler: self.filler, network: PhantomData }
225 }
226
227 pub fn with_chain(self, chain: NamedChain) -> ProviderBuilder<Stack<ChainLayer, L>, F, N> {
232 self.layer(ChainLayer::new(chain))
233 }
234
235 pub fn with_gas_estimation(self) -> ProviderBuilder<L, JoinFill<F, GasFiller>, N> {
241 self.filler(GasFiller)
242 }
243
244 pub fn with_nonce_management<M: NonceManager>(
248 self,
249 nonce_manager: M,
250 ) -> ProviderBuilder<L, JoinFill<F, NonceFiller<M>>, N> {
251 self.filler(NonceFiller::new(nonce_manager))
252 }
253
254 pub fn with_simple_nonce_management(
258 self,
259 ) -> ProviderBuilder<L, JoinFill<F, NonceFiller<SimpleNonceManager>>, N> {
260 self.with_nonce_management(SimpleNonceManager::default())
261 }
262
263 pub fn with_cached_nonce_management(
267 self,
268 ) -> ProviderBuilder<L, JoinFill<F, NonceFiller<CachedNonceManager>>, N> {
269 self.with_nonce_management(CachedNonceManager::default())
270 }
271
272 pub fn fetch_chain_id(self) -> ProviderBuilder<L, JoinFill<F, ChainIdFiller>, N> {
277 self.filler(ChainIdFiller::default())
278 }
279
280 pub fn with_chain_id(
284 self,
285 chain_id: ChainId,
286 ) -> ProviderBuilder<L, JoinFill<F, ChainIdFiller>, N> {
287 self.filler(ChainIdFiller::new(Some(chain_id)))
288 }
289
290 pub fn wallet<W: IntoWallet<N>>(
294 self,
295 wallet: W,
296 ) -> ProviderBuilder<L, JoinFill<F, WalletFiller<W::NetworkWallet>>, N>
297 where
298 N: Network,
299 {
300 self.filler(WalletFiller::new(wallet.into_wallet()))
301 }
302
303 pub fn with_call_batching(self) -> ProviderBuilder<Stack<CallBatchLayer, L>, F, N> {
309 self.layer(CallBatchLayer::new())
310 }
311
312 pub fn with_arbitrum_call_batching(self) -> ProviderBuilder<Stack<CallBatchLayer, L>, F, N> {
317 self.layer(CallBatchLayer::new().arbitrum_compat())
318 }
319
320 pub fn connect_provider<P>(self, provider: P) -> F::Provider
325 where
326 L: ProviderLayer<P, N>,
327 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
328 P: Provider<N>,
329 N: Network,
330 {
331 let Self { layer, filler, network: PhantomData } = self;
332 let stack = Stack::new(layer, filler);
333 stack.layer(provider)
334 }
335
336 #[deprecated(since = "0.12.6", note = "use `connect_provider` instead")]
339 pub fn on_provider<P>(self, provider: P) -> F::Provider
340 where
341 L: ProviderLayer<P, N>,
342 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
343 P: Provider<N>,
344 N: Network,
345 {
346 let Self { layer, filler, network: PhantomData } = self;
347 let stack = Stack::new(layer, filler);
348 stack.layer(provider)
349 }
350
351 pub fn connect_client(self, client: RpcClient) -> F::Provider
357 where
358 L: ProviderLayer<RootProvider<N>, N>,
359 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
360 N: Network,
361 {
362 self.connect_provider(RootProvider::new(client))
363 }
364
365 #[deprecated(since = "0.12.6", note = "use `connect_client` instead")]
371 pub fn on_client(self, client: RpcClient) -> F::Provider
372 where
373 L: ProviderLayer<RootProvider<N>, N>,
374 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
375 N: Network,
376 {
377 self.connect_provider(RootProvider::new(client))
378 }
379
380 pub fn connect_mocked_client(self, asserter: alloy_transport::mock::Asserter) -> F::Provider
386 where
387 L: ProviderLayer<RootProvider<N>, N>,
388 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
389 N: Network,
390 {
391 self.connect_client(RpcClient::mocked(asserter))
392 }
393
394 #[deprecated(since = "0.12.6", note = "use `connect_mocked_client` instead")]
400 pub fn on_mocked_client(self, asserter: alloy_transport::mock::Asserter) -> F::Provider
401 where
402 L: ProviderLayer<RootProvider<N>, N>,
403 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
404 N: Network,
405 {
406 self.connect_client(RpcClient::mocked(asserter))
407 }
408
409 #[doc(alias = "on_builtin")]
413 pub async fn connect(self, s: &str) -> Result<F::Provider, TransportError>
414 where
415 L: ProviderLayer<RootProvider<N>, N>,
416 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
417 N: Network,
418 {
419 let client = ClientBuilder::default().connect(s).await?;
420 Ok(self.connect_client(client))
421 }
422
423 pub async fn connect_with<C>(self, connect: &C) -> Result<F::Provider, TransportError>
425 where
426 L: ProviderLayer<RootProvider<N>, N>,
427 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
428 N: Network,
429 C: TransportConnect,
430 {
431 connect
432 .get_transport()
433 .await
434 .map(|t| RpcClient::new(t, connect.is_local()))
435 .map(|client| self.connect_client(client))
436 }
437
438 #[cfg(feature = "pubsub")]
443 pub async fn connect_pubsub_with<C>(self, connect: C) -> Result<F::Provider, TransportError>
444 where
445 L: ProviderLayer<RootProvider<N>, N>,
446 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
447 N: Network,
448 C: alloy_pubsub::PubSubConnect,
449 {
450 ClientBuilder::default().pubsub(connect).await.map(|client| self.connect_client(client))
451 }
452
453 #[deprecated = "use `connect` instead"]
457 #[doc(hidden)]
458 pub async fn on_builtin(self, s: &str) -> Result<F::Provider, TransportError>
459 where
460 L: ProviderLayer<RootProvider<N>, N>,
461 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
462 N: Network,
463 {
464 self.connect(s).await
465 }
466
467 #[cfg(feature = "ws")]
469 pub async fn connect_ws(
470 self,
471 connect: alloy_transport_ws::WsConnect,
472 ) -> Result<F::Provider, TransportError>
473 where
474 L: ProviderLayer<RootProvider<N>, N>,
475 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
476 N: Network,
477 {
478 let client = ClientBuilder::default().ws(connect).await?;
479 Ok(self.connect_client(client))
480 }
481
482 #[cfg(feature = "ws")]
484 #[deprecated(since = "0.12.6", note = "use `connect_ws` instead")]
485 pub async fn on_ws(
486 self,
487 connect: alloy_transport_ws::WsConnect,
488 ) -> Result<F::Provider, TransportError>
489 where
490 L: ProviderLayer<RootProvider<N>, N>,
491 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
492 N: Network,
493 {
494 let client = ClientBuilder::default().ws(connect).await?;
495 Ok(self.connect_client(client))
496 }
497
498 #[cfg(feature = "ipc")]
500 pub async fn connect_ipc<T>(
501 self,
502 connect: alloy_transport_ipc::IpcConnect<T>,
503 ) -> Result<F::Provider, TransportError>
504 where
505 alloy_transport_ipc::IpcConnect<T>: alloy_pubsub::PubSubConnect,
506 L: ProviderLayer<RootProvider<N>, N>,
507 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
508 N: Network,
509 {
510 let client = ClientBuilder::default().ipc(connect).await?;
511 Ok(self.connect_client(client))
512 }
513
514 #[cfg(feature = "ipc")]
516 #[deprecated(since = "0.12.6", note = "use `connect_ipc` instead")]
517 pub async fn on_ipc<T>(
518 self,
519 connect: alloy_transport_ipc::IpcConnect<T>,
520 ) -> Result<F::Provider, TransportError>
521 where
522 alloy_transport_ipc::IpcConnect<T>: alloy_pubsub::PubSubConnect,
523 L: ProviderLayer<RootProvider<N>, N>,
524 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
525 N: Network,
526 {
527 let client = ClientBuilder::default().ipc(connect).await?;
528 Ok(self.connect_client(client))
529 }
530
531 #[cfg(any(test, feature = "reqwest"))]
533 pub fn connect_http(self, url: reqwest::Url) -> F::Provider
534 where
535 L: ProviderLayer<crate::RootProvider<N>, N>,
536 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
537 N: Network,
538 {
539 let client = ClientBuilder::default().http(url);
540 self.connect_client(client)
541 }
542
543 #[cfg(any(test, feature = "reqwest"))]
545 pub fn connect_reqwest<C>(self, client: C, url: reqwest::Url) -> F::Provider
546 where
547 L: ProviderLayer<crate::RootProvider<N>, N>,
548 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
549 N: Network,
550 C: Into<reqwest::Client>,
551 {
552 let client = ClientBuilder::default().http_with_client(client.into(), url);
553 self.connect_client(client)
554 }
555
556 #[cfg(any(test, feature = "reqwest"))]
558 pub fn with_reqwest<B>(self, url: reqwest::Url, builder: B) -> F::Provider
559 where
560 L: ProviderLayer<crate::RootProvider<N>, N>,
561 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
562 N: Network,
563 B: FnOnce(reqwest::ClientBuilder) -> reqwest::Client,
564 {
565 self.connect_reqwest(builder(reqwest::ClientBuilder::default()), url)
566 }
567
568 #[cfg(any(test, feature = "reqwest"))]
570 #[deprecated(since = "0.12.6", note = "use `connect_http` instead")]
571 pub fn on_http(self, url: reqwest::Url) -> F::Provider
572 where
573 L: ProviderLayer<RootProvider<N>, N>,
574 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
575 N: Network,
576 {
577 let client = ClientBuilder::default().http(url);
578 self.connect_client(client)
579 }
580
581 #[cfg(feature = "hyper")]
583 pub fn connect_hyper_http(self, url: url::Url) -> F::Provider
584 where
585 L: ProviderLayer<crate::RootProvider<N>, N>,
586 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
587 N: Network,
588 {
589 let client = ClientBuilder::default().hyper_http(url);
590 self.connect_client(client)
591 }
592
593 #[cfg(feature = "hyper")]
595 #[deprecated(since = "0.12.6", note = "use `connect_hyper_http` instead")]
596 pub fn on_hyper_http(self, url: url::Url) -> F::Provider
597 where
598 L: ProviderLayer<RootProvider<N>, N>,
599 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
600 N: Network,
601 {
602 let client = ClientBuilder::default().hyper_http(url);
603 self.connect_client(client)
604 }
605}
606
607#[cfg(any(test, feature = "anvil-node"))]
608type JoinedEthereumWalletFiller<F> = JoinFill<F, WalletFiller<alloy_network::EthereumWallet>>;
609
610#[cfg(any(test, feature = "anvil-node"))]
611type AnvilProviderResult<T> = Result<T, alloy_node_bindings::NodeError>;
612
613#[cfg(any(test, feature = "anvil-node"))]
614impl<L, F, N: Network> ProviderBuilder<L, F, N> {
615 pub fn connect_anvil(self) -> F::Provider
617 where
618 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
619 L: crate::builder::ProviderLayer<
620 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
621 N,
622 >,
623 {
624 self.connect_anvil_with_config(std::convert::identity)
625 }
626
627 #[deprecated(since = "0.12.6", note = "use `connect_anvil` instead")]
629 pub fn on_anvil(self) -> F::Provider
630 where
631 L: ProviderLayer<crate::layers::AnvilProvider<RootProvider<N>, N>, N>,
632 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
633 {
634 self.connect_anvil_with_config(std::convert::identity)
635 }
636
637 pub fn connect_anvil_with_wallet(
641 self,
642 ) -> <JoinedEthereumWalletFiller<F> as ProviderLayer<L::Provider, N>>::Provider
643 where
644 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
645 L: crate::builder::ProviderLayer<
646 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
647 N,
648 >,
649 alloy_network::EthereumWallet: alloy_network::NetworkWallet<N>,
650 {
651 self.connect_anvil_with_wallet_and_config(std::convert::identity)
652 .expect("failed to build provider")
653 }
654
655 #[deprecated(since = "0.12.6", note = "use `connect_anvil_with_wallet` instead")]
659 pub fn on_anvil_with_wallet(
660 self,
661 ) -> <JoinedEthereumWalletFiller<F> as ProviderLayer<L::Provider, N>>::Provider
662 where
663 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
664 L: crate::builder::ProviderLayer<
665 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
666 N,
667 >,
668 alloy_network::EthereumWallet: alloy_network::NetworkWallet<N>,
669 {
670 self.connect_anvil_with_wallet_and_config(std::convert::identity)
671 .expect("failed to build provider")
672 }
673
674 pub fn connect_anvil_with_config(
677 self,
678 f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil,
679 ) -> F::Provider
680 where
681 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
682 L: crate::builder::ProviderLayer<
683 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
684 N,
685 >,
686 {
687 let anvil_layer = crate::layers::AnvilLayer::from(f(Default::default()));
688 let url = anvil_layer.endpoint_url();
689
690 let rpc_client = ClientBuilder::default().http(url);
691
692 self.layer(anvil_layer).connect_client(rpc_client)
693 }
694
695 #[deprecated(since = "0.12.6", note = "use `connect_anvil_with_config` instead")]
698 pub fn on_anvil_with_config(
699 self,
700 f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil,
701 ) -> F::Provider
702 where
703 L: ProviderLayer<crate::layers::AnvilProvider<RootProvider<N>, N>, N>,
704 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
705 {
706 let anvil_layer = crate::layers::AnvilLayer::from(f(Default::default()));
707 let url = anvil_layer.endpoint_url();
708
709 let rpc_client = ClientBuilder::default().http(url);
710
711 self.layer(anvil_layer).connect_client(rpc_client)
712 }
713
714 pub fn connect_anvil_with_wallet_and_config(
717 self,
718 f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil,
719 ) -> AnvilProviderResult<
720 <JoinedEthereumWalletFiller<F> as ProviderLayer<L::Provider, N>>::Provider,
721 >
722 where
723 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
724 L: crate::builder::ProviderLayer<
725 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
726 N,
727 >,
728 alloy_network::EthereumWallet: alloy_network::NetworkWallet<N>,
729 {
730 let anvil_layer = crate::layers::AnvilLayer::from(f(Default::default()));
731 let url = anvil_layer.endpoint_url();
732
733 let wallet = anvil_layer
734 .instance()
735 .wallet()
736 .ok_or(alloy_node_bindings::NodeError::NoKeysAvailable)?;
737
738 let rpc_client = ClientBuilder::default().http(url);
739
740 Ok(self.wallet(wallet).layer(anvil_layer).connect_client(rpc_client))
741 }
742
743 #[deprecated(since = "0.12.6", note = "use `connect_anvil_with_wallet_and_config` instead")]
746 pub fn on_anvil_with_wallet_and_config(
747 self,
748 f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil,
749 ) -> AnvilProviderResult<
750 <JoinedEthereumWalletFiller<F> as ProviderLayer<L::Provider, N>>::Provider,
751 >
752 where
753 F: TxFiller<N> + ProviderLayer<L::Provider, N>,
754 L: crate::builder::ProviderLayer<
755 crate::layers::AnvilProvider<crate::provider::RootProvider<N>, N>,
756 N,
757 >,
758 alloy_network::EthereumWallet: alloy_network::NetworkWallet<N>,
759 {
760 let anvil_layer = crate::layers::AnvilLayer::from(f(Default::default()));
761 let url = anvil_layer.endpoint_url();
762
763 let wallet = anvil_layer
764 .instance()
765 .wallet()
766 .ok_or(alloy_node_bindings::NodeError::NoKeysAvailable)?;
767
768 let rpc_client = ClientBuilder::default().http(url);
769
770 Ok(self.wallet(wallet).layer(anvil_layer).connect_client(rpc_client))
771 }
772}
773
774#[cfg(test)]
775mod tests {
776 use super::*;
777 use crate::Provider;
778 use alloy_network::AnyNetwork;
779
780 #[tokio::test]
781 async fn basic() {
782 let provider = ProviderBuilder::new()
783 .with_cached_nonce_management()
784 .with_call_batching()
785 .connect_http("http://localhost:8545".parse().unwrap());
786 let _ = provider.get_account(Default::default());
787 let provider = provider.erased();
788 let _ = provider.get_account(Default::default());
789 }
790
791 #[tokio::test]
792 #[cfg(feature = "reqwest")]
793 async fn test_connect_reqwest() {
794 let provider = ProviderBuilder::new()
795 .with_cached_nonce_management()
796 .with_call_batching()
797 .connect_reqwest(
798 reqwest::Client::new(),
799 reqwest::Url::parse("http://localhost:8545").unwrap(),
800 );
801 let _ = provider.get_account(Default::default());
802 let provider = provider.erased();
803 let _ = provider.get_account(Default::default());
804 }
805
806 #[tokio::test]
807 #[cfg(feature = "reqwest")]
808 async fn test_with_reqwest() {
809 let provider = ProviderBuilder::new()
810 .with_cached_nonce_management()
811 .with_call_batching()
812 .with_reqwest(reqwest::Url::parse("http://localhost:8545").unwrap(), |builder| {
813 builder
814 .user_agent("alloy/test")
815 .timeout(std::time::Duration::from_secs(10))
816 .build()
817 .expect("failed to build reqwest client")
818 });
819 let _ = provider.get_account(Default::default());
820 let provider = provider.erased();
821 let _ = provider.get_account(Default::default());
822 }
823
824 #[tokio::test]
825 async fn compile_with_network() {
826 let p = ProviderBuilder::new_with_network::<AnyNetwork>().connect_anvil();
827 let num = p.get_block_number().await.unwrap();
828 assert_eq!(num, 0);
829 }
830}