starknet_providers/
any.rs

1use async_trait::async_trait;
2use starknet_core::types::{
3    BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction,
4    BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction,
5    ConfirmedBlockId, ContractClass, ContractStorageKeys, DeclareTransactionResult,
6    DeployAccountTransactionResult, EventFilter, EventsPage, FeeEstimate, Felt, FunctionCall,
7    Hash256, InvokeTransactionResult, MaybePreConfirmedBlockWithReceipts,
8    MaybePreConfirmedBlockWithTxHashes, MaybePreConfirmedBlockWithTxs,
9    MaybePreConfirmedStateUpdate, MessageFeeEstimate, MessageStatus, MsgFromL1,
10    SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, StorageProof,
11    SyncStatusType, Transaction, TransactionReceiptWithBlockInfo, TransactionStatus,
12    TransactionTrace, TransactionTraceWithHash,
13};
14
15use crate::{
16    jsonrpc::{HttpTransport, JsonRpcClient},
17    Provider, ProviderError, ProviderRequestData, ProviderResponseData, SequencerGatewayProvider,
18};
19
20/// A convenient Box-able type that implements the [Provider] trait. This can be useful when you
21/// want to accept any built-in provider implementation from the library in your appliation, since
22/// the [Provider] trait itself cannot be Box-ed due to the use of associated type.
23///
24/// A recommended pattern is to make your business logic code (e.g. functions) generic over the
25/// [Provider] trait, while using this [`AnyProvider`] type for bootstrapping your application.
26///
27/// NOTE: This type was introduced when [Provider] was not Box-able. It should be reviewed whether
28///       it's still needed anymore.
29#[derive(Debug)]
30pub enum AnyProvider {
31    /// JSON-RPC provider.
32    JsonRpcHttp(JsonRpcClient<HttpTransport>),
33    /// Sequencer gateway provider.
34    SequencerGateway(SequencerGatewayProvider),
35}
36
37#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
38#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
39impl Provider for AnyProvider {
40    async fn spec_version(&self) -> Result<String, ProviderError> {
41        match self {
42            Self::JsonRpcHttp(inner) => {
43                <JsonRpcClient<HttpTransport> as Provider>::spec_version(inner).await
44            }
45            Self::SequencerGateway(inner) => {
46                <SequencerGatewayProvider as Provider>::spec_version(inner).await
47            }
48        }
49    }
50
51    async fn get_block_with_tx_hashes<B>(
52        &self,
53        block_id: B,
54    ) -> Result<MaybePreConfirmedBlockWithTxHashes, ProviderError>
55    where
56        B: AsRef<BlockId> + Send + Sync,
57    {
58        match self {
59            Self::JsonRpcHttp(inner) => {
60                <JsonRpcClient<HttpTransport> as Provider>::get_block_with_tx_hashes(
61                    inner, block_id,
62                )
63                .await
64            }
65            Self::SequencerGateway(inner) => {
66                <SequencerGatewayProvider as Provider>::get_block_with_tx_hashes(inner, block_id)
67                    .await
68            }
69        }
70    }
71
72    async fn get_block_with_txs<B>(
73        &self,
74        block_id: B,
75    ) -> Result<MaybePreConfirmedBlockWithTxs, ProviderError>
76    where
77        B: AsRef<BlockId> + Send + Sync,
78    {
79        match self {
80            Self::JsonRpcHttp(inner) => {
81                <JsonRpcClient<HttpTransport> as Provider>::get_block_with_txs(inner, block_id)
82                    .await
83            }
84            Self::SequencerGateway(inner) => {
85                <SequencerGatewayProvider as Provider>::get_block_with_txs(inner, block_id).await
86            }
87        }
88    }
89
90    async fn get_block_with_receipts<B>(
91        &self,
92        block_id: B,
93    ) -> Result<MaybePreConfirmedBlockWithReceipts, ProviderError>
94    where
95        B: AsRef<BlockId> + Send + Sync,
96    {
97        match self {
98            Self::JsonRpcHttp(inner) => {
99                <JsonRpcClient<HttpTransport> as Provider>::get_block_with_receipts(inner, block_id)
100                    .await
101            }
102            Self::SequencerGateway(inner) => {
103                <SequencerGatewayProvider as Provider>::get_block_with_receipts(inner, block_id)
104                    .await
105            }
106        }
107    }
108
109    async fn get_state_update<B>(
110        &self,
111        block_id: B,
112    ) -> Result<MaybePreConfirmedStateUpdate, ProviderError>
113    where
114        B: AsRef<BlockId> + Send + Sync,
115    {
116        match self {
117            Self::JsonRpcHttp(inner) => {
118                <JsonRpcClient<HttpTransport> as Provider>::get_state_update(inner, block_id).await
119            }
120            Self::SequencerGateway(inner) => {
121                <SequencerGatewayProvider as Provider>::get_state_update(inner, block_id).await
122            }
123        }
124    }
125
126    async fn get_storage_at<A, K, B>(
127        &self,
128        contract_address: A,
129        key: K,
130        block_id: B,
131    ) -> Result<Felt, ProviderError>
132    where
133        A: AsRef<Felt> + Send + Sync,
134        K: AsRef<Felt> + Send + Sync,
135        B: AsRef<BlockId> + Send + Sync,
136    {
137        match self {
138            Self::JsonRpcHttp(inner) => {
139                <JsonRpcClient<HttpTransport> as Provider>::get_storage_at(
140                    inner,
141                    contract_address,
142                    key,
143                    block_id,
144                )
145                .await
146            }
147            Self::SequencerGateway(inner) => {
148                <SequencerGatewayProvider as Provider>::get_storage_at(
149                    inner,
150                    contract_address,
151                    key,
152                    block_id,
153                )
154                .await
155            }
156        }
157    }
158
159    async fn get_messages_status(
160        &self,
161        transaction_hash: Hash256,
162    ) -> Result<Vec<MessageStatus>, ProviderError> {
163        match self {
164            Self::JsonRpcHttp(inner) => {
165                <JsonRpcClient<HttpTransport> as Provider>::get_messages_status(
166                    inner,
167                    transaction_hash,
168                )
169                .await
170            }
171            Self::SequencerGateway(inner) => {
172                <SequencerGatewayProvider as Provider>::get_messages_status(inner, transaction_hash)
173                    .await
174            }
175        }
176    }
177
178    async fn get_transaction_status<H>(
179        &self,
180        transaction_hash: H,
181    ) -> Result<TransactionStatus, ProviderError>
182    where
183        H: AsRef<Felt> + Send + Sync,
184    {
185        match self {
186            Self::JsonRpcHttp(inner) => {
187                <JsonRpcClient<HttpTransport> as Provider>::get_transaction_status(
188                    inner,
189                    transaction_hash,
190                )
191                .await
192            }
193            Self::SequencerGateway(inner) => {
194                <SequencerGatewayProvider as Provider>::get_transaction_status(
195                    inner,
196                    transaction_hash,
197                )
198                .await
199            }
200        }
201    }
202
203    async fn get_transaction_by_hash<H>(
204        &self,
205        transaction_hash: H,
206    ) -> Result<Transaction, ProviderError>
207    where
208        H: AsRef<Felt> + Send + Sync,
209    {
210        match self {
211            Self::JsonRpcHttp(inner) => {
212                <JsonRpcClient<HttpTransport> as Provider>::get_transaction_by_hash(
213                    inner,
214                    transaction_hash,
215                )
216                .await
217            }
218            Self::SequencerGateway(inner) => {
219                <SequencerGatewayProvider as Provider>::get_transaction_by_hash(
220                    inner,
221                    transaction_hash,
222                )
223                .await
224            }
225        }
226    }
227
228    async fn get_transaction_by_block_id_and_index<B>(
229        &self,
230        block_id: B,
231        index: u64,
232    ) -> Result<Transaction, ProviderError>
233    where
234        B: AsRef<BlockId> + Send + Sync,
235    {
236        match self {
237            Self::JsonRpcHttp(inner) => {
238                <JsonRpcClient<HttpTransport> as Provider>::get_transaction_by_block_id_and_index(
239                    inner, block_id, index,
240                )
241                .await
242            }
243            Self::SequencerGateway(inner) => {
244                <SequencerGatewayProvider as Provider>::get_transaction_by_block_id_and_index(
245                    inner, block_id, index,
246                )
247                .await
248            }
249        }
250    }
251
252    async fn get_transaction_receipt<H>(
253        &self,
254        transaction_hash: H,
255    ) -> Result<TransactionReceiptWithBlockInfo, ProviderError>
256    where
257        H: AsRef<Felt> + Send + Sync,
258    {
259        match self {
260            Self::JsonRpcHttp(inner) => {
261                <JsonRpcClient<HttpTransport> as Provider>::get_transaction_receipt(
262                    inner,
263                    transaction_hash,
264                )
265                .await
266            }
267            Self::SequencerGateway(inner) => {
268                <SequencerGatewayProvider as Provider>::get_transaction_receipt(
269                    inner,
270                    transaction_hash,
271                )
272                .await
273            }
274        }
275    }
276
277    async fn get_class<B, H>(
278        &self,
279        block_id: B,
280        class_hash: H,
281    ) -> Result<ContractClass, ProviderError>
282    where
283        B: AsRef<BlockId> + Send + Sync,
284        H: AsRef<Felt> + Send + Sync,
285    {
286        match self {
287            Self::JsonRpcHttp(inner) => {
288                <JsonRpcClient<HttpTransport> as Provider>::get_class(inner, block_id, class_hash)
289                    .await
290            }
291            Self::SequencerGateway(inner) => {
292                <SequencerGatewayProvider as Provider>::get_class(inner, block_id, class_hash).await
293            }
294        }
295    }
296
297    async fn get_class_hash_at<B, A>(
298        &self,
299        block_id: B,
300        contract_address: A,
301    ) -> Result<Felt, ProviderError>
302    where
303        B: AsRef<BlockId> + Send + Sync,
304        A: AsRef<Felt> + Send + Sync,
305    {
306        match self {
307            Self::JsonRpcHttp(inner) => {
308                <JsonRpcClient<HttpTransport> as Provider>::get_class_hash_at(
309                    inner,
310                    block_id,
311                    contract_address,
312                )
313                .await
314            }
315            Self::SequencerGateway(inner) => {
316                <SequencerGatewayProvider as Provider>::get_class_hash_at(
317                    inner,
318                    block_id,
319                    contract_address,
320                )
321                .await
322            }
323        }
324    }
325
326    async fn get_class_at<B, A>(
327        &self,
328        block_id: B,
329        contract_address: A,
330    ) -> Result<ContractClass, ProviderError>
331    where
332        B: AsRef<BlockId> + Send + Sync,
333        A: AsRef<Felt> + Send + Sync,
334    {
335        match self {
336            Self::JsonRpcHttp(inner) => {
337                <JsonRpcClient<HttpTransport> as Provider>::get_class_at(
338                    inner,
339                    block_id,
340                    contract_address,
341                )
342                .await
343            }
344            Self::SequencerGateway(inner) => {
345                <SequencerGatewayProvider as Provider>::get_class_at(
346                    inner,
347                    block_id,
348                    contract_address,
349                )
350                .await
351            }
352        }
353    }
354
355    async fn get_block_transaction_count<B>(&self, block_id: B) -> Result<u64, ProviderError>
356    where
357        B: AsRef<BlockId> + Send + Sync,
358    {
359        match self {
360            Self::JsonRpcHttp(inner) => {
361                <JsonRpcClient<HttpTransport> as Provider>::get_block_transaction_count(
362                    inner, block_id,
363                )
364                .await
365            }
366            Self::SequencerGateway(inner) => {
367                <SequencerGatewayProvider as Provider>::get_block_transaction_count(inner, block_id)
368                    .await
369            }
370        }
371    }
372
373    async fn call<R, B>(&self, request: R, block_id: B) -> Result<Vec<Felt>, ProviderError>
374    where
375        R: AsRef<FunctionCall> + Send + Sync,
376        B: AsRef<BlockId> + Send + Sync,
377    {
378        match self {
379            Self::JsonRpcHttp(inner) => {
380                <JsonRpcClient<HttpTransport> as Provider>::call(inner, request, block_id).await
381            }
382            Self::SequencerGateway(inner) => {
383                <SequencerGatewayProvider as Provider>::call(inner, request, block_id).await
384            }
385        }
386    }
387
388    async fn estimate_fee<R, S, B>(
389        &self,
390        request: R,
391        simulation_flags: S,
392        block_id: B,
393    ) -> Result<Vec<FeeEstimate>, ProviderError>
394    where
395        R: AsRef<[BroadcastedTransaction]> + Send + Sync,
396        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
397        B: AsRef<BlockId> + Send + Sync,
398    {
399        match self {
400            Self::JsonRpcHttp(inner) => {
401                <JsonRpcClient<HttpTransport> as Provider>::estimate_fee(
402                    inner,
403                    request,
404                    simulation_flags,
405                    block_id,
406                )
407                .await
408            }
409            Self::SequencerGateway(inner) => {
410                <SequencerGatewayProvider as Provider>::estimate_fee(
411                    inner,
412                    request,
413                    simulation_flags,
414                    block_id,
415                )
416                .await
417            }
418        }
419    }
420
421    async fn estimate_message_fee<M, B>(
422        &self,
423        message: M,
424        block_id: B,
425    ) -> Result<MessageFeeEstimate, ProviderError>
426    where
427        M: AsRef<MsgFromL1> + Send + Sync,
428        B: AsRef<BlockId> + Send + Sync,
429    {
430        match self {
431            Self::JsonRpcHttp(inner) => {
432                <JsonRpcClient<HttpTransport> as Provider>::estimate_message_fee(
433                    inner, message, block_id,
434                )
435                .await
436            }
437            Self::SequencerGateway(inner) => {
438                <SequencerGatewayProvider as Provider>::estimate_message_fee(
439                    inner, message, block_id,
440                )
441                .await
442            }
443        }
444    }
445
446    async fn block_number(&self) -> Result<u64, ProviderError> {
447        match self {
448            Self::JsonRpcHttp(inner) => {
449                <JsonRpcClient<HttpTransport> as Provider>::block_number(inner).await
450            }
451            Self::SequencerGateway(inner) => {
452                <SequencerGatewayProvider as Provider>::block_number(inner).await
453            }
454        }
455    }
456
457    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError> {
458        match self {
459            Self::JsonRpcHttp(inner) => {
460                <JsonRpcClient<HttpTransport> as Provider>::block_hash_and_number(inner).await
461            }
462            Self::SequencerGateway(inner) => {
463                <SequencerGatewayProvider as Provider>::block_hash_and_number(inner).await
464            }
465        }
466    }
467
468    async fn chain_id(&self) -> Result<Felt, ProviderError> {
469        match self {
470            Self::JsonRpcHttp(inner) => {
471                <JsonRpcClient<HttpTransport> as Provider>::chain_id(inner).await
472            }
473            Self::SequencerGateway(inner) => {
474                <SequencerGatewayProvider as Provider>::chain_id(inner).await
475            }
476        }
477    }
478
479    async fn syncing(&self) -> Result<SyncStatusType, ProviderError> {
480        match self {
481            Self::JsonRpcHttp(inner) => {
482                <JsonRpcClient<HttpTransport> as Provider>::syncing(inner).await
483            }
484            Self::SequencerGateway(inner) => {
485                <SequencerGatewayProvider as Provider>::syncing(inner).await
486            }
487        }
488    }
489
490    async fn get_events(
491        &self,
492        filter: EventFilter,
493        continuation_token: Option<String>,
494        chunk_size: u64,
495    ) -> Result<EventsPage, ProviderError> {
496        match self {
497            Self::JsonRpcHttp(inner) => {
498                <JsonRpcClient<HttpTransport> as Provider>::get_events(
499                    inner,
500                    filter,
501                    continuation_token,
502                    chunk_size,
503                )
504                .await
505            }
506            Self::SequencerGateway(inner) => {
507                <SequencerGatewayProvider as Provider>::get_events(
508                    inner,
509                    filter,
510                    continuation_token,
511                    chunk_size,
512                )
513                .await
514            }
515        }
516    }
517
518    async fn get_nonce<B, A>(&self, block_id: B, contract_address: A) -> Result<Felt, ProviderError>
519    where
520        B: AsRef<BlockId> + Send + Sync,
521        A: AsRef<Felt> + Send + Sync,
522    {
523        match self {
524            Self::JsonRpcHttp(inner) => {
525                <JsonRpcClient<HttpTransport> as Provider>::get_nonce(
526                    inner,
527                    block_id,
528                    contract_address,
529                )
530                .await
531            }
532            Self::SequencerGateway(inner) => {
533                <SequencerGatewayProvider as Provider>::get_nonce(inner, block_id, contract_address)
534                    .await
535            }
536        }
537    }
538
539    async fn get_storage_proof<B, H, A, K>(
540        &self,
541        block_id: B,
542        class_hashes: H,
543        contract_addresses: A,
544        contracts_storage_keys: K,
545    ) -> Result<StorageProof, ProviderError>
546    where
547        B: AsRef<ConfirmedBlockId> + Send + Sync,
548        H: AsRef<[Felt]> + Send + Sync,
549        A: AsRef<[Felt]> + Send + Sync,
550        K: AsRef<[ContractStorageKeys]> + Send + Sync,
551    {
552        match self {
553            Self::JsonRpcHttp(inner) => {
554                <JsonRpcClient<HttpTransport> as Provider>::get_storage_proof(
555                    inner,
556                    block_id,
557                    class_hashes,
558                    contract_addresses,
559                    contracts_storage_keys,
560                )
561                .await
562            }
563            Self::SequencerGateway(inner) => {
564                <SequencerGatewayProvider as Provider>::get_storage_proof(
565                    inner,
566                    block_id,
567                    class_hashes,
568                    contract_addresses,
569                    contracts_storage_keys,
570                )
571                .await
572            }
573        }
574    }
575
576    async fn add_invoke_transaction<I>(
577        &self,
578        invoke_transaction: I,
579    ) -> Result<InvokeTransactionResult, ProviderError>
580    where
581        I: AsRef<BroadcastedInvokeTransaction> + Send + Sync,
582    {
583        match self {
584            Self::JsonRpcHttp(inner) => {
585                <JsonRpcClient<HttpTransport> as Provider>::add_invoke_transaction(
586                    inner,
587                    invoke_transaction,
588                )
589                .await
590            }
591            Self::SequencerGateway(inner) => {
592                <SequencerGatewayProvider as Provider>::add_invoke_transaction(
593                    inner,
594                    invoke_transaction,
595                )
596                .await
597            }
598        }
599    }
600
601    async fn add_declare_transaction<D>(
602        &self,
603        declare_transaction: D,
604    ) -> Result<DeclareTransactionResult, ProviderError>
605    where
606        D: AsRef<BroadcastedDeclareTransaction> + Send + Sync,
607    {
608        match self {
609            Self::JsonRpcHttp(inner) => {
610                <JsonRpcClient<HttpTransport> as Provider>::add_declare_transaction(
611                    inner,
612                    declare_transaction,
613                )
614                .await
615            }
616            Self::SequencerGateway(inner) => {
617                <SequencerGatewayProvider as Provider>::add_declare_transaction(
618                    inner,
619                    declare_transaction,
620                )
621                .await
622            }
623        }
624    }
625
626    async fn add_deploy_account_transaction<D>(
627        &self,
628        deploy_account_transaction: D,
629    ) -> Result<DeployAccountTransactionResult, ProviderError>
630    where
631        D: AsRef<BroadcastedDeployAccountTransaction> + Send + Sync,
632    {
633        match self {
634            Self::JsonRpcHttp(inner) => {
635                <JsonRpcClient<HttpTransport> as Provider>::add_deploy_account_transaction(
636                    inner,
637                    deploy_account_transaction,
638                )
639                .await
640            }
641            Self::SequencerGateway(inner) => {
642                <SequencerGatewayProvider as Provider>::add_deploy_account_transaction(
643                    inner,
644                    deploy_account_transaction,
645                )
646                .await
647            }
648        }
649    }
650
651    async fn trace_transaction<H>(
652        &self,
653        transaction_hash: H,
654    ) -> Result<TransactionTrace, ProviderError>
655    where
656        H: AsRef<Felt> + Send + Sync,
657    {
658        match self {
659            Self::JsonRpcHttp(inner) => {
660                <JsonRpcClient<HttpTransport> as Provider>::trace_transaction(
661                    inner,
662                    transaction_hash,
663                )
664                .await
665            }
666            Self::SequencerGateway(inner) => {
667                <SequencerGatewayProvider as Provider>::trace_transaction(inner, transaction_hash)
668                    .await
669            }
670        }
671    }
672
673    async fn simulate_transactions<B, T, S>(
674        &self,
675        block_id: B,
676        transactions: T,
677        simulation_flags: S,
678    ) -> Result<Vec<SimulatedTransaction>, ProviderError>
679    where
680        B: AsRef<BlockId> + Send + Sync,
681        T: AsRef<[BroadcastedTransaction]> + Send + Sync,
682        S: AsRef<[SimulationFlag]> + Send + Sync,
683    {
684        match self {
685            Self::JsonRpcHttp(inner) => {
686                <JsonRpcClient<HttpTransport> as Provider>::simulate_transactions(
687                    inner,
688                    block_id,
689                    transactions,
690                    simulation_flags,
691                )
692                .await
693            }
694            Self::SequencerGateway(inner) => {
695                <SequencerGatewayProvider as Provider>::simulate_transactions(
696                    inner,
697                    block_id,
698                    transactions,
699                    simulation_flags,
700                )
701                .await
702            }
703        }
704    }
705
706    async fn trace_block_transactions<B>(
707        &self,
708        block_id: B,
709    ) -> Result<Vec<TransactionTraceWithHash>, ProviderError>
710    where
711        B: AsRef<ConfirmedBlockId> + Send + Sync,
712    {
713        match self {
714            Self::JsonRpcHttp(inner) => {
715                <JsonRpcClient<HttpTransport> as Provider>::trace_block_transactions(
716                    inner, block_id,
717                )
718                .await
719            }
720            Self::SequencerGateway(inner) => {
721                <SequencerGatewayProvider as Provider>::trace_block_transactions(inner, block_id)
722                    .await
723            }
724        }
725    }
726
727    async fn batch_requests<R>(
728        &self,
729        requests: R,
730    ) -> Result<Vec<ProviderResponseData>, ProviderError>
731    where
732        R: AsRef<[ProviderRequestData]> + Send + Sync,
733    {
734        match self {
735            Self::JsonRpcHttp(inner) => {
736                <JsonRpcClient<HttpTransport> as Provider>::batch_requests(inner, requests).await
737            }
738            Self::SequencerGateway(inner) => {
739                <SequencerGatewayProvider as Provider>::batch_requests(inner, requests).await
740            }
741        }
742    }
743}