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