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#[derive(Debug, Clone)]
39pub struct JsonRpcClient<T> {
40 transport: T,
41}
42
43#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
45pub enum JsonRpcMethod {
46 #[serde(rename = "starknet_specVersion")]
48 SpecVersion,
49 #[serde(rename = "starknet_getBlockWithTxHashes")]
51 GetBlockWithTxHashes,
52 #[serde(rename = "starknet_getBlockWithTxs")]
54 GetBlockWithTxs,
55 #[serde(rename = "starknet_getBlockWithReceipts")]
57 GetBlockWithReceipts,
58 #[serde(rename = "starknet_getStateUpdate")]
60 GetStateUpdate,
61 #[serde(rename = "starknet_getStorageAt")]
63 GetStorageAt,
64 #[serde(rename = "starknet_getMessagesStatus")]
66 GetMessagesStatus,
67 #[serde(rename = "starknet_getTransactionStatus")]
69 GetTransactionStatus,
70 #[serde(rename = "starknet_getTransactionByHash")]
72 GetTransactionByHash,
73 #[serde(rename = "starknet_getTransactionByBlockIdAndIndex")]
75 GetTransactionByBlockIdAndIndex,
76 #[serde(rename = "starknet_getTransactionReceipt")]
78 GetTransactionReceipt,
79 #[serde(rename = "starknet_getClass")]
81 GetClass,
82 #[serde(rename = "starknet_getClassHashAt")]
84 GetClassHashAt,
85 #[serde(rename = "starknet_getClassAt")]
87 GetClassAt,
88 #[serde(rename = "starknet_getBlockTransactionCount")]
90 GetBlockTransactionCount,
91 #[serde(rename = "starknet_call")]
93 Call,
94 #[serde(rename = "starknet_estimateFee")]
96 EstimateFee,
97 #[serde(rename = "starknet_estimateMessageFee")]
99 EstimateMessageFee,
100 #[serde(rename = "starknet_blockNumber")]
102 BlockNumber,
103 #[serde(rename = "starknet_blockHashAndNumber")]
105 BlockHashAndNumber,
106 #[serde(rename = "starknet_chainId")]
108 ChainId,
109 #[serde(rename = "starknet_syncing")]
111 Syncing,
112 #[serde(rename = "starknet_getEvents")]
114 GetEvents,
115 #[serde(rename = "starknet_getNonce")]
117 GetNonce,
118 #[serde(rename = "starknet_getStorageProof")]
120 GetStorageProof,
121 #[serde(rename = "starknet_addInvokeTransaction")]
123 AddInvokeTransaction,
124 #[serde(rename = "starknet_addDeclareTransaction")]
126 AddDeclareTransaction,
127 #[serde(rename = "starknet_addDeployAccountTransaction")]
129 AddDeployAccountTransaction,
130 #[serde(rename = "starknet_traceTransaction")]
132 TraceTransaction,
133 #[serde(rename = "starknet_simulateTransactions")]
135 SimulateTransactions,
136 #[serde(rename = "starknet_traceBlockTransactions")]
138 TraceBlockTransactions,
139 #[serde(rename = "starknet_subscribeNewHeads")]
141 SubscribeNewHeads,
142 #[serde(rename = "starknet_subscriptionNewHeads")]
144 SubscriptionNewHeads,
145 #[serde(rename = "starknet_subscribeEvents")]
147 SubscribeEvents,
148 #[serde(rename = "starknet_subscriptionEvents")]
150 SubscriptionEvents,
151 #[serde(rename = "starknet_subscribeTransactionStatus")]
153 SubscribeTransactionStatus,
154 #[serde(rename = "starknet_subscriptionTransactionStatus")]
156 SubscriptionTransactionStatus,
157 #[serde(rename = "starknet_subscribeNewTransactionReceipts")]
159 SubscribeNewTransactionReceipts,
160 #[serde(rename = "starknet_subscriptionNewTransactionReceipts")]
162 SubscriptionNewTransactionReceipts,
163 #[serde(rename = "starknet_subscribeNewTransactions")]
165 SubscribeNewTransactions,
166 #[serde(rename = "starknet_subscriptionNewTransaction")]
168 SubscriptionNewTransaction,
169 #[serde(rename = "starknet_subscriptionReorg")]
171 SubscriptionReorg,
172 #[serde(rename = "starknet_unsubscribe")]
174 Unsubscribe,
175}
176
177#[derive(Debug, Clone)]
179pub struct JsonRpcRequest {
180 pub id: u64,
182 pub data: ProviderRequestData,
184}
185
186#[derive(Debug, Clone)]
188pub struct JsonRpcStreamUpdate {
189 pub data: StreamUpdateData,
191}
192
193#[derive(Debug, thiserror::Error)]
195pub enum JsonRpcClientError<T> {
196 #[error(transparent)]
198 JsonError(serde_json::Error),
199 #[error(transparent)]
201 TransportError(T),
202 #[error(transparent)]
204 JsonRpcError(JsonRpcError),
205}
206
207#[derive(Debug, Clone, Deserialize)]
209pub struct JsonRpcError {
210 pub code: i64,
212 pub message: String,
214 #[serde(skip_serializing_if = "Option::is_none")]
216 pub data: Option<serde_json::Value>,
217}
218
219#[derive(Debug, Clone, Deserialize)]
221#[serde(untagged)]
222pub enum JsonRpcResponse<T> {
223 Success {
225 id: u64,
227 result: T,
229 },
230 Error {
232 id: u64,
234 error: JsonRpcError,
236 },
237}
238
239#[derive(Debug, thiserror::Error)]
248pub enum JsonRpcErrorConversionError {
249 #[error("unknown error code")]
251 UnknownCode,
252 #[error("missing data field")]
254 MissingData,
255 #[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 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 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 async fn spec_version(&self) -> Result<String, ProviderError> {
548 self.send_request(JsonRpcMethod::SpecVersion, SpecVersionRequest)
549 .await
550 }
551
552 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 async fn block_number(&self) -> Result<u64, ProviderError> {
870 self.send_request(JsonRpcMethod::BlockNumber, BlockNumberRequest)
871 .await
872 }
873
874 async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, ProviderError> {
876 self.send_request(JsonRpcMethod::BlockHashAndNumber, BlockHashAndNumberRequest)
877 .await
878 }
879
880 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 async fn syncing(&self) -> Result<SyncStatusType, ProviderError> {
890 self.send_request(JsonRpcMethod::Syncing, SyncingRequest)
891 .await
892 }
893
894 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 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 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 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 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 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 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 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 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}