starknet_rust_providers/
any.rs

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