pallet_stateful_storage_rpc/
lib.rs

1#![allow(deprecated)]
2// Strong Documentation Lints
3#![deny(
4	rustdoc::broken_intra_doc_links,
5	rustdoc::missing_crate_level_docs,
6	rustdoc::invalid_codeblock_attributes,
7	missing_docs
8)]
9
10//! Custom APIs for [Stateful-Storage](../pallet_stateful_storage/index.html)
11
12use common_primitives::{
13	msa::MessageSourceId,
14	schema::*,
15	stateful_storage::{ItemizedStoragePageResponseV2, PaginatedStorageResponseV2},
16};
17use jsonrpsee::{
18	core::{async_trait, RpcResult},
19	proc_macros::rpc,
20	types::error::{ErrorCode, ErrorObject},
21};
22use pallet_stateful_storage_runtime_api::StatefulStorageRuntimeApi;
23use sp_api::{ApiError, ProvideRuntimeApi};
24use sp_blockchain::HeaderBackend;
25use sp_runtime::{traits::Block as BlockT, DispatchError};
26extern crate alloc;
27use alloc::{sync::Arc, vec::Vec};
28
29#[cfg(test)]
30mod tests;
31
32/// Frequency Stateful Storage Custom RPC API
33#[rpc(client, server)]
34pub trait StatefulStorageApi<BlockHash> {
35	/// retrieving pages of stateful storage
36	#[method(name = "statefulStorage_getPaginatedStorage")]
37	fn get_paginated_storage(
38		&self,
39		msa_id: MessageSourceId,
40		intent_id: IntentId,
41	) -> RpcResult<Vec<PaginatedStorageResponseV2>>;
42
43	/// retrieving itemized storage of stateful storage
44	#[method(name = "statefulStorage_getItemizedStorage")]
45	fn get_itemized_storage(
46		&self,
47		msa_id: MessageSourceId,
48		intent_id: IntentId,
49	) -> RpcResult<ItemizedStoragePageResponseV2>;
50}
51
52/// The client handler for the API used by Frequency Service RPC with `jsonrpsee`
53pub struct StatefulStorageHandler<C, M> {
54	client: Arc<C>,
55	_marker: std::marker::PhantomData<M>,
56}
57
58impl<C, M> StatefulStorageHandler<C, M> {
59	/// Create new instance with the given reference to the client.
60	pub fn new(client: Arc<C>) -> Self {
61		Self { client, _marker: Default::default() }
62	}
63}
64
65#[async_trait]
66impl<C, Block> StatefulStorageApiServer<<Block as BlockT>::Hash>
67	for StatefulStorageHandler<C, Block>
68where
69	Block: BlockT,
70	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
71	C::Api: StatefulStorageRuntimeApi<Block>,
72{
73	fn get_paginated_storage(
74		&self,
75		msa_id: MessageSourceId,
76		intent_id: IntentId,
77	) -> RpcResult<Vec<PaginatedStorageResponseV2>> {
78		let api = self.client.runtime_api();
79		let at = self.client.info().best_hash;
80		let api_result = api.get_paginated_storage_v2(at, msa_id, intent_id);
81		map_result(api_result)
82	}
83
84	fn get_itemized_storage(
85		&self,
86		msa_id: MessageSourceId,
87		intent_id: IntentId,
88	) -> RpcResult<ItemizedStoragePageResponseV2> {
89		let api = self.client.runtime_api();
90		let at = self.client.info().best_hash;
91		let api_result = api.get_itemized_storage_v2(at, msa_id, intent_id);
92		map_result(api_result)
93	}
94}
95
96fn map_result<T>(api_result: Result<Result<T, DispatchError>, ApiError>) -> RpcResult<T> {
97	match api_result {
98		Ok(Ok(result)) => Ok(result),
99		Ok(Err(e)) => Err(ErrorObject::owned(
100			ErrorCode::ServerError(300).code(), // No real reason for this value
101			"Runtime Error",
102			Some(format!("{e:?}")),
103		)),
104		Err(e) => Err(ErrorObject::owned(
105			ErrorCode::ServerError(301).code(), // No real reason for this value
106			"Api Error",
107			Some(format!("{e:?}")),
108		)),
109	}
110}