starknet_providers/
provider.rs

1use async_trait::async_trait;
2use auto_impl::auto_impl;
3use serde::Serialize;
4use starknet_core::types::{
5    requests::*, BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction,
6    BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction,
7    ConfirmedBlockId, ContractClass, ContractStorageKeys, DeclareTransactionResult,
8    DeployAccountTransactionResult, EventFilter, EventsPage, FeeEstimate, Felt, FunctionCall,
9    Hash256, InvokeTransactionResult, MaybePreConfirmedBlockWithReceipts,
10    MaybePreConfirmedBlockWithTxHashes, MaybePreConfirmedBlockWithTxs,
11    MaybePreConfirmedStateUpdate, MessageFeeEstimate, MessageStatus, MsgFromL1,
12    SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, StarknetError,
13    StorageProof, SubscriptionId, SyncStatusType, Transaction, TransactionReceiptWithBlockInfo,
14    TransactionStatus, TransactionTrace, TransactionTraceWithHash,
15};
16use std::{any::Any, error::Error, fmt::Debug};
17
18/// A generic interface for any type allowing communication with a Starknet network.
19///
20/// Historically, the only official way to access the network is through the sequencer gateway,
21/// implemented by [`SequencerGatewayProvider`](crate::sequencer::SequencerGatewayProvider), which
22/// has since been deprecated. Currently, the recommended way of accessing the network is via the
23/// JSON-RPC specification, implemented with [`JsonRpcClient`](crate::jsonrpc::JsonRpcClient).
24///
25/// The legacy [`SequencerGatewayProvider`](crate::sequencer::SequencerGatewayProvider) still
26/// implements this trait for backward compatibility reasons, but most of its methods no longer work
27/// in practice, as public sequencer servers have generally block access to most methods.
28#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
29#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
30#[auto_impl(&, Box, Arc)]
31pub trait Provider {
32    /// Returns the version of the Starknet JSON-RPC specification being used.
33    async fn spec_version(&self) -> Result<String, ProviderError>;
34
35    /// Gets block information with transaction hashes given the block id.
36    async fn get_block_with_tx_hashes<B>(
37        &self,
38        block_id: B,
39    ) -> Result<MaybePreConfirmedBlockWithTxHashes, ProviderError>
40    where
41        B: AsRef<BlockId> + Send + Sync;
42
43    /// Gets block information with full transactions given the block id.
44    async fn get_block_with_txs<B>(
45        &self,
46        block_id: B,
47    ) -> Result<MaybePreConfirmedBlockWithTxs, ProviderError>
48    where
49        B: AsRef<BlockId> + Send + Sync;
50
51    /// Gets block information with full transactions and receipts given the block id.
52    async fn get_block_with_receipts<B>(
53        &self,
54        block_id: B,
55    ) -> Result<MaybePreConfirmedBlockWithReceipts, ProviderError>
56    where
57        B: AsRef<BlockId> + Send + Sync;
58
59    /// Gets the information about the result of executing the requested block.
60    async fn get_state_update<B>(
61        &self,
62        block_id: B,
63    ) -> Result<MaybePreConfirmedStateUpdate, ProviderError>
64    where
65        B: AsRef<BlockId> + Send + Sync;
66
67    /// Gets the value of the storage at the given address and key.
68    async fn get_storage_at<A, K, B>(
69        &self,
70        contract_address: A,
71        key: K,
72        block_id: B,
73    ) -> Result<Felt, ProviderError>
74    where
75        A: AsRef<Felt> + Send + Sync,
76        K: AsRef<Felt> + Send + Sync,
77        B: AsRef<BlockId> + Send + Sync;
78
79    /// Given an l1 tx hash, returns the associated `l1_handler` tx hashes and statuses for all L1 ->
80    /// L2 messages sent by the l1 transaction, ordered by the l1 tx sending order
81    async fn get_messages_status(
82        &self,
83        transaction_hash: Hash256,
84    ) -> Result<Vec<MessageStatus>, ProviderError>;
85
86    /// Gets the transaction status (possibly reflecting that the tx is still in the mempool, or
87    /// dropped from it).
88    async fn get_transaction_status<H>(
89        &self,
90        transaction_hash: H,
91    ) -> Result<TransactionStatus, ProviderError>
92    where
93        H: AsRef<Felt> + Send + Sync;
94
95    /// Gets the details and status of a submitted transaction.
96    async fn get_transaction_by_hash<H>(
97        &self,
98        transaction_hash: H,
99    ) -> Result<Transaction, ProviderError>
100    where
101        H: AsRef<Felt> + Send + Sync;
102
103    /// Gets the details of a transaction by a given block id and index.
104    async fn get_transaction_by_block_id_and_index<B>(
105        &self,
106        block_id: B,
107        index: u64,
108    ) -> Result<Transaction, ProviderError>
109    where
110        B: AsRef<BlockId> + Send + Sync;
111
112    /// Gets the details of a transaction by a given block number and index.
113    async fn get_transaction_receipt<H>(
114        &self,
115        transaction_hash: H,
116    ) -> Result<TransactionReceiptWithBlockInfo, ProviderError>
117    where
118        H: AsRef<Felt> + Send + Sync;
119
120    /// Gets the contract class definition in the given block associated with the given hash.
121    async fn get_class<B, H>(
122        &self,
123        block_id: B,
124        class_hash: H,
125    ) -> Result<ContractClass, ProviderError>
126    where
127        B: AsRef<BlockId> + Send + Sync,
128        H: AsRef<Felt> + Send + Sync;
129
130    /// Gets the contract class hash in the given block for the contract deployed at the given
131    /// address.
132    async fn get_class_hash_at<B, A>(
133        &self,
134        block_id: B,
135        contract_address: A,
136    ) -> Result<Felt, ProviderError>
137    where
138        B: AsRef<BlockId> + Send + Sync,
139        A: AsRef<Felt> + Send + Sync;
140
141    /// Gets the contract class definition in the given block at the given address.
142    async fn get_class_at<B, A>(
143        &self,
144        block_id: B,
145        contract_address: A,
146    ) -> Result<ContractClass, ProviderError>
147    where
148        B: AsRef<BlockId> + Send + Sync,
149        A: AsRef<Felt> + Send + Sync;
150
151    /// Gets the number of transactions in a block given a block id.
152    async fn get_block_transaction_count<B>(&self, block_id: B) -> Result<u64, ProviderError>
153    where
154        B: AsRef<BlockId> + Send + Sync;
155
156    /// Calls a starknet function without creating a Starknet transaction.
157    async fn call<R, B>(&self, request: R, block_id: B) -> Result<Vec<Felt>, ProviderError>
158    where
159        R: AsRef<FunctionCall> + Send + Sync,
160        B: AsRef<BlockId> + Send + Sync;
161
162    /// Estimates the fee for a given Starknet transaction.
163    async fn estimate_fee<R, S, B>(
164        &self,
165        request: R,
166        simulation_flags: S,
167        block_id: B,
168    ) -> Result<Vec<FeeEstimate>, ProviderError>
169    where
170        R: AsRef<[BroadcastedTransaction]> + Send + Sync,
171        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
172        B: AsRef<BlockId> + Send + Sync;
173
174    /// Estimates the fee for sending an L1-to-L2 message.
175    async fn estimate_message_fee<M, B>(
176        &self,
177        message: M,
178        block_id: B,
179    ) -> Result<MessageFeeEstimate, ProviderError>
180    where
181        M: AsRef<MsgFromL1> + Send + Sync,
182        B: AsRef<BlockId> + Send + Sync;
183
184    /// Gets the most recent accepted block number.
185    async fn block_number(&self) -> Result<u64, ProviderError>;
186
187    /// Gets the most recent accepted block hash and number.
188    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError>;
189
190    /// Returns the currently configured Starknet chain id.
191    async fn chain_id(&self) -> Result<Felt, ProviderError>;
192
193    /// Returns an object about the sync status, or false if the node is not synching.
194    async fn syncing(&self) -> Result<SyncStatusType, ProviderError>;
195
196    /// Returns all events matching the given filter.
197    async fn get_events(
198        &self,
199        filter: EventFilter,
200        continuation_token: Option<String>,
201        chunk_size: u64,
202    ) -> Result<EventsPage, ProviderError>;
203
204    /// Gets the nonce associated with the given address in the given block.
205    async fn get_nonce<B, A>(
206        &self,
207        block_id: B,
208        contract_address: A,
209    ) -> Result<Felt, ProviderError>
210    where
211        B: AsRef<BlockId> + Send + Sync,
212        A: AsRef<Felt> + Send + Sync;
213
214    /// Get merkle paths in one of the state tries: global state, classes, individual contract.
215    /// A single request can query for any mix of the three types of storage proofs (classes,
216    /// contracts, and storage).
217    async fn get_storage_proof<B, H, A, K>(
218        &self,
219        block_id: B,
220        class_hashes: H,
221        contract_addresses: A,
222        contracts_storage_keys: K,
223    ) -> Result<StorageProof, ProviderError>
224    where
225        B: AsRef<ConfirmedBlockId> + Send + Sync,
226        H: AsRef<[Felt]> + Send + Sync,
227        A: AsRef<[Felt]> + Send + Sync,
228        K: AsRef<[ContractStorageKeys]> + Send + Sync;
229
230    /// Submits a new transaction to be added to the chain.
231    async fn add_invoke_transaction<I>(
232        &self,
233        invoke_transaction: I,
234    ) -> Result<InvokeTransactionResult, ProviderError>
235    where
236        I: AsRef<BroadcastedInvokeTransaction> + Send + Sync;
237
238    /// Submits a new transaction to be added to the chain.
239    async fn add_declare_transaction<D>(
240        &self,
241        declare_transaction: D,
242    ) -> Result<DeclareTransactionResult, ProviderError>
243    where
244        D: AsRef<BroadcastedDeclareTransaction> + Send + Sync;
245
246    /// Submits a new deploy account transaction.
247    async fn add_deploy_account_transaction<D>(
248        &self,
249        deploy_account_transaction: D,
250    ) -> Result<DeployAccountTransactionResult, ProviderError>
251    where
252        D: AsRef<BroadcastedDeployAccountTransaction> + Send + Sync;
253
254    /// For a given executed transaction, returns the trace of its execution, including internal
255    /// calls.
256    async fn trace_transaction<H>(
257        &self,
258        transaction_hash: H,
259    ) -> Result<TransactionTrace, ProviderError>
260    where
261        H: AsRef<Felt> + Send + Sync;
262
263    /// Simulates a given sequence of transactions on the requested state, and generate the
264    /// execution traces. Note that some of the transactions may revert, in which case no error is
265    /// thrown, but revert details can be seen on the returned trace object.
266    ///
267    /// Note that some of the transactions may revert, this will be reflected by the `revert_error`
268    /// property in the trace. Other types of failures (e.g. unexpected error or failure in the
269    /// validation phase) will result in `TRANSACTION_EXECUTION_ERROR`.
270    async fn simulate_transactions<B, T, S>(
271        &self,
272        block_id: B,
273        transactions: T,
274        simulation_flags: S,
275    ) -> Result<Vec<SimulatedTransaction>, ProviderError>
276    where
277        B: AsRef<BlockId> + Send + Sync,
278        T: AsRef<[BroadcastedTransaction]> + Send + Sync,
279        S: AsRef<[SimulationFlag]> + Send + Sync;
280
281    /// Retrieves traces for all transactions in the given block.
282    async fn trace_block_transactions<B>(
283        &self,
284        block_id: B,
285    ) -> Result<Vec<TransactionTraceWithHash>, ProviderError>
286    where
287        B: AsRef<ConfirmedBlockId> + Send + Sync;
288
289    /// Sends multiple requests in parallel. The function call fails if any of the requests fails.
290    /// Implementations must guarantee that responses follow the exact order as the requests.
291    async fn batch_requests<R>(
292        &self,
293        requests: R,
294    ) -> Result<Vec<ProviderResponseData>, ProviderError>
295    where
296        R: AsRef<[ProviderRequestData]> + Send + Sync;
297
298    /// Same as [`estimate_fee`](fn.estimate_fee), but only with one estimate.
299    async fn estimate_fee_single<R, S, B>(
300        &self,
301        request: R,
302        simulation_flags: S,
303        block_id: B,
304    ) -> Result<FeeEstimate, ProviderError>
305    where
306        R: AsRef<BroadcastedTransaction> + Send + Sync,
307        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
308        B: AsRef<BlockId> + Send + Sync,
309    {
310        let mut result = self
311            .estimate_fee([request.as_ref().to_owned()], simulation_flags, block_id)
312            .await?;
313
314        if result.len() == 1 {
315            // Unwrapping here is safe becuase we already checked length
316            Ok(result.pop().unwrap())
317        } else {
318            Err(ProviderError::ArrayLengthMismatch)
319        }
320    }
321
322    /// Same as [`simulate_transactions`](fn.simulate_transactions), but only with one simulation.
323    async fn simulate_transaction<B, T, S>(
324        &self,
325        block_id: B,
326        transaction: T,
327        simulation_flags: S,
328    ) -> Result<SimulatedTransaction, ProviderError>
329    where
330        B: AsRef<BlockId> + Send + Sync,
331        T: AsRef<BroadcastedTransaction> + Send + Sync,
332        S: AsRef<[SimulationFlag]> + Send + Sync,
333    {
334        let mut result = self
335            .simulate_transactions(
336                block_id,
337                [transaction.as_ref().to_owned()],
338                simulation_flags,
339            )
340            .await?;
341
342        if result.len() == 1 {
343            // Unwrapping here is safe becuase we already checked length
344            Ok(result.pop().unwrap())
345        } else {
346            Err(ProviderError::ArrayLengthMismatch)
347        }
348    }
349}
350
351/// Trait for implementation-specific error type. These errors are irrelevant in most cases,
352/// assuming that users typically care more about the specifics of RPC errors instead of the
353/// underlying transport. Therefore, it makes little sense to bloat [`ProviderError`] with a generic
354/// parameter just for these errors. Instead, they're erased to this trait object.
355///
356/// This trait is used instead of a plain [`std::error::Error`] to allow downcasting, in case access
357/// to the specific error type is indeed desired. This is achieved with the `as_any()` method.
358pub trait ProviderImplError: Error + Debug + Send + Sync {
359    /// Returns a reference to the error as a trait object, allowing downcasting to the specific
360    /// error type.
361    fn as_any(&self) -> &dyn Any;
362}
363
364/// Errors using any [`Provider`] implementation. This type is deliberately not made generic such
365/// that:
366///
367/// - the [`Provider`] trait itself can be boxed;
368/// - error handling is easier.
369///
370/// As a downside, the [`Other`](ProviderError::Other) variant contains a boxed implementation-
371/// specific error. It's generally expected that users of [`Provider`] would not need to care about
372/// these errors, but in the case where they do, it's slightly harder to access than if generics are
373/// used instead.
374#[derive(Debug, thiserror::Error)]
375pub enum ProviderError {
376    /// A Starknet-related error, usually regarding the state or transaction.
377    #[error(transparent)]
378    StarknetError(StarknetError),
379    /// The request fails as the client is rate-limited.
380    #[error("Request rate limited")]
381    RateLimited,
382    /// When estimating fees for or simulating a single transaction, the server unexpectedly returns
383    /// data for zero or more than one transactions.
384    #[error("Array length mismatch")]
385    ArrayLengthMismatch,
386    /// Boxed implementation-specific errors.
387    #[error("{0}")]
388    Other(Box<dyn ProviderImplError>),
389}
390
391/// Typed request data for [`Provider`] requests.
392#[derive(Debug, Clone, Serialize)]
393#[serde(untagged)]
394pub enum ProviderRequestData {
395    /// Request data for `starknet_specVersion`.
396    SpecVersion(SpecVersionRequest),
397    /// Request data for `starknet_getBlockWithTxHashes`.
398    GetBlockWithTxHashes(GetBlockWithTxHashesRequest),
399    /// Request data for `starknet_getBlockWithTxs`.
400    GetBlockWithTxs(GetBlockWithTxsRequest),
401    /// Request data for `starknet_getBlockWithReceipts`.
402    GetBlockWithReceipts(GetBlockWithReceiptsRequest),
403    /// Request data for `starknet_getStateUpdate`.
404    GetStateUpdate(GetStateUpdateRequest),
405    /// Request data for `starknet_getStorageAt`.
406    GetStorageAt(GetStorageAtRequest),
407    /// Request data for `starknet_getMessagesStatus`.
408    GetMessagesStatus(GetMessagesStatusRequest),
409    /// Request data for `starknet_getTransactionStatus`.
410    GetTransactionStatus(GetTransactionStatusRequest),
411    /// Request data for `starknet_getTransactionByHash`.
412    GetTransactionByHash(GetTransactionByHashRequest),
413    /// Request data for `starknet_getTransactionByBlockIdAndIndex`.
414    GetTransactionByBlockIdAndIndex(GetTransactionByBlockIdAndIndexRequest),
415    /// Request data for `starknet_getTransactionReceipt`.
416    GetTransactionReceipt(GetTransactionReceiptRequest),
417    /// Request data for `starknet_getClass`.
418    GetClass(GetClassRequest),
419    /// Request data for `starknet_getClassHashAt`.
420    GetClassHashAt(GetClassHashAtRequest),
421    /// Request data for `starknet_getClassAt`.
422    GetClassAt(GetClassAtRequest),
423    /// Request data for `starknet_getBlockTransactionCount`.
424    GetBlockTransactionCount(GetBlockTransactionCountRequest),
425    /// Request data for `starknet_call`.
426    Call(CallRequest),
427    /// Request data for `starknet_estimateFee`.
428    EstimateFee(EstimateFeeRequest),
429    /// Request data for `starknet_estimateMessageFee`.
430    EstimateMessageFee(EstimateMessageFeeRequest),
431    /// Request data for `starknet_blockNumber`.
432    BlockNumber(BlockNumberRequest),
433    /// Request data for `starknet_blockHashAndNumber`.
434    BlockHashAndNumber(BlockHashAndNumberRequest),
435    /// Request data for `starknet_chainId`.
436    ChainId(ChainIdRequest),
437    /// Request data for `starknet_syncing`.
438    Syncing(SyncingRequest),
439    /// Request data for `starknet_getEvents`.
440    GetEvents(GetEventsRequest),
441    /// Request data for `starknet_getNonce`.
442    GetNonce(GetNonceRequest),
443    /// Request data for `starknet_getStorageProof`.
444    GetStorageProof(GetStorageProofRequest),
445    /// Request data for `starknet_addInvokeTransaction`.
446    AddInvokeTransaction(AddInvokeTransactionRequest),
447    /// Request data for `starknet_addDeclareTransaction`.
448    AddDeclareTransaction(AddDeclareTransactionRequest),
449    /// Request data for `starknet_addDeployAccountTransaction`.
450    AddDeployAccountTransaction(AddDeployAccountTransactionRequest),
451    /// Request data for `starknet_traceTransaction`.
452    TraceTransaction(TraceTransactionRequest),
453    /// Request data for `starknet_simulateTransactions`.
454    SimulateTransactions(SimulateTransactionsRequest),
455    /// Request data for `starknet_traceBlockTransactions`.
456    TraceBlockTransactions(TraceBlockTransactionsRequest),
457    /// Request data for `starknet_subscribeNewHeads`.
458    SubscribeNewHeads(SubscribeNewHeadsRequest),
459    /// Request data for `starknet_subscribeEvents`.
460    SubscribeEvents(SubscribeEventsRequest),
461    /// Request data for `starknet_subscribeTransactionStatus`.
462    SubscribeTransactionStatus(SubscribeTransactionStatusRequest),
463    /// Request data for `starknet_subscribeNewTransactionReceipts`.
464    SubscribeNewTransactionReceipts(SubscribeNewTransactionReceiptsRequest),
465    /// Request data for `starknet_subscribeNewTransactions`.
466    SubscribeNewTransactions(SubscribeNewTransactionsRequest),
467    /// Request data for `starknet_unsubscribe`.
468    Unsubscribe(UnsubscribeRequest),
469}
470
471/// Typed response data for [`Provider`] responses.
472#[allow(clippy::large_enum_variant)]
473#[derive(Debug, Clone)]
474pub enum ProviderResponseData {
475    /// Response data for `starknet_specVersion`.
476    SpecVersion(String),
477    /// Response data for `starknet_getBlockWithTxHashes`.
478    GetBlockWithTxHashes(MaybePreConfirmedBlockWithTxHashes),
479    /// Response data for `starknet_getBlockWithTxs`.
480    GetBlockWithTxs(MaybePreConfirmedBlockWithTxs),
481    /// Response data for `starknet_getBlockWithReceipts`.
482    GetBlockWithReceipts(MaybePreConfirmedBlockWithReceipts),
483    /// Response data for `starknet_getStateUpdate`.
484    GetStateUpdate(MaybePreConfirmedStateUpdate),
485    /// Response data for `starknet_getStorageAt`.
486    GetStorageAt(Felt),
487    /// Response data for `starknet_getMessagesStatus`.
488    GetMessagesStatus(Vec<MessageStatus>),
489    /// Response data for `starknet_getTransactionStatus`.
490    GetTransactionStatus(TransactionStatus),
491    /// Response data for `starknet_getTransactionByHash`.
492    GetTransactionByHash(Transaction),
493    /// Response data for `starknet_getTransactionByBlockIdAndIndex`.
494    GetTransactionByBlockIdAndIndex(Transaction),
495    /// Response data for `starknet_getTransactionReceipt`.
496    GetTransactionReceipt(TransactionReceiptWithBlockInfo),
497    /// Response data for `starknet_getClass`.
498    GetClass(ContractClass),
499    /// Response data for `starknet_getClassHashAt`.
500    GetClassHashAt(Felt),
501    /// Response data for `starknet_getClassAt`.
502    GetClassAt(ContractClass),
503    /// Response data for `starknet_getBlockTransactionCount`.
504    GetBlockTransactionCount(u64),
505    /// Response data for `starknet_call`.
506    Call(Vec<Felt>),
507    /// Response data for `starknet_estimateFee`.
508    EstimateFee(Vec<FeeEstimate>),
509    /// Response data for `starknet_estimateMessageFee`.
510    EstimateMessageFee(FeeEstimate),
511    /// Response data for `starknet_blockNumber`.
512    BlockNumber(u64),
513    /// Response data for `starknet_blockHashAndNumber`.
514    BlockHashAndNumber(BlockHashAndNumber),
515    /// Response data for `starknet_chainId`.
516    ChainId(Felt),
517    /// Response data for `starknet_syncing`.
518    Syncing(SyncStatusType),
519    /// Response data for `starknet_getEvents`.
520    GetEvents(EventsPage),
521    /// Response data for `starknet_getNonce`.
522    GetNonce(Felt),
523    /// Response data for `starknet_getStorageProof`.
524    GetStorageProof(StorageProof),
525    /// Response data for `starknet_addInvokeTransaction`.
526    AddInvokeTransaction(InvokeTransactionResult),
527    /// Response data for `starknet_addDeclareTransaction`.
528    AddDeclareTransaction(DeclareTransactionResult),
529    /// Response data for `starknet_addDeployAccountTransaction`.
530    AddDeployAccountTransaction(DeployAccountTransactionResult),
531    /// Response data for `starknet_traceTransaction`.
532    TraceTransaction(TransactionTrace),
533    /// Response data for `starknet_simulateTransactions`.
534    SimulateTransactions(Vec<SimulatedTransaction>),
535    /// Response data for `starknet_traceBlockTransactions`.
536    TraceBlockTransactions(Vec<TransactionTraceWithHash>),
537    /// Response data for `starknet_subscribeNewHeads`.
538    SubscribeNewHeads(SubscriptionId),
539    /// Response data for `starknet_subscribeEvents`.
540    SubscribeEvents(SubscriptionId),
541    /// Response data for `starknet_subscribeTransactionStatus`.
542    SubscribeTransactionStatus(SubscriptionId),
543    /// Response data for `starknet_subscribeNewTransactionReceipts`.
544    SubscribeNewTransactionReceipts(SubscriptionId),
545    /// Response data for `starknet_subscribeNewTransactions`.
546    SubscribeNewTransactions(SubscriptionId),
547    /// Response data for `starknet_unsubscribe`.
548    Unsubscribe(bool),
549}
550
551/// Typed data for stream updates.
552#[allow(clippy::enum_variant_names)]
553#[derive(Debug, Clone, Serialize)]
554#[serde(untagged)]
555pub enum StreamUpdateData {
556    /// Stream data for `starknet_subscriptionNewHeads`.
557    SubscriptionNewHeads(SubscriptionNewHeadsRequest),
558    /// Stream data for `starknet_subscriptionEvents`.
559    SubscriptionEvents(SubscriptionEventsRequest),
560    /// Stream data for `starknet_subscriptionTransactionStatus`.
561    SubscriptionTransactionStatus(SubscriptionTransactionStatusRequest),
562    /// Stream data for `starknet_subscriptionNewTransactionReceipts`.
563    SubscriptionNewTransactionReceipts(SubscriptionNewTransactionReceiptsRequest),
564    /// Stream data for `starknet_subscriptionNewTransaction`.
565    SubscriptionNewTransaction(SubscriptionNewTransactionRequest),
566    /// Stream data for `starknet_subscriptionReorg`.
567    SubscriptionReorg(SubscriptionReorgRequest),
568}
569
570impl StreamUpdateData {
571    /// Gets a reference to the subscription ID the update corresponds to.
572    pub fn subscription_id(&self) -> &SubscriptionId {
573        match self {
574            Self::SubscriptionNewHeads(update) => &update.subscription_id,
575            Self::SubscriptionEvents(update) => &update.subscription_id,
576            Self::SubscriptionTransactionStatus(update) => &update.subscription_id,
577            Self::SubscriptionNewTransactionReceipts(update) => &update.subscription_id,
578            Self::SubscriptionNewTransaction(update) => &update.subscription_id,
579            Self::SubscriptionReorg(update) => &update.subscription_id,
580        }
581    }
582}