starknet_rust_providers/sequencer/
provider.rs

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