starknet_providers/sequencer/
provider.rs

1#![allow(deprecated)]
2
3use std::any::Any;
4
5use async_trait::async_trait;
6use starknet_core::types::{
7    BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction,
8    BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction,
9    ConfirmedBlockId, ContractClass, ContractStorageKeys, DeclareTransactionResult,
10    DeployAccountTransactionResult, EventFilter, EventsPage, FeeEstimate, Felt, FunctionCall,
11    Hash256, InvokeTransactionResult, MaybePreConfirmedBlockWithReceipts,
12    MaybePreConfirmedBlockWithTxHashes, MaybePreConfirmedBlockWithTxs,
13    MaybePreConfirmedStateUpdate, MessageFeeEstimate, MessageStatus, MsgFromL1,
14    SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, StarknetError,
15    StorageProof, SyncStatusType, Transaction, TransactionReceiptWithBlockInfo, TransactionStatus,
16    TransactionTrace, TransactionTraceWithHash,
17};
18
19use crate::{
20    provider::ProviderImplError,
21    sequencer::{models::conversions::ConversionError, GatewayClientError},
22    Provider, ProviderError, ProviderRequestData, ProviderResponseData, SequencerGatewayProvider,
23};
24
25use super::models::TransactionFinalityStatus;
26
27#[allow(unused)]
28#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
29#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
30impl Provider for SequencerGatewayProvider {
31    async fn spec_version(&self) -> Result<String, ProviderError> {
32        Ok(String::from("0.8.1"))
33    }
34
35    async fn get_block_with_tx_hashes<B>(
36        &self,
37        block_id: B,
38    ) -> Result<MaybePreConfirmedBlockWithTxHashes, ProviderError>
39    where
40        B: AsRef<BlockId> + Send + Sync,
41    {
42        Ok(self
43            .get_block(block_id.as_ref().to_owned().try_into()?)
44            .await?
45            .try_into()?)
46    }
47
48    async fn get_block_with_txs<B>(
49        &self,
50        block_id: B,
51    ) -> Result<MaybePreConfirmedBlockWithTxs, ProviderError>
52    where
53        B: AsRef<BlockId> + Send + Sync,
54    {
55        Ok(self
56            .get_block(block_id.as_ref().to_owned().try_into()?)
57            .await?
58            .try_into()?)
59    }
60
61    async fn get_block_with_receipts<B>(
62        &self,
63        block_id: B,
64    ) -> Result<MaybePreConfirmedBlockWithReceipts, ProviderError>
65    where
66        B: AsRef<BlockId> + Send + Sync,
67    {
68        Ok(self
69            .get_block(block_id.as_ref().to_owned().try_into()?)
70            .await?
71            .try_into()?)
72    }
73
74    async fn get_state_update<B>(
75        &self,
76        block_id: B,
77    ) -> Result<MaybePreConfirmedStateUpdate, ProviderError>
78    where
79        B: AsRef<BlockId> + Send + Sync,
80    {
81        Ok(self
82            .get_state_update(block_id.as_ref().to_owned().try_into()?)
83            .await?
84            .try_into()?)
85    }
86
87    async fn get_storage_at<A, K, B>(
88        &self,
89        contract_address: A,
90        key: K,
91        block_id: B,
92    ) -> Result<Felt, ProviderError>
93    where
94        A: AsRef<Felt> + Send + Sync,
95        K: AsRef<Felt> + Send + Sync,
96        B: AsRef<BlockId> + Send + Sync,
97    {
98        // Deprecated since Starknet v0.12.3
99        Err(ProviderError::Other(Box::new(
100            GatewayClientError::MethodNotSupported,
101        )))
102    }
103
104    /// Given an l1 tx hash, returns the associated `l1_handler` tx hashes and statuses for all L1 ->
105    /// L2 messages sent by the l1 transaction, ordered by the l1 tx sending order
106    async fn get_messages_status(
107        &self,
108        transaction_hash: Hash256,
109    ) -> Result<Vec<MessageStatus>, ProviderError> {
110        Err(ProviderError::Other(Box::new(
111            GatewayClientError::MethodNotSupported,
112        )))
113    }
114
115    /// Gets the transaction status (possibly reflecting that the tx is still in
116    /// the mempool, or dropped from it)
117    async fn get_transaction_status<H>(
118        &self,
119        transaction_hash: H,
120    ) -> Result<TransactionStatus, ProviderError>
121    where
122        H: AsRef<Felt> + Send + Sync,
123    {
124        let status = self
125            .get_transaction_status(*transaction_hash.as_ref())
126            .await?;
127
128        // `NotReceived` is not a valid status for JSON-RPC. It's an error.
129        if matches!(
130            &status.finality_status,
131            Some(TransactionFinalityStatus::NotReceived)
132        ) {
133            return Err(ProviderError::StarknetError(
134                StarknetError::TransactionHashNotFound,
135            ));
136        }
137
138        Ok(status.try_into()?)
139    }
140
141    async fn get_transaction_by_hash<H>(
142        &self,
143        transaction_hash: H,
144    ) -> Result<Transaction, ProviderError>
145    where
146        H: AsRef<Felt> + Send + Sync,
147    {
148        Ok(self
149            .get_transaction(*transaction_hash.as_ref())
150            .await?
151            .try_into()?)
152    }
153
154    async fn get_transaction_by_block_id_and_index<B>(
155        &self,
156        block_id: B,
157        index: u64,
158    ) -> Result<Transaction, ProviderError>
159    where
160        B: AsRef<BlockId> + Send + Sync,
161    {
162        let mut block = self
163            .get_block(block_id.as_ref().to_owned().try_into()?)
164            .await?;
165
166        let index = index as usize;
167        if index < block.transactions.len() {
168            Ok(block.transactions.remove(index).try_into()?)
169        } else {
170            Err(ProviderError::StarknetError(
171                StarknetError::InvalidTransactionIndex,
172            ))
173        }
174    }
175
176    async fn get_transaction_receipt<H>(
177        &self,
178        transaction_hash: H,
179    ) -> Result<TransactionReceiptWithBlockInfo, ProviderError>
180    where
181        H: AsRef<Felt> + Send + Sync,
182    {
183        // Deprecated since Starknet v0.12.3
184        Err(ProviderError::Other(Box::new(
185            GatewayClientError::MethodNotSupported,
186        )))
187    }
188
189    async fn get_class<B, H>(
190        &self,
191        block_id: B,
192        class_hash: H,
193    ) -> Result<ContractClass, ProviderError>
194    where
195        B: AsRef<BlockId> + Send + Sync,
196        H: AsRef<Felt> + Send + Sync,
197    {
198        Ok(self
199            .get_class_by_hash(
200                *class_hash.as_ref(),
201                block_id.as_ref().to_owned().try_into()?,
202            )
203            .await?
204            .try_into()?)
205    }
206
207    async fn get_class_hash_at<B, A>(
208        &self,
209        block_id: B,
210        contract_address: A,
211    ) -> Result<Felt, ProviderError>
212    where
213        B: AsRef<BlockId> + Send + Sync,
214        A: AsRef<Felt> + Send + Sync,
215    {
216        // Deprecated since Starknet v0.12.3
217        Err(ProviderError::Other(Box::new(
218            GatewayClientError::MethodNotSupported,
219        )))
220    }
221
222    async fn get_class_at<B, A>(
223        &self,
224        block_id: B,
225        contract_address: A,
226    ) -> Result<ContractClass, ProviderError>
227    where
228        B: AsRef<BlockId> + Send + Sync,
229        A: AsRef<Felt> + Send + Sync,
230    {
231        // Deprecated since Starknet v0.12.3
232        Err(ProviderError::Other(Box::new(
233            GatewayClientError::MethodNotSupported,
234        )))
235    }
236
237    async fn get_block_transaction_count<B>(&self, block_id: B) -> Result<u64, ProviderError>
238    where
239        B: AsRef<BlockId> + Send + Sync,
240    {
241        let block = self
242            .get_block(block_id.as_ref().to_owned().try_into()?)
243            .await?;
244        Ok(block.transactions.len() as u64)
245    }
246
247    async fn call<R, B>(&self, request: R, block_id: B) -> Result<Vec<Felt>, ProviderError>
248    where
249        R: AsRef<FunctionCall> + Send + Sync,
250        B: AsRef<BlockId> + Send + Sync,
251    {
252        // Deprecated since Starknet v0.12.3
253        Err(ProviderError::Other(Box::new(
254            GatewayClientError::MethodNotSupported,
255        )))
256    }
257
258    async fn estimate_fee<R, S, B>(
259        &self,
260        request: R,
261        simulation_flags: S,
262        block_id: B,
263    ) -> Result<Vec<FeeEstimate>, ProviderError>
264    where
265        R: AsRef<[BroadcastedTransaction]> + Send + Sync,
266        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
267        B: AsRef<BlockId> + Send + Sync,
268    {
269        // Deprecated since Starknet v0.12.3
270        Err(ProviderError::Other(Box::new(
271            GatewayClientError::MethodNotSupported,
272        )))
273    }
274
275    async fn estimate_message_fee<M, B>(
276        &self,
277        message: M,
278        block_id: B,
279    ) -> Result<MessageFeeEstimate, ProviderError>
280    where
281        M: AsRef<MsgFromL1> + Send + Sync,
282        B: AsRef<BlockId> + Send + Sync,
283    {
284        // Deprecated since Starknet v0.12.3
285        Err(ProviderError::Other(Box::new(
286            GatewayClientError::MethodNotSupported,
287        )))
288    }
289
290    async fn block_number(&self) -> Result<u64, ProviderError> {
291        let block = self.get_block(super::models::BlockId::Latest).await?;
292        Ok(block.block_number.ok_or(ConversionError)?)
293    }
294
295    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError> {
296        let block = self.get_block(super::models::BlockId::Latest).await?;
297        Ok(BlockHashAndNumber {
298            block_hash: block.block_hash.ok_or(ConversionError)?,
299            block_number: block.block_number.ok_or(ConversionError)?,
300        })
301    }
302
303    async fn chain_id(&self) -> Result<Felt, ProviderError> {
304        Ok(self.chain_id)
305    }
306
307    async fn syncing(&self) -> Result<SyncStatusType, ProviderError> {
308        Ok(SyncStatusType::NotSyncing)
309    }
310
311    async fn get_events(
312        &self,
313        filter: EventFilter,
314        continuation_token: Option<String>,
315        chunk_size: u64,
316    ) -> Result<EventsPage, ProviderError> {
317        Err(ProviderError::Other(Box::new(
318            GatewayClientError::MethodNotSupported,
319        )))
320    }
321
322    async fn get_nonce<B, A>(&self, block_id: B, contract_address: A) -> Result<Felt, ProviderError>
323    where
324        B: AsRef<BlockId> + Send + Sync,
325        A: AsRef<Felt> + Send + Sync,
326    {
327        // Deprecated since Starknet v0.12.3
328        Err(ProviderError::Other(Box::new(
329            GatewayClientError::MethodNotSupported,
330        )))
331    }
332
333    async fn get_storage_proof<B, H, A, K>(
334        &self,
335        block_id: B,
336        class_hashes: H,
337        contract_addresses: A,
338        contracts_storage_keys: K,
339    ) -> Result<StorageProof, ProviderError>
340    where
341        B: AsRef<ConfirmedBlockId> + Send + Sync,
342        H: AsRef<[Felt]> + Send + Sync,
343        A: AsRef<[Felt]> + Send + Sync,
344        K: AsRef<[ContractStorageKeys]> + Send + Sync,
345    {
346        Err(ProviderError::Other(Box::new(
347            GatewayClientError::MethodNotSupported,
348        )))
349    }
350
351    async fn add_invoke_transaction<I>(
352        &self,
353        invoke_transaction: I,
354    ) -> Result<InvokeTransactionResult, ProviderError>
355    where
356        I: AsRef<BroadcastedInvokeTransaction> + Send + Sync,
357    {
358        let result = self
359            .add_transaction(super::models::TransactionRequest::InvokeFunction(
360                invoke_transaction.as_ref().to_owned().into(),
361            ))
362            .await?;
363
364        Ok(InvokeTransactionResult {
365            transaction_hash: result.transaction_hash,
366        })
367    }
368
369    async fn add_declare_transaction<D>(
370        &self,
371        declare_transaction: D,
372    ) -> Result<DeclareTransactionResult, ProviderError>
373    where
374        D: AsRef<BroadcastedDeclareTransaction> + Send + Sync,
375    {
376        let result = self
377            .add_transaction(super::models::TransactionRequest::Declare(
378                declare_transaction.as_ref().to_owned().try_into()?,
379            ))
380            .await?;
381
382        Ok(DeclareTransactionResult {
383            transaction_hash: result.transaction_hash,
384            class_hash: result.class_hash.ok_or(ConversionError)?,
385        })
386    }
387
388    async fn add_deploy_account_transaction<D>(
389        &self,
390        deploy_account_transaction: D,
391    ) -> Result<DeployAccountTransactionResult, ProviderError>
392    where
393        D: AsRef<BroadcastedDeployAccountTransaction> + Send + Sync,
394    {
395        let result = self
396            .add_transaction(super::models::TransactionRequest::DeployAccount(
397                deploy_account_transaction.as_ref().to_owned().into(),
398            ))
399            .await?;
400
401        Ok(DeployAccountTransactionResult {
402            transaction_hash: result.transaction_hash,
403            contract_address: result.address.ok_or(ConversionError)?,
404        })
405    }
406
407    async fn trace_transaction<H>(
408        &self,
409        _transaction_hash: H,
410    ) -> Result<TransactionTrace, ProviderError>
411    where
412        H: AsRef<Felt> + Send + Sync,
413    {
414        // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here.
415        //
416        // This is fine as the feeder gateway is soon to be removed anyways.
417        Err(ProviderError::Other(Box::new(
418            GatewayClientError::MethodNotSupported,
419        )))
420    }
421
422    async fn simulate_transactions<B, T, S>(
423        &self,
424        block_id: B,
425        transactions: T,
426        simulation_flags: S,
427    ) -> Result<Vec<SimulatedTransaction>, ProviderError>
428    where
429        B: AsRef<BlockId> + Send + Sync,
430        T: AsRef<[BroadcastedTransaction]> + Send + Sync,
431        S: AsRef<[SimulationFlag]> + Send + Sync,
432    {
433        // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here.
434        //
435        // This is fine as the feeder gateway is soon to be removed anyways.
436        Err(ProviderError::Other(Box::new(
437            GatewayClientError::MethodNotSupported,
438        )))
439    }
440
441    async fn trace_block_transactions<B>(
442        &self,
443        block_id: B,
444    ) -> Result<Vec<TransactionTraceWithHash>, ProviderError>
445    where
446        B: AsRef<ConfirmedBlockId> + Send + Sync,
447    {
448        // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here.
449        //
450        // This is fine as the feeder gateway is soon to be removed anyways.
451        Err(ProviderError::Other(Box::new(
452            GatewayClientError::MethodNotSupported,
453        )))
454    }
455
456    async fn batch_requests<R>(
457        &self,
458        requests: R,
459    ) -> Result<Vec<ProviderResponseData>, ProviderError>
460    where
461        R: AsRef<[ProviderRequestData]> + Send + Sync,
462    {
463        // Not implemented for now. It's technically possible to simulate this by running multiple
464        // requests in parallel.
465        Err(ProviderError::Other(Box::new(
466            GatewayClientError::MethodNotSupported,
467        )))
468    }
469}
470
471impl ProviderImplError for GatewayClientError {
472    fn as_any(&self) -> &dyn Any {
473        self
474    }
475}
476
477impl From<GatewayClientError> for ProviderError {
478    fn from(value: GatewayClientError) -> Self {
479        Self::Other(Box::new(value))
480    }
481}