starknet_rust_providers/jsonrpc/
mod.rs

1use std::{any::Any, error::Error, fmt::Display};
2
3use async_trait::async_trait;
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use serde_with::serde_as;
6use starknet_rust_core::{
7    serde::unsigned_field_element::UfeHex,
8    types::{
9        requests::*, BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction,
10        BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction,
11        ConfirmedBlockId, ContractClass, ContractErrorData, ContractStorageKeys,
12        DeclareTransactionResult, DeployAccountTransactionResult, EventFilter, EventFilterWithPage,
13        EventsPage, FeeEstimate, Felt as FeltPrimitive, FunctionCall, Hash256,
14        InvokeTransactionResult, MaybePreConfirmedBlockWithReceipts,
15        MaybePreConfirmedBlockWithTxHashes, MaybePreConfirmedBlockWithTxs,
16        MaybePreConfirmedStateUpdate, MessageFeeEstimate, MessageStatus, MsgFromL1,
17        NoTraceAvailableErrorData, ResultPageRequest, SimulatedTransaction, SimulationFlag,
18        SimulationFlagForEstimateFee, StarknetError, StorageProof, SubscriptionId, SyncStatusType,
19        Transaction, TransactionExecutionErrorData, TransactionReceiptWithBlockInfo,
20        TransactionStatus, TransactionTrace, TransactionTraceWithHash,
21    },
22};
23
24use crate::{
25    provider::ProviderImplError, Provider, ProviderError, ProviderRequestData,
26    ProviderResponseData, StreamUpdateData,
27};
28
29mod transports;
30pub use transports::{HttpTransport, HttpTransportError, JsonRpcTransport};
31#[cfg(feature = "worker")]
32pub use transports::{WorkersTransport, WorkersTransportError};
33
34/// A generic JSON-RPC client with any transport.
35///
36/// A "transport" is any implementation that can send JSON-RPC requests and receive responses. This
37/// most commonly happens over a network via HTTP connections, as with [`HttpTransport`].
38#[derive(Debug, Clone)]
39pub struct JsonRpcClient<T> {
40    transport: T,
41}
42
43/// All JSON-RPC methods as listed by the official specification.
44#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
45pub enum JsonRpcMethod {
46    /// The `starknet_specVersion` method.
47    #[serde(rename = "starknet_specVersion")]
48    SpecVersion,
49    /// The `starknet_getBlockWithTxHashes` method.
50    #[serde(rename = "starknet_getBlockWithTxHashes")]
51    GetBlockWithTxHashes,
52    /// The `starknet_getBlockWithTxs` method.
53    #[serde(rename = "starknet_getBlockWithTxs")]
54    GetBlockWithTxs,
55    /// The `starknet_getBlockWithReceipts` method.
56    #[serde(rename = "starknet_getBlockWithReceipts")]
57    GetBlockWithReceipts,
58    /// The `starknet_getStateUpdate` method.
59    #[serde(rename = "starknet_getStateUpdate")]
60    GetStateUpdate,
61    /// The `starknet_getStorageAt` method.
62    #[serde(rename = "starknet_getStorageAt")]
63    GetStorageAt,
64    /// The `starknet_getMessagesStatus` method.
65    #[serde(rename = "starknet_getMessagesStatus")]
66    GetMessagesStatus,
67    /// The `starknet_getTransactionStatus` method.
68    #[serde(rename = "starknet_getTransactionStatus")]
69    GetTransactionStatus,
70    /// The `starknet_getTransactionByHash` method.
71    #[serde(rename = "starknet_getTransactionByHash")]
72    GetTransactionByHash,
73    /// The `starknet_getTransactionByBlockIdAndIndex` method.
74    #[serde(rename = "starknet_getTransactionByBlockIdAndIndex")]
75    GetTransactionByBlockIdAndIndex,
76    /// The `starknet_getTransactionReceipt` method.
77    #[serde(rename = "starknet_getTransactionReceipt")]
78    GetTransactionReceipt,
79    /// The `starknet_getClass` method.
80    #[serde(rename = "starknet_getClass")]
81    GetClass,
82    /// The `starknet_getClassHashAt` method.
83    #[serde(rename = "starknet_getClassHashAt")]
84    GetClassHashAt,
85    /// The `starknet_getClassAt` method.
86    #[serde(rename = "starknet_getClassAt")]
87    GetClassAt,
88    /// The `starknet_getBlockTransactionCount` method.
89    #[serde(rename = "starknet_getBlockTransactionCount")]
90    GetBlockTransactionCount,
91    /// The `starknet_call` method.
92    #[serde(rename = "starknet_call")]
93    Call,
94    /// The `starknet_estimateFee` method.
95    #[serde(rename = "starknet_estimateFee")]
96    EstimateFee,
97    /// The `starknet_estimateMessageFee` method.
98    #[serde(rename = "starknet_estimateMessageFee")]
99    EstimateMessageFee,
100    /// The `starknet_blockNumber` method.
101    #[serde(rename = "starknet_blockNumber")]
102    BlockNumber,
103    /// The `starknet_blockHashAndNumber` method.
104    #[serde(rename = "starknet_blockHashAndNumber")]
105    BlockHashAndNumber,
106    /// The `starknet_chainId` method.
107    #[serde(rename = "starknet_chainId")]
108    ChainId,
109    /// The `starknet_syncing` method.
110    #[serde(rename = "starknet_syncing")]
111    Syncing,
112    /// The `starknet_getEvents` method.
113    #[serde(rename = "starknet_getEvents")]
114    GetEvents,
115    /// The `starknet_getNonce` method.
116    #[serde(rename = "starknet_getNonce")]
117    GetNonce,
118    /// The `starknet_getStorageProof` method.
119    #[serde(rename = "starknet_getStorageProof")]
120    GetStorageProof,
121    /// The `starknet_addInvokeTransaction` method.
122    #[serde(rename = "starknet_addInvokeTransaction")]
123    AddInvokeTransaction,
124    /// The `starknet_addDeclareTransaction` method.
125    #[serde(rename = "starknet_addDeclareTransaction")]
126    AddDeclareTransaction,
127    /// The `starknet_addDeployAccountTransaction` method.
128    #[serde(rename = "starknet_addDeployAccountTransaction")]
129    AddDeployAccountTransaction,
130    /// The `starknet_traceTransaction` method.
131    #[serde(rename = "starknet_traceTransaction")]
132    TraceTransaction,
133    /// The `starknet_simulateTransactions` method.
134    #[serde(rename = "starknet_simulateTransactions")]
135    SimulateTransactions,
136    /// The `starknet_traceBlockTransactions` method.
137    #[serde(rename = "starknet_traceBlockTransactions")]
138    TraceBlockTransactions,
139    /// The `starknet_subscribeNewHeads` method.
140    #[serde(rename = "starknet_subscribeNewHeads")]
141    SubscribeNewHeads,
142    /// The `starknet_subscriptionNewHeads` method.
143    #[serde(rename = "starknet_subscriptionNewHeads")]
144    SubscriptionNewHeads,
145    /// The `starknet_subscribeEvents` method.
146    #[serde(rename = "starknet_subscribeEvents")]
147    SubscribeEvents,
148    /// The `starknet_subscriptionEvents` method.
149    #[serde(rename = "starknet_subscriptionEvents")]
150    SubscriptionEvents,
151    /// The `starknet_subscribeTransactionStatus` method.
152    #[serde(rename = "starknet_subscribeTransactionStatus")]
153    SubscribeTransactionStatus,
154    /// The `starknet_subscriptionTransactionStatus` method.
155    #[serde(rename = "starknet_subscriptionTransactionStatus")]
156    SubscriptionTransactionStatus,
157    /// The `starknet_subscribeNewTransactionReceipts` method.
158    #[serde(rename = "starknet_subscribeNewTransactionReceipts")]
159    SubscribeNewTransactionReceipts,
160    /// The `starknet_subscriptionNewTransactionReceipts` method.
161    #[serde(rename = "starknet_subscriptionNewTransactionReceipts")]
162    SubscriptionNewTransactionReceipts,
163    /// The `starknet_subscribeNewTransactions` method.
164    #[serde(rename = "starknet_subscribeNewTransactions")]
165    SubscribeNewTransactions,
166    /// The `starknet_subscriptionNewTransaction` method.
167    #[serde(rename = "starknet_subscriptionNewTransaction")]
168    SubscriptionNewTransaction,
169    /// The `starknet_subscriptionReorg` method.
170    #[serde(rename = "starknet_subscriptionReorg")]
171    SubscriptionReorg,
172    /// The `starknet_unsubscribe` method.
173    #[serde(rename = "starknet_unsubscribe")]
174    Unsubscribe,
175}
176
177/// JSON-RPC request.
178#[derive(Debug, Clone)]
179pub struct JsonRpcRequest {
180    /// ID of the request. Useful for identifying responses in certain transports like `WebSocket`.
181    pub id: u64,
182    /// Data of the requeest.
183    pub data: ProviderRequestData,
184}
185
186/// JSON-RPC stream update.
187#[derive(Debug, Clone)]
188pub struct JsonRpcStreamUpdate {
189    /// Data of the requeest.
190    pub data: StreamUpdateData,
191}
192
193/// Errors from JSON-RPC client.
194#[derive(Debug, thiserror::Error)]
195pub enum JsonRpcClientError<T> {
196    /// JSON serialization/deserialization erors.
197    #[error(transparent)]
198    JsonError(serde_json::Error),
199    /// Transport-specific errors.
200    #[error(transparent)]
201    TransportError(T),
202    /// An unsuccessful response returned from the server is encountered.
203    #[error(transparent)]
204    JsonRpcError(JsonRpcError),
205}
206
207/// An unsuccessful response returned from the server.
208#[derive(Debug, Clone, Deserialize)]
209pub struct JsonRpcError {
210    /// Error code.
211    pub code: i64,
212    /// Error message.
213    pub message: String,
214    /// Additional error data if any.
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub data: Option<serde_json::Value>,
217}
218
219/// JSON-RPC response returned from a server.
220#[derive(Debug, Clone, Deserialize)]
221#[serde(untagged)]
222pub enum JsonRpcResponse<T> {
223    /// Successful response.
224    Success {
225        /// Same ID as the corresponding request.
226        id: u64,
227        /// Response data.
228        result: T,
229    },
230    /// Unsuccessful response.
231    Error {
232        /// Same ID as the corresponding request.
233        id: u64,
234        /// Error details.
235        error: JsonRpcError,
236    },
237}
238
239/// Failures trying to parse a [`JsonRpcError`] into [`StarknetError`].
240///
241/// [`StarknetError`] is the standard, provider-agnostic error type that all [`Provider`]
242/// implementations should strive to return in an error case, in a best-effort basis. This allows
243/// for unified error handling logic.
244///
245/// However, not all error cases can be properly converted, and this error type represents the cases
246/// when such failure happens.
247#[derive(Debug, thiserror::Error)]
248pub enum JsonRpcErrorConversionError {
249    /// The error code is outside of the range specified by the specification.
250    #[error("unknown error code")]
251    UnknownCode,
252    /// Error data is expected but missing.
253    #[error("missing data field")]
254    MissingData,
255    /// Error data is malformed.
256    #[error("unable to parse the data field")]
257    DataParsingFailure,
258}
259
260#[serde_as]
261#[derive(Serialize, Deserialize)]
262struct Felt(#[serde_as(as = "UfeHex")] pub FeltPrimitive);
263
264#[serde_as]
265#[derive(Serialize, Deserialize)]
266struct FeltArray(#[serde_as(as = "Vec<UfeHex>")] pub Vec<FeltPrimitive>);
267
268impl<T> JsonRpcClient<T> {
269    /// Constructs a new [`JsonRpcClient`] from a transport.
270    pub const fn new(transport: T) -> Self {
271        Self { transport }
272    }
273}
274
275impl<T> JsonRpcClient<T>
276where
277    T: 'static + JsonRpcTransport + Send + Sync,
278{
279    async fn send_request<P, R>(&self, method: JsonRpcMethod, params: P) -> Result<R, ProviderError>
280    where
281        P: Serialize + Send + Sync,
282        R: DeserializeOwned + Send,
283    {
284        match self
285            .transport
286            .send_request(method, params)
287            .await
288            .map_err(JsonRpcClientError::TransportError)?
289        {
290            JsonRpcResponse::Success { result, .. } => Ok(result),
291            JsonRpcResponse::Error { error, .. } => {
292                Err(match TryInto::<StarknetError>::try_into(&error) {
293                    Ok(error) => ProviderError::StarknetError(error),
294                    Err(_) => JsonRpcClientError::<T::Error>::JsonRpcError(error).into(),
295                })
296            }
297        }
298    }
299
300    async fn send_requests<R>(
301        &self,
302        requests: R,
303    ) -> Result<Vec<ProviderResponseData>, ProviderError>
304    where
305        R: AsRef<[ProviderRequestData]> + Send + Sync,
306    {
307        let mut results = vec![];
308
309        let responses = self
310            .transport
311            .send_requests(requests.as_ref().to_vec())
312            .await
313            .map_err(JsonRpcClientError::TransportError)?;
314
315        for (request, response) in requests.as_ref().iter().zip(responses.into_iter()) {
316            match response {
317                JsonRpcResponse::Success { result, .. } => {
318                    let result = match request {
319                        ProviderRequestData::SpecVersion(_) => ProviderResponseData::SpecVersion(
320                            String::deserialize(result)
321                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
322                        ),
323                        ProviderRequestData::GetBlockWithTxHashes(_) => {
324                            ProviderResponseData::GetBlockWithTxHashes(
325                                MaybePreConfirmedBlockWithTxHashes::deserialize(result)
326                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
327                            )
328                        }
329                        ProviderRequestData::GetBlockWithTxs(_) => {
330                            ProviderResponseData::GetBlockWithTxs(
331                                MaybePreConfirmedBlockWithTxs::deserialize(result)
332                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
333                            )
334                        }
335                        ProviderRequestData::GetBlockWithReceipts(_) => {
336                            ProviderResponseData::GetBlockWithReceipts(
337                                MaybePreConfirmedBlockWithReceipts::deserialize(result)
338                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
339                            )
340                        }
341                        ProviderRequestData::GetStateUpdate(_) => {
342                            ProviderResponseData::GetStateUpdate(
343                                MaybePreConfirmedStateUpdate::deserialize(result)
344                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
345                            )
346                        }
347                        ProviderRequestData::GetStorageAt(_) => ProviderResponseData::GetStorageAt(
348                            Felt::deserialize(result)
349                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?
350                                .0,
351                        ),
352                        ProviderRequestData::GetMessagesStatus(_) => {
353                            ProviderResponseData::GetMessagesStatus(
354                                Vec::<MessageStatus>::deserialize(result)
355                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
356                            )
357                        }
358                        ProviderRequestData::GetTransactionStatus(_) => {
359                            ProviderResponseData::GetTransactionStatus(
360                                TransactionStatus::deserialize(result)
361                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
362                            )
363                        }
364                        ProviderRequestData::GetTransactionByHash(_) => {
365                            ProviderResponseData::GetTransactionByHash(
366                                Transaction::deserialize(result)
367                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
368                            )
369                        }
370                        ProviderRequestData::GetTransactionByBlockIdAndIndex(_) => {
371                            ProviderResponseData::GetTransactionByBlockIdAndIndex(
372                                Transaction::deserialize(result)
373                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
374                            )
375                        }
376                        ProviderRequestData::GetTransactionReceipt(_) => {
377                            ProviderResponseData::GetTransactionReceipt(
378                                TransactionReceiptWithBlockInfo::deserialize(result)
379                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
380                            )
381                        }
382                        ProviderRequestData::GetClass(_) => ProviderResponseData::GetClass(
383                            ContractClass::deserialize(result)
384                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
385                        ),
386                        ProviderRequestData::GetClassHashAt(_) => {
387                            ProviderResponseData::GetClassHashAt(
388                                Felt::deserialize(result)
389                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?
390                                    .0,
391                            )
392                        }
393                        ProviderRequestData::GetClassAt(_) => ProviderResponseData::GetClassAt(
394                            ContractClass::deserialize(result)
395                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
396                        ),
397                        ProviderRequestData::GetBlockTransactionCount(_) => {
398                            ProviderResponseData::GetBlockTransactionCount(
399                                u64::deserialize(result)
400                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
401                            )
402                        }
403                        ProviderRequestData::Call(_) => ProviderResponseData::Call(
404                            FeltArray::deserialize(result)
405                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?
406                                .0,
407                        ),
408                        ProviderRequestData::EstimateFee(_) => ProviderResponseData::EstimateFee(
409                            Vec::<FeeEstimate>::deserialize(result)
410                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
411                        ),
412                        ProviderRequestData::EstimateMessageFee(_) => {
413                            ProviderResponseData::EstimateMessageFee(
414                                FeeEstimate::deserialize(result)
415                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
416                            )
417                        }
418                        ProviderRequestData::BlockNumber(_) => ProviderResponseData::BlockNumber(
419                            u64::deserialize(result)
420                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
421                        ),
422                        ProviderRequestData::BlockHashAndNumber(_) => {
423                            ProviderResponseData::BlockHashAndNumber(
424                                BlockHashAndNumber::deserialize(result)
425                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
426                            )
427                        }
428                        ProviderRequestData::ChainId(_) => ProviderResponseData::ChainId(
429                            Felt::deserialize(result)
430                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?
431                                .0,
432                        ),
433                        ProviderRequestData::Syncing(_) => ProviderResponseData::Syncing(
434                            SyncStatusType::deserialize(result)
435                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
436                        ),
437                        ProviderRequestData::GetEvents(_) => ProviderResponseData::GetEvents(
438                            EventsPage::deserialize(result)
439                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
440                        ),
441                        ProviderRequestData::GetNonce(_) => ProviderResponseData::GetNonce(
442                            Felt::deserialize(result)
443                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?
444                                .0,
445                        ),
446                        ProviderRequestData::GetStorageProof(_) => {
447                            ProviderResponseData::GetStorageProof(
448                                StorageProof::deserialize(result)
449                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
450                            )
451                        }
452                        ProviderRequestData::AddInvokeTransaction(_) => {
453                            ProviderResponseData::AddInvokeTransaction(
454                                InvokeTransactionResult::deserialize(result)
455                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
456                            )
457                        }
458                        ProviderRequestData::AddDeclareTransaction(_) => {
459                            ProviderResponseData::AddDeclareTransaction(
460                                DeclareTransactionResult::deserialize(result)
461                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
462                            )
463                        }
464                        ProviderRequestData::AddDeployAccountTransaction(_) => {
465                            ProviderResponseData::AddDeployAccountTransaction(
466                                DeployAccountTransactionResult::deserialize(result)
467                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
468                            )
469                        }
470                        ProviderRequestData::TraceTransaction(_) => {
471                            ProviderResponseData::TraceTransaction(
472                                TransactionTrace::deserialize(result)
473                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
474                            )
475                        }
476                        ProviderRequestData::SimulateTransactions(_) => {
477                            ProviderResponseData::SimulateTransactions(
478                                Vec::<SimulatedTransaction>::deserialize(result)
479                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
480                            )
481                        }
482                        ProviderRequestData::TraceBlockTransactions(_) => {
483                            ProviderResponseData::TraceBlockTransactions(
484                                Vec::<TransactionTraceWithHash>::deserialize(result)
485                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
486                            )
487                        }
488                        ProviderRequestData::SubscribeNewHeads(_) => {
489                            ProviderResponseData::SubscribeNewHeads(
490                                SubscriptionId::deserialize(result)
491                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
492                            )
493                        }
494                        ProviderRequestData::SubscribeEvents(_) => {
495                            ProviderResponseData::SubscribeEvents(
496                                SubscriptionId::deserialize(result)
497                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
498                            )
499                        }
500                        ProviderRequestData::SubscribeTransactionStatus(_) => {
501                            ProviderResponseData::SubscribeTransactionStatus(
502                                SubscriptionId::deserialize(result)
503                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
504                            )
505                        }
506                        ProviderRequestData::SubscribeNewTransactionReceipts(_) => {
507                            ProviderResponseData::SubscribeNewTransactionReceipts(
508                                SubscriptionId::deserialize(result)
509                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
510                            )
511                        }
512                        ProviderRequestData::SubscribeNewTransactions(_) => {
513                            ProviderResponseData::SubscribeNewTransactions(
514                                SubscriptionId::deserialize(result)
515                                    .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
516                            )
517                        }
518                        ProviderRequestData::Unsubscribe(_) => ProviderResponseData::Unsubscribe(
519                            bool::deserialize(result)
520                                .map_err(JsonRpcClientError::<T::Error>::JsonError)?,
521                        ),
522                    };
523
524                    results.push(result);
525                }
526                // TODO: add context on index of request causing the error
527                JsonRpcResponse::Error { error, .. } => {
528                    return Err(match TryInto::<StarknetError>::try_into(&error) {
529                        Ok(error) => ProviderError::StarknetError(error),
530                        Err(_) => JsonRpcClientError::<T::Error>::JsonRpcError(error).into(),
531                    })
532                }
533            }
534        }
535
536        Ok(results)
537    }
538}
539
540#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
541#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
542impl<T> Provider for JsonRpcClient<T>
543where
544    T: 'static + JsonRpcTransport + Sync + Send,
545{
546    /// Returns the version of the Starknet JSON-RPC specification being used
547    async fn spec_version(&self) -> Result<String, ProviderError> {
548        self.send_request(JsonRpcMethod::SpecVersion, SpecVersionRequest)
549            .await
550    }
551
552    /// Returns the version of the Starknet being used.
553    async fn starknet_version<B>(&self, block_id: B) -> Result<String, ProviderError>
554    where
555        B: AsRef<BlockId> + Send + Sync,
556    {
557        Ok(match self.get_block_with_tx_hashes(block_id).await? {
558            MaybePreConfirmedBlockWithTxHashes::Block(block) => block.starknet_version,
559            MaybePreConfirmedBlockWithTxHashes::PreConfirmedBlock(block) => block.starknet_version,
560        })
561    }
562
563    /// Get block information with transaction hashes given the block id
564    async fn get_block_with_tx_hashes<B>(
565        &self,
566        block_id: B,
567    ) -> Result<MaybePreConfirmedBlockWithTxHashes, ProviderError>
568    where
569        B: AsRef<BlockId> + Send + Sync,
570    {
571        self.send_request(
572            JsonRpcMethod::GetBlockWithTxHashes,
573            GetBlockWithTxHashesRequestRef {
574                block_id: block_id.as_ref(),
575            },
576        )
577        .await
578    }
579
580    /// Get block information with full transactions given the block id
581    async fn get_block_with_txs<B>(
582        &self,
583        block_id: B,
584    ) -> Result<MaybePreConfirmedBlockWithTxs, ProviderError>
585    where
586        B: AsRef<BlockId> + Send + Sync,
587    {
588        self.send_request(
589            JsonRpcMethod::GetBlockWithTxs,
590            GetBlockWithTxsRequestRef {
591                block_id: block_id.as_ref(),
592            },
593        )
594        .await
595    }
596
597    /// Get block information with full transactions and receipts given the block id
598    async fn get_block_with_receipts<B>(
599        &self,
600        block_id: B,
601    ) -> Result<MaybePreConfirmedBlockWithReceipts, ProviderError>
602    where
603        B: AsRef<BlockId> + Send + Sync,
604    {
605        self.send_request(
606            JsonRpcMethod::GetBlockWithReceipts,
607            GetBlockWithReceiptsRequestRef {
608                block_id: block_id.as_ref(),
609            },
610        )
611        .await
612    }
613
614    /// Get the information about the result of executing the requested block
615    async fn get_state_update<B>(
616        &self,
617        block_id: B,
618    ) -> Result<MaybePreConfirmedStateUpdate, ProviderError>
619    where
620        B: AsRef<BlockId> + Send + Sync,
621    {
622        self.send_request(
623            JsonRpcMethod::GetStateUpdate,
624            GetStateUpdateRequestRef {
625                block_id: block_id.as_ref(),
626            },
627        )
628        .await
629    }
630
631    /// Get the value of the storage at the given address and key
632    async fn get_storage_at<A, K, B>(
633        &self,
634        contract_address: A,
635        key: K,
636        block_id: B,
637    ) -> Result<FeltPrimitive, ProviderError>
638    where
639        A: AsRef<FeltPrimitive> + Send + Sync,
640        K: AsRef<FeltPrimitive> + Send + Sync,
641        B: AsRef<BlockId> + Send + Sync,
642    {
643        Ok(self
644            .send_request::<_, Felt>(
645                JsonRpcMethod::GetStorageAt,
646                GetStorageAtRequestRef {
647                    contract_address: contract_address.as_ref(),
648                    key: key.as_ref(),
649                    block_id: block_id.as_ref(),
650                },
651            )
652            .await?
653            .0)
654    }
655
656    /// Given an l1 tx hash, returns the associated `l1_handler` tx hashes and statuses for all L1 ->
657    /// L2 messages sent by the l1 transaction, ordered by the l1 tx sending order
658    async fn get_messages_status(
659        &self,
660        transaction_hash: Hash256,
661    ) -> Result<Vec<MessageStatus>, ProviderError> {
662        self.send_request(
663            JsonRpcMethod::GetMessagesStatus,
664            GetMessagesStatusRequestRef {
665                transaction_hash: &transaction_hash,
666            },
667        )
668        .await
669    }
670
671    /// Gets the transaction status (possibly reflecting that the tx is still in
672    /// the mempool, or dropped from it)
673    async fn get_transaction_status<H>(
674        &self,
675        transaction_hash: H,
676    ) -> Result<TransactionStatus, ProviderError>
677    where
678        H: AsRef<FeltPrimitive> + Send + Sync,
679    {
680        self.send_request(
681            JsonRpcMethod::GetTransactionStatus,
682            GetTransactionStatusRequestRef {
683                transaction_hash: transaction_hash.as_ref(),
684            },
685        )
686        .await
687    }
688
689    /// Get the details and status of a submitted transaction
690    async fn get_transaction_by_hash<H>(
691        &self,
692        transaction_hash: H,
693    ) -> Result<Transaction, ProviderError>
694    where
695        H: AsRef<FeltPrimitive> + Send + Sync,
696    {
697        self.send_request(
698            JsonRpcMethod::GetTransactionByHash,
699            GetTransactionByHashRequestRef {
700                transaction_hash: transaction_hash.as_ref(),
701            },
702        )
703        .await
704    }
705
706    /// Get the details of a transaction by a given block id and index
707    async fn get_transaction_by_block_id_and_index<B>(
708        &self,
709        block_id: B,
710        index: u64,
711    ) -> Result<Transaction, ProviderError>
712    where
713        B: AsRef<BlockId> + Send + Sync,
714    {
715        self.send_request(
716            JsonRpcMethod::GetTransactionByBlockIdAndIndex,
717            GetTransactionByBlockIdAndIndexRequestRef {
718                block_id: block_id.as_ref(),
719                index: &index,
720            },
721        )
722        .await
723    }
724
725    /// Get the details of a transaction by a given block number and index
726    async fn get_transaction_receipt<H>(
727        &self,
728        transaction_hash: H,
729    ) -> Result<TransactionReceiptWithBlockInfo, ProviderError>
730    where
731        H: AsRef<FeltPrimitive> + Send + Sync,
732    {
733        self.send_request(
734            JsonRpcMethod::GetTransactionReceipt,
735            GetTransactionReceiptRequestRef {
736                transaction_hash: transaction_hash.as_ref(),
737            },
738        )
739        .await
740    }
741
742    /// Get the contract class definition in the given block associated with the given hash
743    async fn get_class<B, H>(
744        &self,
745        block_id: B,
746        class_hash: H,
747    ) -> Result<ContractClass, ProviderError>
748    where
749        B: AsRef<BlockId> + Send + Sync,
750        H: AsRef<FeltPrimitive> + Send + Sync,
751    {
752        self.send_request(
753            JsonRpcMethod::GetClass,
754            GetClassRequestRef {
755                block_id: block_id.as_ref(),
756                class_hash: class_hash.as_ref(),
757            },
758        )
759        .await
760    }
761
762    /// Get the contract class hash in the given block for the contract deployed at the given address
763    async fn get_class_hash_at<B, A>(
764        &self,
765        block_id: B,
766        contract_address: A,
767    ) -> Result<FeltPrimitive, ProviderError>
768    where
769        B: AsRef<BlockId> + Send + Sync,
770        A: AsRef<FeltPrimitive> + Send + Sync,
771    {
772        Ok(self
773            .send_request::<_, Felt>(
774                JsonRpcMethod::GetClassHashAt,
775                GetClassHashAtRequestRef {
776                    block_id: block_id.as_ref(),
777                    contract_address: contract_address.as_ref(),
778                },
779            )
780            .await?
781            .0)
782    }
783
784    /// Get the contract class definition in the given block at the given address
785    async fn get_class_at<B, A>(
786        &self,
787        block_id: B,
788        contract_address: A,
789    ) -> Result<ContractClass, ProviderError>
790    where
791        B: AsRef<BlockId> + Send + Sync,
792        A: AsRef<FeltPrimitive> + Send + Sync,
793    {
794        self.send_request(
795            JsonRpcMethod::GetClassAt,
796            GetClassAtRequestRef {
797                block_id: block_id.as_ref(),
798                contract_address: contract_address.as_ref(),
799            },
800        )
801        .await
802    }
803
804    /// Get the number of transactions in a block given a block id
805    async fn get_block_transaction_count<B>(&self, block_id: B) -> Result<u64, ProviderError>
806    where
807        B: AsRef<BlockId> + Send + Sync,
808    {
809        self.send_request(
810            JsonRpcMethod::GetBlockTransactionCount,
811            GetBlockTransactionCountRequestRef {
812                block_id: block_id.as_ref(),
813            },
814        )
815        .await
816    }
817
818    /// Call a starknet function without creating a Starknet transaction
819    async fn call<R, B>(&self, request: R, block_id: B) -> Result<Vec<FeltPrimitive>, ProviderError>
820    where
821        R: AsRef<FunctionCall> + Send + Sync,
822        B: AsRef<BlockId> + Send + Sync,
823    {
824        Ok(self
825            .send_request::<_, FeltArray>(
826                JsonRpcMethod::Call,
827                CallRequestRef {
828                    request: request.as_ref(),
829                    block_id: block_id.as_ref(),
830                },
831            )
832            .await?
833            .0)
834    }
835
836    /// Estimate the fee for a given Starknet transaction
837    async fn estimate_fee<R, S, B>(
838        &self,
839        request: R,
840        simulation_flags: S,
841        block_id: B,
842    ) -> Result<Vec<FeeEstimate>, ProviderError>
843    where
844        R: AsRef<[BroadcastedTransaction]> + Send + Sync,
845        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
846        B: AsRef<BlockId> + Send + Sync,
847    {
848        self.send_request(
849            JsonRpcMethod::EstimateFee,
850            EstimateFeeRequestRef {
851                request: request.as_ref(),
852                simulation_flags: simulation_flags.as_ref(),
853                block_id: block_id.as_ref(),
854            },
855        )
856        .await
857    }
858
859    /// Estimate the L2 fee of a message sent on L1
860    async fn estimate_message_fee<M, B>(
861        &self,
862        message: M,
863        block_id: B,
864    ) -> Result<MessageFeeEstimate, ProviderError>
865    where
866        M: AsRef<MsgFromL1> + Send + Sync,
867        B: AsRef<BlockId> + Send + Sync,
868    {
869        self.send_request(
870            JsonRpcMethod::EstimateMessageFee,
871            EstimateMessageFeeRequestRef {
872                message: message.as_ref(),
873                block_id: block_id.as_ref(),
874            },
875        )
876        .await
877    }
878
879    /// Get the most recent accepted block number
880    async fn block_number(&self) -> Result<u64, ProviderError> {
881        self.send_request(JsonRpcMethod::BlockNumber, BlockNumberRequest)
882            .await
883    }
884
885    /// Get the most recent accepted block hash and number
886    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError> {
887        self.send_request(JsonRpcMethod::BlockHashAndNumber, BlockHashAndNumberRequest)
888            .await
889    }
890
891    /// Return the currently configured Starknet chain id
892    async fn chain_id(&self) -> Result<FeltPrimitive, ProviderError> {
893        Ok(self
894            .send_request::<_, Felt>(JsonRpcMethod::ChainId, ChainIdRequest)
895            .await?
896            .0)
897    }
898
899    /// Returns an object about the sync status, or false if the node is not synching
900    async fn syncing(&self) -> Result<SyncStatusType, ProviderError> {
901        self.send_request(JsonRpcMethod::Syncing, SyncingRequest)
902            .await
903    }
904
905    /// Returns all events matching the given filter
906    async fn get_events(
907        &self,
908        filter: EventFilter,
909        continuation_token: Option<String>,
910        chunk_size: u64,
911    ) -> Result<EventsPage, ProviderError> {
912        self.send_request(
913            JsonRpcMethod::GetEvents,
914            GetEventsRequestRef {
915                filter: &EventFilterWithPage {
916                    event_filter: filter,
917                    result_page_request: ResultPageRequest {
918                        continuation_token,
919                        chunk_size,
920                    },
921                },
922            },
923        )
924        .await
925    }
926
927    /// Get the nonce associated with the given address in the given block
928    async fn get_nonce<B, A>(
929        &self,
930        block_id: B,
931        contract_address: A,
932    ) -> Result<FeltPrimitive, ProviderError>
933    where
934        B: AsRef<BlockId> + Send + Sync,
935        A: AsRef<FeltPrimitive> + Send + Sync,
936    {
937        Ok(self
938            .send_request::<_, Felt>(
939                JsonRpcMethod::GetNonce,
940                GetNonceRequestRef {
941                    block_id: block_id.as_ref(),
942                    contract_address: contract_address.as_ref(),
943                },
944            )
945            .await?
946            .0)
947    }
948
949    /// Get merkle paths in one of the state tries: global state, classes, individual contract.
950    /// A single request can query for any mix of the three types of storage proofs (classes,
951    /// contracts, and storage).
952    async fn get_storage_proof<B, H, A, K>(
953        &self,
954        block_id: B,
955        class_hashes: H,
956        contract_addresses: A,
957        contracts_storage_keys: K,
958    ) -> Result<StorageProof, ProviderError>
959    where
960        B: AsRef<ConfirmedBlockId> + Send + Sync,
961        H: AsRef<[FeltPrimitive]> + Send + Sync,
962        A: AsRef<[FeltPrimitive]> + Send + Sync,
963        K: AsRef<[ContractStorageKeys]> + Send + Sync,
964    {
965        self.send_request(
966            JsonRpcMethod::GetStorageProof,
967            GetStorageProofRequestRef {
968                block_id: block_id.as_ref(),
969                class_hashes: Some(class_hashes.as_ref()),
970                contract_addresses: Some(contract_addresses.as_ref()),
971                contracts_storage_keys: Some(contracts_storage_keys.as_ref()),
972            },
973        )
974        .await
975    }
976
977    /// Submit a new transaction to be added to the chain
978    async fn add_invoke_transaction<I>(
979        &self,
980        invoke_transaction: I,
981    ) -> Result<InvokeTransactionResult, ProviderError>
982    where
983        I: AsRef<BroadcastedInvokeTransaction> + Send + Sync,
984    {
985        self.send_request(
986            JsonRpcMethod::AddInvokeTransaction,
987            AddInvokeTransactionRequestRef {
988                invoke_transaction: invoke_transaction.as_ref(),
989            },
990        )
991        .await
992    }
993
994    /// Submit a new transaction to be added to the chain
995    async fn add_declare_transaction<D>(
996        &self,
997        declare_transaction: D,
998    ) -> Result<DeclareTransactionResult, ProviderError>
999    where
1000        D: AsRef<BroadcastedDeclareTransaction> + Send + Sync,
1001    {
1002        self.send_request(
1003            JsonRpcMethod::AddDeclareTransaction,
1004            AddDeclareTransactionRequestRef {
1005                declare_transaction: declare_transaction.as_ref(),
1006            },
1007        )
1008        .await
1009    }
1010
1011    /// Submit a new deploy account transaction
1012    async fn add_deploy_account_transaction<D>(
1013        &self,
1014        deploy_account_transaction: D,
1015    ) -> Result<DeployAccountTransactionResult, ProviderError>
1016    where
1017        D: AsRef<BroadcastedDeployAccountTransaction> + Send + Sync,
1018    {
1019        self.send_request(
1020            JsonRpcMethod::AddDeployAccountTransaction,
1021            AddDeployAccountTransactionRequestRef {
1022                deploy_account_transaction: deploy_account_transaction.as_ref(),
1023            },
1024        )
1025        .await
1026    }
1027
1028    /// For a given executed transaction, return the trace of its execution, including internal
1029    /// calls
1030    async fn trace_transaction<H>(
1031        &self,
1032        transaction_hash: H,
1033    ) -> Result<TransactionTrace, ProviderError>
1034    where
1035        H: AsRef<FeltPrimitive> + Send + Sync,
1036    {
1037        self.send_request(
1038            JsonRpcMethod::TraceTransaction,
1039            TraceTransactionRequestRef {
1040                transaction_hash: transaction_hash.as_ref(),
1041            },
1042        )
1043        .await
1044    }
1045
1046    /// Simulate a given sequence of transactions on the requested state, and generate the execution
1047    /// traces. Note that some of the transactions may revert, in which case no error is thrown, but
1048    /// revert details can be seen on the returned trace object. . Note that some of the
1049    /// transactions may revert, this will be reflected by the `revert_error` property in the trace.
1050    /// Other types of failures (e.g. unexpected error or failure in the validation phase) will
1051    /// result in `TRANSACTION_EXECUTION_ERROR`.
1052    async fn simulate_transactions<B, TX, S>(
1053        &self,
1054        block_id: B,
1055        transactions: TX,
1056        simulation_flags: S,
1057    ) -> Result<Vec<SimulatedTransaction>, ProviderError>
1058    where
1059        B: AsRef<BlockId> + Send + Sync,
1060        TX: AsRef<[BroadcastedTransaction]> + Send + Sync,
1061        S: AsRef<[SimulationFlag]> + Send + Sync,
1062    {
1063        self.send_request(
1064            JsonRpcMethod::SimulateTransactions,
1065            SimulateTransactionsRequestRef {
1066                block_id: block_id.as_ref(),
1067                transactions: transactions.as_ref(),
1068                simulation_flags: simulation_flags.as_ref(),
1069            },
1070        )
1071        .await
1072    }
1073
1074    /// Retrieve traces for all transactions in the given block.
1075    async fn trace_block_transactions<B>(
1076        &self,
1077        block_id: B,
1078    ) -> Result<Vec<TransactionTraceWithHash>, ProviderError>
1079    where
1080        B: AsRef<ConfirmedBlockId> + Send + Sync,
1081    {
1082        self.send_request(
1083            JsonRpcMethod::TraceBlockTransactions,
1084            TraceBlockTransactionsRequestRef {
1085                block_id: block_id.as_ref(),
1086            },
1087        )
1088        .await
1089    }
1090
1091    async fn batch_requests<R>(
1092        &self,
1093        requests: R,
1094    ) -> Result<Vec<ProviderResponseData>, ProviderError>
1095    where
1096        R: AsRef<[ProviderRequestData]> + Send + Sync,
1097    {
1098        self.send_requests(requests).await
1099    }
1100}
1101
1102impl ProviderRequestData {
1103    const fn jsonrpc_method(&self) -> JsonRpcMethod {
1104        match self {
1105            Self::SpecVersion(_) => JsonRpcMethod::SpecVersion,
1106            Self::GetBlockWithTxHashes(_) => JsonRpcMethod::GetBlockWithTxHashes,
1107            Self::GetBlockWithTxs(_) => JsonRpcMethod::GetBlockWithTxs,
1108            Self::GetBlockWithReceipts(_) => JsonRpcMethod::GetBlockWithReceipts,
1109            Self::GetStateUpdate(_) => JsonRpcMethod::GetStateUpdate,
1110            Self::GetStorageAt(_) => JsonRpcMethod::GetStorageAt,
1111            Self::GetMessagesStatus(_) => JsonRpcMethod::GetMessagesStatus,
1112            Self::GetTransactionStatus(_) => JsonRpcMethod::GetTransactionStatus,
1113            Self::GetTransactionByHash(_) => JsonRpcMethod::GetTransactionByHash,
1114            Self::GetTransactionByBlockIdAndIndex(_) => {
1115                JsonRpcMethod::GetTransactionByBlockIdAndIndex
1116            }
1117            Self::GetTransactionReceipt(_) => JsonRpcMethod::GetTransactionReceipt,
1118            Self::GetClass(_) => JsonRpcMethod::GetClass,
1119            Self::GetClassHashAt(_) => JsonRpcMethod::GetClassHashAt,
1120            Self::GetClassAt(_) => JsonRpcMethod::GetClassAt,
1121            Self::GetBlockTransactionCount(_) => JsonRpcMethod::GetBlockTransactionCount,
1122            Self::Call(_) => JsonRpcMethod::Call,
1123            Self::EstimateFee(_) => JsonRpcMethod::EstimateFee,
1124            Self::EstimateMessageFee(_) => JsonRpcMethod::EstimateMessageFee,
1125            Self::BlockNumber(_) => JsonRpcMethod::BlockNumber,
1126            Self::BlockHashAndNumber(_) => JsonRpcMethod::BlockHashAndNumber,
1127            Self::ChainId(_) => JsonRpcMethod::ChainId,
1128            Self::Syncing(_) => JsonRpcMethod::Syncing,
1129            Self::GetEvents(_) => JsonRpcMethod::GetEvents,
1130            Self::GetNonce(_) => JsonRpcMethod::GetNonce,
1131            Self::GetStorageProof(_) => JsonRpcMethod::GetStorageProof,
1132            Self::AddInvokeTransaction(_) => JsonRpcMethod::AddInvokeTransaction,
1133            Self::AddDeclareTransaction(_) => JsonRpcMethod::AddDeclareTransaction,
1134            Self::AddDeployAccountTransaction(_) => JsonRpcMethod::AddDeployAccountTransaction,
1135            Self::TraceTransaction(_) => JsonRpcMethod::TraceTransaction,
1136            Self::SimulateTransactions(_) => JsonRpcMethod::SimulateTransactions,
1137            Self::TraceBlockTransactions(_) => JsonRpcMethod::TraceBlockTransactions,
1138            Self::SubscribeNewHeads(_) => JsonRpcMethod::SubscribeNewHeads,
1139            Self::SubscribeEvents(_) => JsonRpcMethod::SubscribeEvents,
1140            Self::SubscribeTransactionStatus(_) => JsonRpcMethod::SubscribeTransactionStatus,
1141            Self::SubscribeNewTransactionReceipts(_) => {
1142                JsonRpcMethod::SubscribeNewTransactionReceipts
1143            }
1144            Self::SubscribeNewTransactions(_) => JsonRpcMethod::SubscribeNewTransactions,
1145            Self::Unsubscribe(_) => JsonRpcMethod::Unsubscribe,
1146        }
1147    }
1148}
1149
1150impl StreamUpdateData {
1151    const fn jsonrpc_method(&self) -> JsonRpcMethod {
1152        match self {
1153            Self::SubscriptionNewHeads(_) => JsonRpcMethod::SubscriptionNewHeads,
1154            Self::SubscriptionEvents(_) => JsonRpcMethod::SubscriptionEvents,
1155            Self::SubscriptionTransactionStatus(_) => JsonRpcMethod::SubscriptionTransactionStatus,
1156            Self::SubscriptionNewTransactionReceipts(_) => {
1157                JsonRpcMethod::SubscriptionNewTransactionReceipts
1158            }
1159            Self::SubscriptionNewTransaction(_) => JsonRpcMethod::SubscriptionNewTransaction,
1160            Self::SubscriptionReorg(_) => JsonRpcMethod::SubscriptionReorg,
1161        }
1162    }
1163}
1164
1165impl Serialize for JsonRpcRequest {
1166    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1167    where
1168        S: serde::Serializer,
1169    {
1170        #[derive(Serialize)]
1171        struct RawRequest<'a> {
1172            jsonrpc: &'static str,
1173            id: u64,
1174            method: JsonRpcMethod,
1175            params: &'a ProviderRequestData,
1176        }
1177
1178        RawRequest::serialize(
1179            &RawRequest {
1180                jsonrpc: "2.0",
1181                id: self.id,
1182                method: self.data.jsonrpc_method(),
1183                params: &self.data,
1184            },
1185            serializer,
1186        )
1187    }
1188}
1189
1190impl<'de> Deserialize<'de> for JsonRpcRequest {
1191    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1192    where
1193        D: serde::Deserializer<'de>,
1194    {
1195        #[derive(Deserialize)]
1196        struct RawRequest {
1197            id: u64,
1198            method: JsonRpcMethod,
1199            params: serde_json::Value,
1200        }
1201
1202        let error_mapper =
1203            |err| serde::de::Error::custom(format!("unable to decode params: {err}"));
1204
1205        let raw_request = RawRequest::deserialize(deserializer)?;
1206        let request_data = match raw_request.method {
1207            JsonRpcMethod::SpecVersion => ProviderRequestData::SpecVersion(
1208                serde_json::from_value::<SpecVersionRequest>(raw_request.params)
1209                    .map_err(error_mapper)?,
1210            ),
1211            JsonRpcMethod::GetBlockWithTxHashes => ProviderRequestData::GetBlockWithTxHashes(
1212                serde_json::from_value::<GetBlockWithTxHashesRequest>(raw_request.params)
1213                    .map_err(error_mapper)?,
1214            ),
1215            JsonRpcMethod::GetBlockWithTxs => ProviderRequestData::GetBlockWithTxs(
1216                serde_json::from_value::<GetBlockWithTxsRequest>(raw_request.params)
1217                    .map_err(error_mapper)?,
1218            ),
1219            JsonRpcMethod::GetBlockWithReceipts => ProviderRequestData::GetBlockWithReceipts(
1220                serde_json::from_value::<GetBlockWithReceiptsRequest>(raw_request.params)
1221                    .map_err(error_mapper)?,
1222            ),
1223            JsonRpcMethod::GetStateUpdate => ProviderRequestData::GetStateUpdate(
1224                serde_json::from_value::<GetStateUpdateRequest>(raw_request.params)
1225                    .map_err(error_mapper)?,
1226            ),
1227            JsonRpcMethod::GetStorageAt => ProviderRequestData::GetStorageAt(
1228                serde_json::from_value::<GetStorageAtRequest>(raw_request.params)
1229                    .map_err(error_mapper)?,
1230            ),
1231            JsonRpcMethod::GetMessagesStatus => ProviderRequestData::GetMessagesStatus(
1232                serde_json::from_value::<GetMessagesStatusRequest>(raw_request.params)
1233                    .map_err(error_mapper)?,
1234            ),
1235            JsonRpcMethod::GetTransactionStatus => ProviderRequestData::GetTransactionStatus(
1236                serde_json::from_value::<GetTransactionStatusRequest>(raw_request.params)
1237                    .map_err(error_mapper)?,
1238            ),
1239            JsonRpcMethod::GetTransactionByHash => ProviderRequestData::GetTransactionByHash(
1240                serde_json::from_value::<GetTransactionByHashRequest>(raw_request.params)
1241                    .map_err(error_mapper)?,
1242            ),
1243            JsonRpcMethod::GetTransactionByBlockIdAndIndex => {
1244                ProviderRequestData::GetTransactionByBlockIdAndIndex(
1245                    serde_json::from_value::<GetTransactionByBlockIdAndIndexRequest>(
1246                        raw_request.params,
1247                    )
1248                    .map_err(error_mapper)?,
1249                )
1250            }
1251            JsonRpcMethod::GetTransactionReceipt => ProviderRequestData::GetTransactionReceipt(
1252                serde_json::from_value::<GetTransactionReceiptRequest>(raw_request.params)
1253                    .map_err(error_mapper)?,
1254            ),
1255            JsonRpcMethod::GetClass => ProviderRequestData::GetClass(
1256                serde_json::from_value::<GetClassRequest>(raw_request.params)
1257                    .map_err(error_mapper)?,
1258            ),
1259            JsonRpcMethod::GetClassHashAt => ProviderRequestData::GetClassHashAt(
1260                serde_json::from_value::<GetClassHashAtRequest>(raw_request.params)
1261                    .map_err(error_mapper)?,
1262            ),
1263            JsonRpcMethod::GetClassAt => ProviderRequestData::GetClassAt(
1264                serde_json::from_value::<GetClassAtRequest>(raw_request.params)
1265                    .map_err(error_mapper)?,
1266            ),
1267            JsonRpcMethod::GetBlockTransactionCount => {
1268                ProviderRequestData::GetBlockTransactionCount(
1269                    serde_json::from_value::<GetBlockTransactionCountRequest>(raw_request.params)
1270                        .map_err(error_mapper)?,
1271                )
1272            }
1273            JsonRpcMethod::Call => ProviderRequestData::Call(
1274                serde_json::from_value::<CallRequest>(raw_request.params).map_err(error_mapper)?,
1275            ),
1276            JsonRpcMethod::EstimateFee => ProviderRequestData::EstimateFee(
1277                serde_json::from_value::<EstimateFeeRequest>(raw_request.params)
1278                    .map_err(error_mapper)?,
1279            ),
1280            JsonRpcMethod::EstimateMessageFee => ProviderRequestData::EstimateMessageFee(
1281                serde_json::from_value::<EstimateMessageFeeRequest>(raw_request.params)
1282                    .map_err(error_mapper)?,
1283            ),
1284            JsonRpcMethod::BlockNumber => ProviderRequestData::BlockNumber(
1285                serde_json::from_value::<BlockNumberRequest>(raw_request.params)
1286                    .map_err(error_mapper)?,
1287            ),
1288            JsonRpcMethod::BlockHashAndNumber => ProviderRequestData::BlockHashAndNumber(
1289                serde_json::from_value::<BlockHashAndNumberRequest>(raw_request.params)
1290                    .map_err(error_mapper)?,
1291            ),
1292            JsonRpcMethod::ChainId => ProviderRequestData::ChainId(
1293                serde_json::from_value::<ChainIdRequest>(raw_request.params)
1294                    .map_err(error_mapper)?,
1295            ),
1296            JsonRpcMethod::Syncing => ProviderRequestData::Syncing(
1297                serde_json::from_value::<SyncingRequest>(raw_request.params)
1298                    .map_err(error_mapper)?,
1299            ),
1300            JsonRpcMethod::GetEvents => ProviderRequestData::GetEvents(
1301                serde_json::from_value::<GetEventsRequest>(raw_request.params)
1302                    .map_err(error_mapper)?,
1303            ),
1304            JsonRpcMethod::GetNonce => ProviderRequestData::GetNonce(
1305                serde_json::from_value::<GetNonceRequest>(raw_request.params)
1306                    .map_err(error_mapper)?,
1307            ),
1308            JsonRpcMethod::GetStorageProof => ProviderRequestData::GetStorageProof(
1309                serde_json::from_value::<GetStorageProofRequest>(raw_request.params)
1310                    .map_err(error_mapper)?,
1311            ),
1312            JsonRpcMethod::AddInvokeTransaction => ProviderRequestData::AddInvokeTransaction(
1313                serde_json::from_value::<AddInvokeTransactionRequest>(raw_request.params)
1314                    .map_err(error_mapper)?,
1315            ),
1316            JsonRpcMethod::AddDeclareTransaction => ProviderRequestData::AddDeclareTransaction(
1317                serde_json::from_value::<AddDeclareTransactionRequest>(raw_request.params)
1318                    .map_err(error_mapper)?,
1319            ),
1320            JsonRpcMethod::AddDeployAccountTransaction => {
1321                ProviderRequestData::AddDeployAccountTransaction(
1322                    serde_json::from_value::<AddDeployAccountTransactionRequest>(
1323                        raw_request.params,
1324                    )
1325                    .map_err(error_mapper)?,
1326                )
1327            }
1328            JsonRpcMethod::TraceTransaction => ProviderRequestData::TraceTransaction(
1329                serde_json::from_value::<TraceTransactionRequest>(raw_request.params)
1330                    .map_err(error_mapper)?,
1331            ),
1332            JsonRpcMethod::SimulateTransactions => ProviderRequestData::SimulateTransactions(
1333                serde_json::from_value::<SimulateTransactionsRequest>(raw_request.params)
1334                    .map_err(error_mapper)?,
1335            ),
1336            JsonRpcMethod::TraceBlockTransactions => ProviderRequestData::TraceBlockTransactions(
1337                serde_json::from_value::<TraceBlockTransactionsRequest>(raw_request.params)
1338                    .map_err(error_mapper)?,
1339            ),
1340            JsonRpcMethod::SubscribeNewHeads => ProviderRequestData::SubscribeNewHeads(
1341                serde_json::from_value::<SubscribeNewHeadsRequest>(raw_request.params)
1342                    .map_err(error_mapper)?,
1343            ),
1344            JsonRpcMethod::SubscribeEvents => ProviderRequestData::SubscribeEvents(
1345                serde_json::from_value::<SubscribeEventsRequest>(raw_request.params)
1346                    .map_err(error_mapper)?,
1347            ),
1348            JsonRpcMethod::SubscribeTransactionStatus => {
1349                ProviderRequestData::SubscribeTransactionStatus(
1350                    serde_json::from_value::<SubscribeTransactionStatusRequest>(raw_request.params)
1351                        .map_err(error_mapper)?,
1352                )
1353            }
1354            JsonRpcMethod::SubscribeNewTransactionReceipts => {
1355                ProviderRequestData::SubscribeNewTransactionReceipts(
1356                    serde_json::from_value::<SubscribeNewTransactionReceiptsRequest>(
1357                        raw_request.params,
1358                    )
1359                    .map_err(error_mapper)?,
1360                )
1361            }
1362            JsonRpcMethod::SubscribeNewTransactions => {
1363                ProviderRequestData::SubscribeNewTransactions(
1364                    serde_json::from_value::<SubscribeNewTransactionsRequest>(raw_request.params)
1365                        .map_err(error_mapper)?,
1366                )
1367            }
1368            JsonRpcMethod::Unsubscribe => ProviderRequestData::Unsubscribe(
1369                serde_json::from_value::<UnsubscribeRequest>(raw_request.params)
1370                    .map_err(error_mapper)?,
1371            ),
1372            JsonRpcMethod::SubscriptionNewHeads
1373            | JsonRpcMethod::SubscriptionEvents
1374            | JsonRpcMethod::SubscriptionTransactionStatus
1375            | JsonRpcMethod::SubscriptionNewTransactionReceipts
1376            | JsonRpcMethod::SubscriptionNewTransaction
1377            | JsonRpcMethod::SubscriptionReorg => {
1378                return Err(serde::de::Error::custom(format!(
1379                    "unsupported request method: {:?}",
1380                    raw_request.method
1381                )))
1382            }
1383        };
1384
1385        Ok(Self {
1386            id: raw_request.id,
1387            data: request_data,
1388        })
1389    }
1390}
1391
1392impl Serialize for JsonRpcStreamUpdate {
1393    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1394    where
1395        S: serde::Serializer,
1396    {
1397        #[derive(Serialize)]
1398        struct RawRequest<'a> {
1399            jsonrpc: &'static str,
1400            method: JsonRpcMethod,
1401            params: &'a StreamUpdateData,
1402        }
1403
1404        RawRequest::serialize(
1405            &RawRequest {
1406                jsonrpc: "2.0",
1407                method: self.data.jsonrpc_method(),
1408                params: &self.data,
1409            },
1410            serializer,
1411        )
1412    }
1413}
1414
1415impl<'de> Deserialize<'de> for JsonRpcStreamUpdate {
1416    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1417    where
1418        D: serde::Deserializer<'de>,
1419    {
1420        #[derive(Deserialize)]
1421        struct RawRequest {
1422            method: JsonRpcMethod,
1423            params: serde_json::Value,
1424        }
1425
1426        let error_mapper =
1427            |err| serde::de::Error::custom(format!("unable to decode params: {err}"));
1428
1429        let raw_request = RawRequest::deserialize(deserializer)?;
1430        let request_data = match raw_request.method {
1431            JsonRpcMethod::SubscriptionNewHeads => StreamUpdateData::SubscriptionNewHeads(
1432                serde_json::from_value::<SubscriptionNewHeadsRequest>(raw_request.params)
1433                    .map_err(error_mapper)?,
1434            ),
1435            JsonRpcMethod::SubscriptionEvents => StreamUpdateData::SubscriptionEvents(
1436                serde_json::from_value::<SubscriptionEventsRequest>(raw_request.params)
1437                    .map_err(error_mapper)?,
1438            ),
1439            JsonRpcMethod::SubscriptionTransactionStatus => {
1440                StreamUpdateData::SubscriptionTransactionStatus(
1441                    serde_json::from_value::<SubscriptionTransactionStatusRequest>(
1442                        raw_request.params,
1443                    )
1444                    .map_err(error_mapper)?,
1445                )
1446            }
1447            JsonRpcMethod::SubscriptionNewTransactionReceipts => {
1448                StreamUpdateData::SubscriptionNewTransactionReceipts(
1449                    serde_json::from_value::<SubscriptionNewTransactionReceiptsRequest>(
1450                        raw_request.params,
1451                    )
1452                    .map_err(error_mapper)?,
1453                )
1454            }
1455            JsonRpcMethod::SubscriptionNewTransaction => {
1456                StreamUpdateData::SubscriptionNewTransaction(
1457                    serde_json::from_value::<SubscriptionNewTransactionRequest>(raw_request.params)
1458                        .map_err(error_mapper)?,
1459                )
1460            }
1461            JsonRpcMethod::SubscriptionReorg => StreamUpdateData::SubscriptionReorg(
1462                serde_json::from_value::<SubscriptionReorgRequest>(raw_request.params)
1463                    .map_err(error_mapper)?,
1464            ),
1465            JsonRpcMethod::SpecVersion
1466            | JsonRpcMethod::GetBlockWithTxHashes
1467            | JsonRpcMethod::GetBlockWithTxs
1468            | JsonRpcMethod::GetBlockWithReceipts
1469            | JsonRpcMethod::GetStateUpdate
1470            | JsonRpcMethod::GetStorageAt
1471            | JsonRpcMethod::GetMessagesStatus
1472            | JsonRpcMethod::GetTransactionStatus
1473            | JsonRpcMethod::GetTransactionByHash
1474            | JsonRpcMethod::GetTransactionByBlockIdAndIndex
1475            | JsonRpcMethod::GetTransactionReceipt
1476            | JsonRpcMethod::GetClass
1477            | JsonRpcMethod::GetClassHashAt
1478            | JsonRpcMethod::GetClassAt
1479            | JsonRpcMethod::GetBlockTransactionCount
1480            | JsonRpcMethod::Call
1481            | JsonRpcMethod::EstimateFee
1482            | JsonRpcMethod::EstimateMessageFee
1483            | JsonRpcMethod::BlockNumber
1484            | JsonRpcMethod::BlockHashAndNumber
1485            | JsonRpcMethod::ChainId
1486            | JsonRpcMethod::Syncing
1487            | JsonRpcMethod::GetEvents
1488            | JsonRpcMethod::GetNonce
1489            | JsonRpcMethod::GetStorageProof
1490            | JsonRpcMethod::AddInvokeTransaction
1491            | JsonRpcMethod::AddDeclareTransaction
1492            | JsonRpcMethod::AddDeployAccountTransaction
1493            | JsonRpcMethod::TraceTransaction
1494            | JsonRpcMethod::SimulateTransactions
1495            | JsonRpcMethod::TraceBlockTransactions
1496            | JsonRpcMethod::SubscribeNewHeads
1497            | JsonRpcMethod::SubscribeEvents
1498            | JsonRpcMethod::SubscribeTransactionStatus
1499            | JsonRpcMethod::SubscribeNewTransactionReceipts
1500            | JsonRpcMethod::SubscribeNewTransactions
1501            | JsonRpcMethod::Unsubscribe => {
1502                return Err(serde::de::Error::custom(format!(
1503                    "unsupported request method: {:?}",
1504                    raw_request.method
1505                )))
1506            }
1507        };
1508
1509        Ok(Self { data: request_data })
1510    }
1511}
1512
1513impl<T> ProviderImplError for JsonRpcClientError<T>
1514where
1515    T: 'static + Error + Send + Sync,
1516{
1517    fn as_any(&self) -> &dyn Any {
1518        self
1519    }
1520}
1521
1522impl<T> From<JsonRpcClientError<T>> for ProviderError
1523where
1524    T: 'static + Error + Send + Sync,
1525{
1526    fn from(value: JsonRpcClientError<T>) -> Self {
1527        Self::Other(Box::new(value))
1528    }
1529}
1530
1531impl<T> From<serde_json::Error> for JsonRpcClientError<T> {
1532    fn from(value: serde_json::Error) -> Self {
1533        Self::JsonError(value)
1534    }
1535}
1536
1537impl TryFrom<&JsonRpcError> for StarknetError {
1538    type Error = JsonRpcErrorConversionError;
1539
1540    fn try_from(value: &JsonRpcError) -> Result<Self, Self::Error> {
1541        match value.code {
1542            1 => Ok(Self::FailedToReceiveTransaction),
1543            20 => Ok(Self::ContractNotFound),
1544            21 => Ok(Self::EntrypointNotFound),
1545            24 => Ok(Self::BlockNotFound),
1546            27 => Ok(Self::InvalidTransactionIndex),
1547            28 => Ok(Self::ClassHashNotFound),
1548            29 => Ok(Self::TransactionHashNotFound),
1549            31 => Ok(Self::PageSizeTooBig),
1550            32 => Ok(Self::NoBlocks),
1551            33 => Ok(Self::InvalidContinuationToken),
1552            34 => Ok(Self::TooManyKeysInFilter),
1553            40 => {
1554                let data = ContractErrorData::deserialize(
1555                    value
1556                        .data
1557                        .as_ref()
1558                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1559                )
1560                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1561                Ok(Self::ContractError(data))
1562            }
1563            41 => {
1564                let data = TransactionExecutionErrorData::deserialize(
1565                    value
1566                        .data
1567                        .as_ref()
1568                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1569                )
1570                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1571                Ok(Self::TransactionExecutionError(data))
1572            }
1573            51 => Ok(Self::ClassAlreadyDeclared),
1574            52 => {
1575                let data = String::deserialize(
1576                    value
1577                        .data
1578                        .as_ref()
1579                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1580                )
1581                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1582                Ok(Self::InvalidTransactionNonce(data))
1583            }
1584            53 => Ok(Self::InsufficientResourcesForValidate),
1585            54 => Ok(Self::InsufficientAccountBalance),
1586            55 => {
1587                let data = String::deserialize(
1588                    value
1589                        .data
1590                        .as_ref()
1591                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1592                )
1593                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1594                Ok(Self::ValidationFailure(data))
1595            }
1596            56 => {
1597                let data = String::deserialize(
1598                    value
1599                        .data
1600                        .as_ref()
1601                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1602                )
1603                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1604                Ok(Self::CompilationFailed(data))
1605            }
1606            57 => Ok(Self::ContractClassSizeIsTooLarge),
1607            58 => Ok(Self::NonAccount),
1608            59 => Ok(Self::DuplicateTx),
1609            60 => Ok(Self::CompiledClassHashMismatch),
1610            61 => Ok(Self::UnsupportedTxVersion),
1611            62 => Ok(Self::UnsupportedContractClassVersion),
1612            63 => {
1613                let data = String::deserialize(
1614                    value
1615                        .data
1616                        .as_ref()
1617                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1618                )
1619                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1620                Ok(Self::UnexpectedError(data))
1621            }
1622            64 => Ok(Self::ReplacementTransactionUnderpriced),
1623            65 => Ok(Self::FeeBelowMinimum),
1624            66 => Ok(Self::InvalidSubscriptionId),
1625            67 => Ok(Self::TooManyAddressesInFilter),
1626            68 => Ok(Self::TooManyBlocksBack),
1627            10 => {
1628                let data = NoTraceAvailableErrorData::deserialize(
1629                    value
1630                        .data
1631                        .as_ref()
1632                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1633                )
1634                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1635                Ok(Self::NoTraceAvailable(data))
1636            }
1637            _ => Err(JsonRpcErrorConversionError::UnknownCode),
1638        }
1639    }
1640}
1641
1642impl Error for JsonRpcError {}
1643
1644impl Display for JsonRpcError {
1645    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1646        match &self.data {
1647            Some(data) => {
1648                write!(
1649                    f,
1650                    "JSON-RPC error: code={}, message=\"{}\", data={}",
1651                    self.code,
1652                    self.message,
1653                    serde_json::to_string(data).map_err(|_| std::fmt::Error)?
1654                )
1655            }
1656            None => {
1657                write!(
1658                    f,
1659                    "JSON-RPC error: code={}, message=\"{}\"",
1660                    self.code, self.message
1661                )
1662            }
1663        }
1664    }
1665}