substrate_api_client/api/runtime_api/
mod.rs1pub use self::{
15 account_nonce::*, api_core::*, authority_discovery::*, block_builder::*, metadata::*, mmr::*,
16 session_keys::*, staking::*, transaction_payment::*, transaction_payment_call::*,
17};
18
19pub mod account_nonce;
20pub mod api_core;
21pub mod authority_discovery;
22pub mod block_builder;
23pub mod metadata;
24pub mod mmr;
25pub mod session_keys;
26pub mod staking;
27pub mod transaction_payment;
28pub mod transaction_payment_call;
29
30use crate::{api::Result, rpc::Request};
31use ac_compose_macros::rpc_params;
32use ac_primitives::config::Config;
33#[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
34use alloc::boxed::Box;
35use alloc::{sync::Arc, vec::Vec};
36use codec::Decode;
37use core::marker::PhantomData;
38use sp_core::Bytes;
39
40#[derive(Clone)]
41pub struct RuntimeApiClient<T, Client> {
42 client: Arc<Client>,
43 _phantom: PhantomData<T>,
44}
45
46impl<T, Client> RuntimeApiClient<T, Client> {
47 pub fn new(client: Arc<Client>) -> Self {
48 Self { client, _phantom: PhantomData }
49 }
50}
51
52#[maybe_async::maybe_async(?Send)]
53pub trait RuntimeApi {
54 type Hash;
55
56 async fn runtime_call<V: Decode>(
58 &self,
59 method: &str,
60 data: Vec<Vec<u8>>,
61 at_block: Option<Self::Hash>,
62 ) -> Result<V>;
63
64 async fn opaque_runtime_call(
66 &self,
67 method: &str,
68 data: Vec<Vec<u8>>,
69 at_block: Option<Self::Hash>,
70 ) -> Result<Bytes>;
71
72 async fn rpc_call(
74 &self,
75 method: &str,
76 data: Option<Bytes>,
77 at_block: Option<Self::Hash>,
78 ) -> Result<Bytes>;
79}
80
81#[maybe_async::maybe_async(?Send)]
82impl<T, Client> RuntimeApi for RuntimeApiClient<T, Client>
83where
84 T: Config,
85 Client: Request,
86{
87 type Hash = T::Hash;
88
89 async fn runtime_call<V: Decode>(
90 &self,
91 method: &str,
92 data: Vec<Vec<u8>>,
93 at_block: Option<Self::Hash>,
94 ) -> Result<V> {
95 let bytes = self.opaque_runtime_call(method, data, at_block).await?;
96 Ok(Decode::decode(&mut bytes.0.as_slice())?)
97 }
98
99 async fn opaque_runtime_call(
100 &self,
101 method: &str,
102 data: Vec<Vec<u8>>,
103 at_block: Option<Self::Hash>,
104 ) -> Result<Bytes> {
105 let data = match data.is_empty() {
106 true => None,
107 false => {
108 let mut appended_data = Vec::new();
109 for mut item in data {
110 appended_data.append(&mut item);
111 }
112 Some(appended_data.into())
113 },
114 };
115 self.rpc_call(method, data, at_block).await
116 }
117
118 async fn rpc_call(
119 &self,
120 method: &str,
121 data: Option<Bytes>,
122 at_block: Option<Self::Hash>,
123 ) -> Result<Bytes> {
124 let extracted_data: Bytes = match data {
125 Some(data) => data,
126 None => Vec::new().into(),
127 };
128 let return_bytes = self
129 .client
130 .request("state_call", rpc_params![method, extracted_data, at_block])
131 .await?;
132 Ok(return_bytes)
133 }
134}