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