starknet_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_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    /// Get block information with transaction hashes given the block id
553    async fn get_block_with_tx_hashes<B>(
554        &self,
555        block_id: B,
556    ) -> Result<MaybePreConfirmedBlockWithTxHashes, ProviderError>
557    where
558        B: AsRef<BlockId> + Send + Sync,
559    {
560        self.send_request(
561            JsonRpcMethod::GetBlockWithTxHashes,
562            GetBlockWithTxHashesRequestRef {
563                block_id: block_id.as_ref(),
564            },
565        )
566        .await
567    }
568
569    /// Get block information with full transactions given the block id
570    async fn get_block_with_txs<B>(
571        &self,
572        block_id: B,
573    ) -> Result<MaybePreConfirmedBlockWithTxs, ProviderError>
574    where
575        B: AsRef<BlockId> + Send + Sync,
576    {
577        self.send_request(
578            JsonRpcMethod::GetBlockWithTxs,
579            GetBlockWithTxsRequestRef {
580                block_id: block_id.as_ref(),
581            },
582        )
583        .await
584    }
585
586    /// Get block information with full transactions and receipts given the block id
587    async fn get_block_with_receipts<B>(
588        &self,
589        block_id: B,
590    ) -> Result<MaybePreConfirmedBlockWithReceipts, ProviderError>
591    where
592        B: AsRef<BlockId> + Send + Sync,
593    {
594        self.send_request(
595            JsonRpcMethod::GetBlockWithReceipts,
596            GetBlockWithReceiptsRequestRef {
597                block_id: block_id.as_ref(),
598            },
599        )
600        .await
601    }
602
603    /// Get the information about the result of executing the requested block
604    async fn get_state_update<B>(
605        &self,
606        block_id: B,
607    ) -> Result<MaybePreConfirmedStateUpdate, ProviderError>
608    where
609        B: AsRef<BlockId> + Send + Sync,
610    {
611        self.send_request(
612            JsonRpcMethod::GetStateUpdate,
613            GetStateUpdateRequestRef {
614                block_id: block_id.as_ref(),
615            },
616        )
617        .await
618    }
619
620    /// Get the value of the storage at the given address and key
621    async fn get_storage_at<A, K, B>(
622        &self,
623        contract_address: A,
624        key: K,
625        block_id: B,
626    ) -> Result<FeltPrimitive, ProviderError>
627    where
628        A: AsRef<FeltPrimitive> + Send + Sync,
629        K: AsRef<FeltPrimitive> + Send + Sync,
630        B: AsRef<BlockId> + Send + Sync,
631    {
632        Ok(self
633            .send_request::<_, Felt>(
634                JsonRpcMethod::GetStorageAt,
635                GetStorageAtRequestRef {
636                    contract_address: contract_address.as_ref(),
637                    key: key.as_ref(),
638                    block_id: block_id.as_ref(),
639                },
640            )
641            .await?
642            .0)
643    }
644
645    /// Given an l1 tx hash, returns the associated `l1_handler` tx hashes and statuses for all L1 ->
646    /// L2 messages sent by the l1 transaction, ordered by the l1 tx sending order
647    async fn get_messages_status(
648        &self,
649        transaction_hash: Hash256,
650    ) -> Result<Vec<MessageStatus>, ProviderError> {
651        self.send_request(
652            JsonRpcMethod::GetMessagesStatus,
653            GetMessagesStatusRequestRef {
654                transaction_hash: &transaction_hash,
655            },
656        )
657        .await
658    }
659
660    /// Gets the transaction status (possibly reflecting that the tx is still in
661    /// the mempool, or dropped from it)
662    async fn get_transaction_status<H>(
663        &self,
664        transaction_hash: H,
665    ) -> Result<TransactionStatus, ProviderError>
666    where
667        H: AsRef<FeltPrimitive> + Send + Sync,
668    {
669        self.send_request(
670            JsonRpcMethod::GetTransactionStatus,
671            GetTransactionStatusRequestRef {
672                transaction_hash: transaction_hash.as_ref(),
673            },
674        )
675        .await
676    }
677
678    /// Get the details and status of a submitted transaction
679    async fn get_transaction_by_hash<H>(
680        &self,
681        transaction_hash: H,
682    ) -> Result<Transaction, ProviderError>
683    where
684        H: AsRef<FeltPrimitive> + Send + Sync,
685    {
686        self.send_request(
687            JsonRpcMethod::GetTransactionByHash,
688            GetTransactionByHashRequestRef {
689                transaction_hash: transaction_hash.as_ref(),
690            },
691        )
692        .await
693    }
694
695    /// Get the details of a transaction by a given block id and index
696    async fn get_transaction_by_block_id_and_index<B>(
697        &self,
698        block_id: B,
699        index: u64,
700    ) -> Result<Transaction, ProviderError>
701    where
702        B: AsRef<BlockId> + Send + Sync,
703    {
704        self.send_request(
705            JsonRpcMethod::GetTransactionByBlockIdAndIndex,
706            GetTransactionByBlockIdAndIndexRequestRef {
707                block_id: block_id.as_ref(),
708                index: &index,
709            },
710        )
711        .await
712    }
713
714    /// Get the details of a transaction by a given block number and index
715    async fn get_transaction_receipt<H>(
716        &self,
717        transaction_hash: H,
718    ) -> Result<TransactionReceiptWithBlockInfo, ProviderError>
719    where
720        H: AsRef<FeltPrimitive> + Send + Sync,
721    {
722        self.send_request(
723            JsonRpcMethod::GetTransactionReceipt,
724            GetTransactionReceiptRequestRef {
725                transaction_hash: transaction_hash.as_ref(),
726            },
727        )
728        .await
729    }
730
731    /// Get the contract class definition in the given block associated with the given hash
732    async fn get_class<B, H>(
733        &self,
734        block_id: B,
735        class_hash: H,
736    ) -> Result<ContractClass, ProviderError>
737    where
738        B: AsRef<BlockId> + Send + Sync,
739        H: AsRef<FeltPrimitive> + Send + Sync,
740    {
741        self.send_request(
742            JsonRpcMethod::GetClass,
743            GetClassRequestRef {
744                block_id: block_id.as_ref(),
745                class_hash: class_hash.as_ref(),
746            },
747        )
748        .await
749    }
750
751    /// Get the contract class hash in the given block for the contract deployed at the given address
752    async fn get_class_hash_at<B, A>(
753        &self,
754        block_id: B,
755        contract_address: A,
756    ) -> Result<FeltPrimitive, ProviderError>
757    where
758        B: AsRef<BlockId> + Send + Sync,
759        A: AsRef<FeltPrimitive> + Send + Sync,
760    {
761        Ok(self
762            .send_request::<_, Felt>(
763                JsonRpcMethod::GetClassHashAt,
764                GetClassHashAtRequestRef {
765                    block_id: block_id.as_ref(),
766                    contract_address: contract_address.as_ref(),
767                },
768            )
769            .await?
770            .0)
771    }
772
773    /// Get the contract class definition in the given block at the given address
774    async fn get_class_at<B, A>(
775        &self,
776        block_id: B,
777        contract_address: A,
778    ) -> Result<ContractClass, ProviderError>
779    where
780        B: AsRef<BlockId> + Send + Sync,
781        A: AsRef<FeltPrimitive> + Send + Sync,
782    {
783        self.send_request(
784            JsonRpcMethod::GetClassAt,
785            GetClassAtRequestRef {
786                block_id: block_id.as_ref(),
787                contract_address: contract_address.as_ref(),
788            },
789        )
790        .await
791    }
792
793    /// Get the number of transactions in a block given a block id
794    async fn get_block_transaction_count<B>(&self, block_id: B) -> Result<u64, ProviderError>
795    where
796        B: AsRef<BlockId> + Send + Sync,
797    {
798        self.send_request(
799            JsonRpcMethod::GetBlockTransactionCount,
800            GetBlockTransactionCountRequestRef {
801                block_id: block_id.as_ref(),
802            },
803        )
804        .await
805    }
806
807    /// Call a starknet function without creating a Starknet transaction
808    async fn call<R, B>(&self, request: R, block_id: B) -> Result<Vec<FeltPrimitive>, ProviderError>
809    where
810        R: AsRef<FunctionCall> + Send + Sync,
811        B: AsRef<BlockId> + Send + Sync,
812    {
813        Ok(self
814            .send_request::<_, FeltArray>(
815                JsonRpcMethod::Call,
816                CallRequestRef {
817                    request: request.as_ref(),
818                    block_id: block_id.as_ref(),
819                },
820            )
821            .await?
822            .0)
823    }
824
825    /// Estimate the fee for a given Starknet transaction
826    async fn estimate_fee<R, S, B>(
827        &self,
828        request: R,
829        simulation_flags: S,
830        block_id: B,
831    ) -> Result<Vec<FeeEstimate>, ProviderError>
832    where
833        R: AsRef<[BroadcastedTransaction]> + Send + Sync,
834        S: AsRef<[SimulationFlagForEstimateFee]> + Send + Sync,
835        B: AsRef<BlockId> + Send + Sync,
836    {
837        self.send_request(
838            JsonRpcMethod::EstimateFee,
839            EstimateFeeRequestRef {
840                request: request.as_ref(),
841                simulation_flags: simulation_flags.as_ref(),
842                block_id: block_id.as_ref(),
843            },
844        )
845        .await
846    }
847
848    /// Estimate the L2 fee of a message sent on L1
849    async fn estimate_message_fee<M, B>(
850        &self,
851        message: M,
852        block_id: B,
853    ) -> Result<MessageFeeEstimate, ProviderError>
854    where
855        M: AsRef<MsgFromL1> + Send + Sync,
856        B: AsRef<BlockId> + Send + Sync,
857    {
858        self.send_request(
859            JsonRpcMethod::EstimateMessageFee,
860            EstimateMessageFeeRequestRef {
861                message: message.as_ref(),
862                block_id: block_id.as_ref(),
863            },
864        )
865        .await
866    }
867
868    /// Get the most recent accepted block number
869    async fn block_number(&self) -> Result<u64, ProviderError> {
870        self.send_request(JsonRpcMethod::BlockNumber, BlockNumberRequest)
871            .await
872    }
873
874    /// Get the most recent accepted block hash and number
875    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError> {
876        self.send_request(JsonRpcMethod::BlockHashAndNumber, BlockHashAndNumberRequest)
877            .await
878    }
879
880    /// Return the currently configured Starknet chain id
881    async fn chain_id(&self) -> Result<FeltPrimitive, ProviderError> {
882        Ok(self
883            .send_request::<_, Felt>(JsonRpcMethod::ChainId, ChainIdRequest)
884            .await?
885            .0)
886    }
887
888    /// Returns an object about the sync status, or false if the node is not synching
889    async fn syncing(&self) -> Result<SyncStatusType, ProviderError> {
890        self.send_request(JsonRpcMethod::Syncing, SyncingRequest)
891            .await
892    }
893
894    /// Returns all events matching the given filter
895    async fn get_events(
896        &self,
897        filter: EventFilter,
898        continuation_token: Option<String>,
899        chunk_size: u64,
900    ) -> Result<EventsPage, ProviderError> {
901        self.send_request(
902            JsonRpcMethod::GetEvents,
903            GetEventsRequestRef {
904                filter: &EventFilterWithPage {
905                    event_filter: filter,
906                    result_page_request: ResultPageRequest {
907                        continuation_token,
908                        chunk_size,
909                    },
910                },
911            },
912        )
913        .await
914    }
915
916    /// Get the nonce associated with the given address in the given block
917    async fn get_nonce<B, A>(
918        &self,
919        block_id: B,
920        contract_address: A,
921    ) -> Result<FeltPrimitive, ProviderError>
922    where
923        B: AsRef<BlockId> + Send + Sync,
924        A: AsRef<FeltPrimitive> + Send + Sync,
925    {
926        Ok(self
927            .send_request::<_, Felt>(
928                JsonRpcMethod::GetNonce,
929                GetNonceRequestRef {
930                    block_id: block_id.as_ref(),
931                    contract_address: contract_address.as_ref(),
932                },
933            )
934            .await?
935            .0)
936    }
937
938    /// Get merkle paths in one of the state tries: global state, classes, individual contract.
939    /// A single request can query for any mix of the three types of storage proofs (classes,
940    /// contracts, and storage).
941    async fn get_storage_proof<B, H, A, K>(
942        &self,
943        block_id: B,
944        class_hashes: H,
945        contract_addresses: A,
946        contracts_storage_keys: K,
947    ) -> Result<StorageProof, ProviderError>
948    where
949        B: AsRef<ConfirmedBlockId> + Send + Sync,
950        H: AsRef<[FeltPrimitive]> + Send + Sync,
951        A: AsRef<[FeltPrimitive]> + Send + Sync,
952        K: AsRef<[ContractStorageKeys]> + Send + Sync,
953    {
954        self.send_request(
955            JsonRpcMethod::GetStorageProof,
956            GetStorageProofRequestRef {
957                block_id: block_id.as_ref(),
958                class_hashes: Some(class_hashes.as_ref()),
959                contract_addresses: Some(contract_addresses.as_ref()),
960                contracts_storage_keys: Some(contracts_storage_keys.as_ref()),
961            },
962        )
963        .await
964    }
965
966    /// Submit a new transaction to be added to the chain
967    async fn add_invoke_transaction<I>(
968        &self,
969        invoke_transaction: I,
970    ) -> Result<InvokeTransactionResult, ProviderError>
971    where
972        I: AsRef<BroadcastedInvokeTransaction> + Send + Sync,
973    {
974        self.send_request(
975            JsonRpcMethod::AddInvokeTransaction,
976            AddInvokeTransactionRequestRef {
977                invoke_transaction: invoke_transaction.as_ref(),
978            },
979        )
980        .await
981    }
982
983    /// Submit a new transaction to be added to the chain
984    async fn add_declare_transaction<D>(
985        &self,
986        declare_transaction: D,
987    ) -> Result<DeclareTransactionResult, ProviderError>
988    where
989        D: AsRef<BroadcastedDeclareTransaction> + Send + Sync,
990    {
991        self.send_request(
992            JsonRpcMethod::AddDeclareTransaction,
993            AddDeclareTransactionRequestRef {
994                declare_transaction: declare_transaction.as_ref(),
995            },
996        )
997        .await
998    }
999
1000    /// Submit a new deploy account transaction
1001    async fn add_deploy_account_transaction<D>(
1002        &self,
1003        deploy_account_transaction: D,
1004    ) -> Result<DeployAccountTransactionResult, ProviderError>
1005    where
1006        D: AsRef<BroadcastedDeployAccountTransaction> + Send + Sync,
1007    {
1008        self.send_request(
1009            JsonRpcMethod::AddDeployAccountTransaction,
1010            AddDeployAccountTransactionRequestRef {
1011                deploy_account_transaction: deploy_account_transaction.as_ref(),
1012            },
1013        )
1014        .await
1015    }
1016
1017    /// For a given executed transaction, return the trace of its execution, including internal
1018    /// calls
1019    async fn trace_transaction<H>(
1020        &self,
1021        transaction_hash: H,
1022    ) -> Result<TransactionTrace, ProviderError>
1023    where
1024        H: AsRef<FeltPrimitive> + Send + Sync,
1025    {
1026        self.send_request(
1027            JsonRpcMethod::TraceTransaction,
1028            TraceTransactionRequestRef {
1029                transaction_hash: transaction_hash.as_ref(),
1030            },
1031        )
1032        .await
1033    }
1034
1035    /// Simulate a given sequence of transactions on the requested state, and generate the execution
1036    /// traces. Note that some of the transactions may revert, in which case no error is thrown, but
1037    /// revert details can be seen on the returned trace object. . Note that some of the
1038    /// transactions may revert, this will be reflected by the `revert_error` property in the trace.
1039    /// Other types of failures (e.g. unexpected error or failure in the validation phase) will
1040    /// result in `TRANSACTION_EXECUTION_ERROR`.
1041    async fn simulate_transactions<B, TX, S>(
1042        &self,
1043        block_id: B,
1044        transactions: TX,
1045        simulation_flags: S,
1046    ) -> Result<Vec<SimulatedTransaction>, ProviderError>
1047    where
1048        B: AsRef<BlockId> + Send + Sync,
1049        TX: AsRef<[BroadcastedTransaction]> + Send + Sync,
1050        S: AsRef<[SimulationFlag]> + Send + Sync,
1051    {
1052        self.send_request(
1053            JsonRpcMethod::SimulateTransactions,
1054            SimulateTransactionsRequestRef {
1055                block_id: block_id.as_ref(),
1056                transactions: transactions.as_ref(),
1057                simulation_flags: simulation_flags.as_ref(),
1058            },
1059        )
1060        .await
1061    }
1062
1063    /// Retrieve traces for all transactions in the given block.
1064    async fn trace_block_transactions<B>(
1065        &self,
1066        block_id: B,
1067    ) -> Result<Vec<TransactionTraceWithHash>, ProviderError>
1068    where
1069        B: AsRef<ConfirmedBlockId> + Send + Sync,
1070    {
1071        self.send_request(
1072            JsonRpcMethod::TraceBlockTransactions,
1073            TraceBlockTransactionsRequestRef {
1074                block_id: block_id.as_ref(),
1075            },
1076        )
1077        .await
1078    }
1079
1080    async fn batch_requests<R>(
1081        &self,
1082        requests: R,
1083    ) -> Result<Vec<ProviderResponseData>, ProviderError>
1084    where
1085        R: AsRef<[ProviderRequestData]> + Send + Sync,
1086    {
1087        self.send_requests(requests).await
1088    }
1089}
1090
1091impl ProviderRequestData {
1092    const fn jsonrpc_method(&self) -> JsonRpcMethod {
1093        match self {
1094            Self::SpecVersion(_) => JsonRpcMethod::SpecVersion,
1095            Self::GetBlockWithTxHashes(_) => JsonRpcMethod::GetBlockWithTxHashes,
1096            Self::GetBlockWithTxs(_) => JsonRpcMethod::GetBlockWithTxs,
1097            Self::GetBlockWithReceipts(_) => JsonRpcMethod::GetBlockWithReceipts,
1098            Self::GetStateUpdate(_) => JsonRpcMethod::GetStateUpdate,
1099            Self::GetStorageAt(_) => JsonRpcMethod::GetStorageAt,
1100            Self::GetMessagesStatus(_) => JsonRpcMethod::GetMessagesStatus,
1101            Self::GetTransactionStatus(_) => JsonRpcMethod::GetTransactionStatus,
1102            Self::GetTransactionByHash(_) => JsonRpcMethod::GetTransactionByHash,
1103            Self::GetTransactionByBlockIdAndIndex(_) => {
1104                JsonRpcMethod::GetTransactionByBlockIdAndIndex
1105            }
1106            Self::GetTransactionReceipt(_) => JsonRpcMethod::GetTransactionReceipt,
1107            Self::GetClass(_) => JsonRpcMethod::GetClass,
1108            Self::GetClassHashAt(_) => JsonRpcMethod::GetClassHashAt,
1109            Self::GetClassAt(_) => JsonRpcMethod::GetClassAt,
1110            Self::GetBlockTransactionCount(_) => JsonRpcMethod::GetBlockTransactionCount,
1111            Self::Call(_) => JsonRpcMethod::Call,
1112            Self::EstimateFee(_) => JsonRpcMethod::EstimateFee,
1113            Self::EstimateMessageFee(_) => JsonRpcMethod::EstimateMessageFee,
1114            Self::BlockNumber(_) => JsonRpcMethod::BlockNumber,
1115            Self::BlockHashAndNumber(_) => JsonRpcMethod::BlockHashAndNumber,
1116            Self::ChainId(_) => JsonRpcMethod::ChainId,
1117            Self::Syncing(_) => JsonRpcMethod::Syncing,
1118            Self::GetEvents(_) => JsonRpcMethod::GetEvents,
1119            Self::GetNonce(_) => JsonRpcMethod::GetNonce,
1120            Self::GetStorageProof(_) => JsonRpcMethod::GetStorageProof,
1121            Self::AddInvokeTransaction(_) => JsonRpcMethod::AddInvokeTransaction,
1122            Self::AddDeclareTransaction(_) => JsonRpcMethod::AddDeclareTransaction,
1123            Self::AddDeployAccountTransaction(_) => JsonRpcMethod::AddDeployAccountTransaction,
1124            Self::TraceTransaction(_) => JsonRpcMethod::TraceTransaction,
1125            Self::SimulateTransactions(_) => JsonRpcMethod::SimulateTransactions,
1126            Self::TraceBlockTransactions(_) => JsonRpcMethod::TraceBlockTransactions,
1127            Self::SubscribeNewHeads(_) => JsonRpcMethod::SubscribeNewHeads,
1128            Self::SubscribeEvents(_) => JsonRpcMethod::SubscribeEvents,
1129            Self::SubscribeTransactionStatus(_) => JsonRpcMethod::SubscribeTransactionStatus,
1130            Self::SubscribeNewTransactionReceipts(_) => {
1131                JsonRpcMethod::SubscribeNewTransactionReceipts
1132            }
1133            Self::SubscribeNewTransactions(_) => JsonRpcMethod::SubscribeNewTransactions,
1134            Self::Unsubscribe(_) => JsonRpcMethod::Unsubscribe,
1135        }
1136    }
1137}
1138
1139impl StreamUpdateData {
1140    const fn jsonrpc_method(&self) -> JsonRpcMethod {
1141        match self {
1142            Self::SubscriptionNewHeads(_) => JsonRpcMethod::SubscriptionNewHeads,
1143            Self::SubscriptionEvents(_) => JsonRpcMethod::SubscriptionEvents,
1144            Self::SubscriptionTransactionStatus(_) => JsonRpcMethod::SubscriptionTransactionStatus,
1145            Self::SubscriptionNewTransactionReceipts(_) => {
1146                JsonRpcMethod::SubscriptionNewTransactionReceipts
1147            }
1148            Self::SubscriptionNewTransaction(_) => JsonRpcMethod::SubscriptionNewTransaction,
1149            Self::SubscriptionReorg(_) => JsonRpcMethod::SubscriptionReorg,
1150        }
1151    }
1152}
1153
1154impl Serialize for JsonRpcRequest {
1155    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1156    where
1157        S: serde::Serializer,
1158    {
1159        #[derive(Serialize)]
1160        struct RawRequest<'a> {
1161            jsonrpc: &'static str,
1162            id: u64,
1163            method: JsonRpcMethod,
1164            params: &'a ProviderRequestData,
1165        }
1166
1167        RawRequest::serialize(
1168            &RawRequest {
1169                jsonrpc: "2.0",
1170                id: self.id,
1171                method: self.data.jsonrpc_method(),
1172                params: &self.data,
1173            },
1174            serializer,
1175        )
1176    }
1177}
1178
1179impl<'de> Deserialize<'de> for JsonRpcRequest {
1180    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1181    where
1182        D: serde::Deserializer<'de>,
1183    {
1184        #[derive(Deserialize)]
1185        struct RawRequest {
1186            id: u64,
1187            method: JsonRpcMethod,
1188            params: serde_json::Value,
1189        }
1190
1191        let error_mapper =
1192            |err| serde::de::Error::custom(format!("unable to decode params: {err}"));
1193
1194        let raw_request = RawRequest::deserialize(deserializer)?;
1195        let request_data = match raw_request.method {
1196            JsonRpcMethod::SpecVersion => ProviderRequestData::SpecVersion(
1197                serde_json::from_value::<SpecVersionRequest>(raw_request.params)
1198                    .map_err(error_mapper)?,
1199            ),
1200            JsonRpcMethod::GetBlockWithTxHashes => ProviderRequestData::GetBlockWithTxHashes(
1201                serde_json::from_value::<GetBlockWithTxHashesRequest>(raw_request.params)
1202                    .map_err(error_mapper)?,
1203            ),
1204            JsonRpcMethod::GetBlockWithTxs => ProviderRequestData::GetBlockWithTxs(
1205                serde_json::from_value::<GetBlockWithTxsRequest>(raw_request.params)
1206                    .map_err(error_mapper)?,
1207            ),
1208            JsonRpcMethod::GetBlockWithReceipts => ProviderRequestData::GetBlockWithReceipts(
1209                serde_json::from_value::<GetBlockWithReceiptsRequest>(raw_request.params)
1210                    .map_err(error_mapper)?,
1211            ),
1212            JsonRpcMethod::GetStateUpdate => ProviderRequestData::GetStateUpdate(
1213                serde_json::from_value::<GetStateUpdateRequest>(raw_request.params)
1214                    .map_err(error_mapper)?,
1215            ),
1216            JsonRpcMethod::GetStorageAt => ProviderRequestData::GetStorageAt(
1217                serde_json::from_value::<GetStorageAtRequest>(raw_request.params)
1218                    .map_err(error_mapper)?,
1219            ),
1220            JsonRpcMethod::GetMessagesStatus => ProviderRequestData::GetMessagesStatus(
1221                serde_json::from_value::<GetMessagesStatusRequest>(raw_request.params)
1222                    .map_err(error_mapper)?,
1223            ),
1224            JsonRpcMethod::GetTransactionStatus => ProviderRequestData::GetTransactionStatus(
1225                serde_json::from_value::<GetTransactionStatusRequest>(raw_request.params)
1226                    .map_err(error_mapper)?,
1227            ),
1228            JsonRpcMethod::GetTransactionByHash => ProviderRequestData::GetTransactionByHash(
1229                serde_json::from_value::<GetTransactionByHashRequest>(raw_request.params)
1230                    .map_err(error_mapper)?,
1231            ),
1232            JsonRpcMethod::GetTransactionByBlockIdAndIndex => {
1233                ProviderRequestData::GetTransactionByBlockIdAndIndex(
1234                    serde_json::from_value::<GetTransactionByBlockIdAndIndexRequest>(
1235                        raw_request.params,
1236                    )
1237                    .map_err(error_mapper)?,
1238                )
1239            }
1240            JsonRpcMethod::GetTransactionReceipt => ProviderRequestData::GetTransactionReceipt(
1241                serde_json::from_value::<GetTransactionReceiptRequest>(raw_request.params)
1242                    .map_err(error_mapper)?,
1243            ),
1244            JsonRpcMethod::GetClass => ProviderRequestData::GetClass(
1245                serde_json::from_value::<GetClassRequest>(raw_request.params)
1246                    .map_err(error_mapper)?,
1247            ),
1248            JsonRpcMethod::GetClassHashAt => ProviderRequestData::GetClassHashAt(
1249                serde_json::from_value::<GetClassHashAtRequest>(raw_request.params)
1250                    .map_err(error_mapper)?,
1251            ),
1252            JsonRpcMethod::GetClassAt => ProviderRequestData::GetClassAt(
1253                serde_json::from_value::<GetClassAtRequest>(raw_request.params)
1254                    .map_err(error_mapper)?,
1255            ),
1256            JsonRpcMethod::GetBlockTransactionCount => {
1257                ProviderRequestData::GetBlockTransactionCount(
1258                    serde_json::from_value::<GetBlockTransactionCountRequest>(raw_request.params)
1259                        .map_err(error_mapper)?,
1260                )
1261            }
1262            JsonRpcMethod::Call => ProviderRequestData::Call(
1263                serde_json::from_value::<CallRequest>(raw_request.params).map_err(error_mapper)?,
1264            ),
1265            JsonRpcMethod::EstimateFee => ProviderRequestData::EstimateFee(
1266                serde_json::from_value::<EstimateFeeRequest>(raw_request.params)
1267                    .map_err(error_mapper)?,
1268            ),
1269            JsonRpcMethod::EstimateMessageFee => ProviderRequestData::EstimateMessageFee(
1270                serde_json::from_value::<EstimateMessageFeeRequest>(raw_request.params)
1271                    .map_err(error_mapper)?,
1272            ),
1273            JsonRpcMethod::BlockNumber => ProviderRequestData::BlockNumber(
1274                serde_json::from_value::<BlockNumberRequest>(raw_request.params)
1275                    .map_err(error_mapper)?,
1276            ),
1277            JsonRpcMethod::BlockHashAndNumber => ProviderRequestData::BlockHashAndNumber(
1278                serde_json::from_value::<BlockHashAndNumberRequest>(raw_request.params)
1279                    .map_err(error_mapper)?,
1280            ),
1281            JsonRpcMethod::ChainId => ProviderRequestData::ChainId(
1282                serde_json::from_value::<ChainIdRequest>(raw_request.params)
1283                    .map_err(error_mapper)?,
1284            ),
1285            JsonRpcMethod::Syncing => ProviderRequestData::Syncing(
1286                serde_json::from_value::<SyncingRequest>(raw_request.params)
1287                    .map_err(error_mapper)?,
1288            ),
1289            JsonRpcMethod::GetEvents => ProviderRequestData::GetEvents(
1290                serde_json::from_value::<GetEventsRequest>(raw_request.params)
1291                    .map_err(error_mapper)?,
1292            ),
1293            JsonRpcMethod::GetNonce => ProviderRequestData::GetNonce(
1294                serde_json::from_value::<GetNonceRequest>(raw_request.params)
1295                    .map_err(error_mapper)?,
1296            ),
1297            JsonRpcMethod::GetStorageProof => ProviderRequestData::GetStorageProof(
1298                serde_json::from_value::<GetStorageProofRequest>(raw_request.params)
1299                    .map_err(error_mapper)?,
1300            ),
1301            JsonRpcMethod::AddInvokeTransaction => ProviderRequestData::AddInvokeTransaction(
1302                serde_json::from_value::<AddInvokeTransactionRequest>(raw_request.params)
1303                    .map_err(error_mapper)?,
1304            ),
1305            JsonRpcMethod::AddDeclareTransaction => ProviderRequestData::AddDeclareTransaction(
1306                serde_json::from_value::<AddDeclareTransactionRequest>(raw_request.params)
1307                    .map_err(error_mapper)?,
1308            ),
1309            JsonRpcMethod::AddDeployAccountTransaction => {
1310                ProviderRequestData::AddDeployAccountTransaction(
1311                    serde_json::from_value::<AddDeployAccountTransactionRequest>(
1312                        raw_request.params,
1313                    )
1314                    .map_err(error_mapper)?,
1315                )
1316            }
1317            JsonRpcMethod::TraceTransaction => ProviderRequestData::TraceTransaction(
1318                serde_json::from_value::<TraceTransactionRequest>(raw_request.params)
1319                    .map_err(error_mapper)?,
1320            ),
1321            JsonRpcMethod::SimulateTransactions => ProviderRequestData::SimulateTransactions(
1322                serde_json::from_value::<SimulateTransactionsRequest>(raw_request.params)
1323                    .map_err(error_mapper)?,
1324            ),
1325            JsonRpcMethod::TraceBlockTransactions => ProviderRequestData::TraceBlockTransactions(
1326                serde_json::from_value::<TraceBlockTransactionsRequest>(raw_request.params)
1327                    .map_err(error_mapper)?,
1328            ),
1329            JsonRpcMethod::SubscribeNewHeads => ProviderRequestData::SubscribeNewHeads(
1330                serde_json::from_value::<SubscribeNewHeadsRequest>(raw_request.params)
1331                    .map_err(error_mapper)?,
1332            ),
1333            JsonRpcMethod::SubscribeEvents => ProviderRequestData::SubscribeEvents(
1334                serde_json::from_value::<SubscribeEventsRequest>(raw_request.params)
1335                    .map_err(error_mapper)?,
1336            ),
1337            JsonRpcMethod::SubscribeTransactionStatus => {
1338                ProviderRequestData::SubscribeTransactionStatus(
1339                    serde_json::from_value::<SubscribeTransactionStatusRequest>(raw_request.params)
1340                        .map_err(error_mapper)?,
1341                )
1342            }
1343            JsonRpcMethod::SubscribeNewTransactionReceipts => {
1344                ProviderRequestData::SubscribeNewTransactionReceipts(
1345                    serde_json::from_value::<SubscribeNewTransactionReceiptsRequest>(
1346                        raw_request.params,
1347                    )
1348                    .map_err(error_mapper)?,
1349                )
1350            }
1351            JsonRpcMethod::SubscribeNewTransactions => {
1352                ProviderRequestData::SubscribeNewTransactions(
1353                    serde_json::from_value::<SubscribeNewTransactionsRequest>(raw_request.params)
1354                        .map_err(error_mapper)?,
1355                )
1356            }
1357            JsonRpcMethod::Unsubscribe => ProviderRequestData::Unsubscribe(
1358                serde_json::from_value::<UnsubscribeRequest>(raw_request.params)
1359                    .map_err(error_mapper)?,
1360            ),
1361            JsonRpcMethod::SubscriptionNewHeads
1362            | JsonRpcMethod::SubscriptionEvents
1363            | JsonRpcMethod::SubscriptionTransactionStatus
1364            | JsonRpcMethod::SubscriptionNewTransactionReceipts
1365            | JsonRpcMethod::SubscriptionNewTransaction
1366            | JsonRpcMethod::SubscriptionReorg => {
1367                return Err(serde::de::Error::custom(format!(
1368                    "unsupported request method: {:?}",
1369                    raw_request.method
1370                )))
1371            }
1372        };
1373
1374        Ok(Self {
1375            id: raw_request.id,
1376            data: request_data,
1377        })
1378    }
1379}
1380
1381impl Serialize for JsonRpcStreamUpdate {
1382    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1383    where
1384        S: serde::Serializer,
1385    {
1386        #[derive(Serialize)]
1387        struct RawRequest<'a> {
1388            jsonrpc: &'static str,
1389            method: JsonRpcMethod,
1390            params: &'a StreamUpdateData,
1391        }
1392
1393        RawRequest::serialize(
1394            &RawRequest {
1395                jsonrpc: "2.0",
1396                method: self.data.jsonrpc_method(),
1397                params: &self.data,
1398            },
1399            serializer,
1400        )
1401    }
1402}
1403
1404impl<'de> Deserialize<'de> for JsonRpcStreamUpdate {
1405    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1406    where
1407        D: serde::Deserializer<'de>,
1408    {
1409        #[derive(Deserialize)]
1410        struct RawRequest {
1411            method: JsonRpcMethod,
1412            params: serde_json::Value,
1413        }
1414
1415        let error_mapper =
1416            |err| serde::de::Error::custom(format!("unable to decode params: {err}"));
1417
1418        let raw_request = RawRequest::deserialize(deserializer)?;
1419        let request_data = match raw_request.method {
1420            JsonRpcMethod::SubscriptionNewHeads => StreamUpdateData::SubscriptionNewHeads(
1421                serde_json::from_value::<SubscriptionNewHeadsRequest>(raw_request.params)
1422                    .map_err(error_mapper)?,
1423            ),
1424            JsonRpcMethod::SubscriptionEvents => StreamUpdateData::SubscriptionEvents(
1425                serde_json::from_value::<SubscriptionEventsRequest>(raw_request.params)
1426                    .map_err(error_mapper)?,
1427            ),
1428            JsonRpcMethod::SubscriptionTransactionStatus => {
1429                StreamUpdateData::SubscriptionTransactionStatus(
1430                    serde_json::from_value::<SubscriptionTransactionStatusRequest>(
1431                        raw_request.params,
1432                    )
1433                    .map_err(error_mapper)?,
1434                )
1435            }
1436            JsonRpcMethod::SubscriptionNewTransactionReceipts => {
1437                StreamUpdateData::SubscriptionNewTransactionReceipts(
1438                    serde_json::from_value::<SubscriptionNewTransactionReceiptsRequest>(
1439                        raw_request.params,
1440                    )
1441                    .map_err(error_mapper)?,
1442                )
1443            }
1444            JsonRpcMethod::SubscriptionNewTransaction => {
1445                StreamUpdateData::SubscriptionNewTransaction(
1446                    serde_json::from_value::<SubscriptionNewTransactionRequest>(raw_request.params)
1447                        .map_err(error_mapper)?,
1448                )
1449            }
1450            JsonRpcMethod::SubscriptionReorg => StreamUpdateData::SubscriptionReorg(
1451                serde_json::from_value::<SubscriptionReorgRequest>(raw_request.params)
1452                    .map_err(error_mapper)?,
1453            ),
1454            JsonRpcMethod::SpecVersion
1455            | JsonRpcMethod::GetBlockWithTxHashes
1456            | JsonRpcMethod::GetBlockWithTxs
1457            | JsonRpcMethod::GetBlockWithReceipts
1458            | JsonRpcMethod::GetStateUpdate
1459            | JsonRpcMethod::GetStorageAt
1460            | JsonRpcMethod::GetMessagesStatus
1461            | JsonRpcMethod::GetTransactionStatus
1462            | JsonRpcMethod::GetTransactionByHash
1463            | JsonRpcMethod::GetTransactionByBlockIdAndIndex
1464            | JsonRpcMethod::GetTransactionReceipt
1465            | JsonRpcMethod::GetClass
1466            | JsonRpcMethod::GetClassHashAt
1467            | JsonRpcMethod::GetClassAt
1468            | JsonRpcMethod::GetBlockTransactionCount
1469            | JsonRpcMethod::Call
1470            | JsonRpcMethod::EstimateFee
1471            | JsonRpcMethod::EstimateMessageFee
1472            | JsonRpcMethod::BlockNumber
1473            | JsonRpcMethod::BlockHashAndNumber
1474            | JsonRpcMethod::ChainId
1475            | JsonRpcMethod::Syncing
1476            | JsonRpcMethod::GetEvents
1477            | JsonRpcMethod::GetNonce
1478            | JsonRpcMethod::GetStorageProof
1479            | JsonRpcMethod::AddInvokeTransaction
1480            | JsonRpcMethod::AddDeclareTransaction
1481            | JsonRpcMethod::AddDeployAccountTransaction
1482            | JsonRpcMethod::TraceTransaction
1483            | JsonRpcMethod::SimulateTransactions
1484            | JsonRpcMethod::TraceBlockTransactions
1485            | JsonRpcMethod::SubscribeNewHeads
1486            | JsonRpcMethod::SubscribeEvents
1487            | JsonRpcMethod::SubscribeTransactionStatus
1488            | JsonRpcMethod::SubscribeNewTransactionReceipts
1489            | JsonRpcMethod::SubscribeNewTransactions
1490            | JsonRpcMethod::Unsubscribe => {
1491                return Err(serde::de::Error::custom(format!(
1492                    "unsupported request method: {:?}",
1493                    raw_request.method
1494                )))
1495            }
1496        };
1497
1498        Ok(Self { data: request_data })
1499    }
1500}
1501
1502impl<T> ProviderImplError for JsonRpcClientError<T>
1503where
1504    T: 'static + Error + Send + Sync,
1505{
1506    fn as_any(&self) -> &dyn Any {
1507        self
1508    }
1509}
1510
1511impl<T> From<JsonRpcClientError<T>> for ProviderError
1512where
1513    T: 'static + Error + Send + Sync,
1514{
1515    fn from(value: JsonRpcClientError<T>) -> Self {
1516        Self::Other(Box::new(value))
1517    }
1518}
1519
1520impl<T> From<serde_json::Error> for JsonRpcClientError<T> {
1521    fn from(value: serde_json::Error) -> Self {
1522        Self::JsonError(value)
1523    }
1524}
1525
1526impl TryFrom<&JsonRpcError> for StarknetError {
1527    type Error = JsonRpcErrorConversionError;
1528
1529    fn try_from(value: &JsonRpcError) -> Result<Self, Self::Error> {
1530        match value.code {
1531            1 => Ok(Self::FailedToReceiveTransaction),
1532            20 => Ok(Self::ContractNotFound),
1533            21 => Ok(Self::EntrypointNotFound),
1534            24 => Ok(Self::BlockNotFound),
1535            27 => Ok(Self::InvalidTransactionIndex),
1536            28 => Ok(Self::ClassHashNotFound),
1537            29 => Ok(Self::TransactionHashNotFound),
1538            31 => Ok(Self::PageSizeTooBig),
1539            32 => Ok(Self::NoBlocks),
1540            33 => Ok(Self::InvalidContinuationToken),
1541            34 => Ok(Self::TooManyKeysInFilter),
1542            40 => {
1543                let data = ContractErrorData::deserialize(
1544                    value
1545                        .data
1546                        .as_ref()
1547                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1548                )
1549                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1550                Ok(Self::ContractError(data))
1551            }
1552            41 => {
1553                let data = TransactionExecutionErrorData::deserialize(
1554                    value
1555                        .data
1556                        .as_ref()
1557                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1558                )
1559                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1560                Ok(Self::TransactionExecutionError(data))
1561            }
1562            51 => Ok(Self::ClassAlreadyDeclared),
1563            52 => {
1564                let data = String::deserialize(
1565                    value
1566                        .data
1567                        .as_ref()
1568                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1569                )
1570                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1571                Ok(Self::InvalidTransactionNonce(data))
1572            }
1573            53 => Ok(Self::InsufficientResourcesForValidate),
1574            54 => Ok(Self::InsufficientAccountBalance),
1575            55 => {
1576                let data = String::deserialize(
1577                    value
1578                        .data
1579                        .as_ref()
1580                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1581                )
1582                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1583                Ok(Self::ValidationFailure(data))
1584            }
1585            56 => {
1586                let data = String::deserialize(
1587                    value
1588                        .data
1589                        .as_ref()
1590                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1591                )
1592                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1593                Ok(Self::CompilationFailed(data))
1594            }
1595            57 => Ok(Self::ContractClassSizeIsTooLarge),
1596            58 => Ok(Self::NonAccount),
1597            59 => Ok(Self::DuplicateTx),
1598            60 => Ok(Self::CompiledClassHashMismatch),
1599            61 => Ok(Self::UnsupportedTxVersion),
1600            62 => Ok(Self::UnsupportedContractClassVersion),
1601            63 => {
1602                let data = String::deserialize(
1603                    value
1604                        .data
1605                        .as_ref()
1606                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1607                )
1608                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1609                Ok(Self::UnexpectedError(data))
1610            }
1611            64 => Ok(Self::ReplacementTransactionUnderpriced),
1612            65 => Ok(Self::FeeBelowMinimum),
1613            66 => Ok(Self::InvalidSubscriptionId),
1614            67 => Ok(Self::TooManyAddressesInFilter),
1615            68 => Ok(Self::TooManyBlocksBack),
1616            10 => {
1617                let data = NoTraceAvailableErrorData::deserialize(
1618                    value
1619                        .data
1620                        .as_ref()
1621                        .ok_or(JsonRpcErrorConversionError::MissingData)?,
1622                )
1623                .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?;
1624                Ok(Self::NoTraceAvailable(data))
1625            }
1626            _ => Err(JsonRpcErrorConversionError::UnknownCode),
1627        }
1628    }
1629}
1630
1631impl Error for JsonRpcError {}
1632
1633impl Display for JsonRpcError {
1634    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1635        match &self.data {
1636            Some(data) => {
1637                write!(
1638                    f,
1639                    "JSON-RPC error: code={}, message=\"{}\", data={}",
1640                    self.code,
1641                    self.message,
1642                    serde_json::to_string(data).map_err(|_| std::fmt::Error)?
1643                )
1644            }
1645            None => {
1646                write!(
1647                    f,
1648                    "JSON-RPC error: code={}, message=\"{}\"",
1649                    self.code, self.message
1650                )
1651            }
1652        }
1653    }
1654}