substrate_api_client/api/rpc_api/
frame_system.rs

1/*
2   Copyright 2019 Supercomputing Systems AG
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6	   http://www.apache.org/licenses/LICENSE-2.0
7   Unless required by applicable law or agreed to in writing, software
8   distributed under the License is distributed on an "AS IS" BASIS,
9   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10   See the License for the specific language governing permissions and
11   limitations under the License.
12*/
13
14//! Interface to common frame system pallet information.
15
16use crate::{
17	api::{Api, GetStorage, Result},
18	rpc::Request,
19};
20use ac_compose_macros::rpc_params;
21use ac_primitives::{config::Config, AccountInfo};
22#[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
23use alloc::boxed::Box;
24use alloc::{string::String, vec::Vec};
25use log::*;
26use sp_storage::StorageKey;
27
28#[maybe_async::maybe_async(?Send)]
29pub trait GetAccountInformation {
30	type AccountId;
31	type Index;
32	type AccountData;
33
34	/// Retrieves the next account index as available on the node.
35	async fn get_system_account_next_index(
36		&self,
37		account_id: Self::AccountId,
38	) -> Result<Self::Index>;
39
40	async fn get_account_info(
41		&self,
42		address: &Self::AccountId,
43	) -> Result<Option<AccountInfo<Self::Index, Self::AccountData>>>;
44
45	async fn get_account_data(
46		&self,
47		address: &Self::AccountId,
48	) -> Result<Option<Self::AccountData>>;
49
50	/// Get nonce of an account.
51	async fn get_account_nonce(&self, account: &Self::AccountId) -> Result<Self::Index>;
52}
53
54#[maybe_async::maybe_async(?Send)]
55impl<T, Client> GetAccountInformation for Api<T, Client>
56where
57	T: Config,
58	Client: Request,
59{
60	type AccountId = T::AccountId;
61	type Index = T::Index;
62	type AccountData = T::AccountData;
63
64	async fn get_system_account_next_index(
65		&self,
66		account_id: Self::AccountId,
67	) -> Result<Self::Index> {
68		let next_index = self
69			.client()
70			.request("system_accountNextIndex", rpc_params![account_id])
71			.await?;
72		Ok(next_index)
73	}
74
75	async fn get_account_info(
76		&self,
77		address: &Self::AccountId,
78	) -> Result<Option<AccountInfo<Self::Index, Self::AccountData>>> {
79		let storagekey: StorageKey = self.metadata().storage_map_key::<Self::AccountId>(
80			"System",
81			"Account",
82			address.clone(),
83		)?;
84
85		info!("storage key is: 0x{}", hex::encode(&storagekey));
86		self.get_storage_by_key(storagekey, None).await
87	}
88
89	async fn get_account_data(
90		&self,
91		address: &Self::AccountId,
92	) -> Result<Option<Self::AccountData>> {
93		self.get_account_info(address).await.map(|info| info.map(|i| i.data))
94	}
95
96	async fn get_account_nonce(&self, account: &Self::AccountId) -> Result<Self::Index> {
97		self.get_account_info(account)
98			.await
99			.map(|acc_opt| acc_opt.map_or_else(|| 0u32.into(), |acc| acc.nonce))
100	}
101}
102
103/// Helper functions for some common SystemApi function.
104#[maybe_async::maybe_async(?Send)]
105pub trait SystemApi {
106	type ChainType;
107	type Properties;
108	type Health;
109
110	/// Get the node's implementation name.
111	async fn get_system_name(&self) -> Result<String>;
112
113	/// Get the node implementation's version. Should be a semver string.
114	async fn get_system_version(&self) -> Result<String>;
115
116	/// Get the chain's name. Given as a string identifier.
117	async fn get_system_chain(&self) -> Result<String>;
118
119	/// Get the chain's type.
120	async fn get_system_chain_type(&self) -> Result<Self::ChainType>;
121
122	/// Get a custom set of properties as a JSON object, defined in the chain spec.
123	async fn get_system_properties(&self) -> Result<Self::Properties>;
124
125	/// Return health status of the node.
126	///
127	/// Node is considered healthy if it is:
128	/// - connected to some peers (unless running in dev mode)
129	/// - not performing a major sync
130	async fn get_system_health(&self) -> Result<Self::Health>;
131
132	/// Get the base58-encoded PeerId of the node.
133	async fn get_system_local_peer_id(&self) -> Result<String>;
134
135	/// Returns the multi-addresses that the local node is listening on.
136	///
137	/// The addresses include a trailing `/p2p/` with the local PeerId, and are thus suitable to
138	/// be passed to `addReservedPeer` or as a bootnode address for example.
139	async fn get_system_local_listen_addresses(&self) -> Result<Vec<String>>;
140}
141
142#[maybe_async::maybe_async(?Send)]
143impl<T, Client> SystemApi for Api<T, Client>
144where
145	T: Config,
146	Client: Request,
147{
148	type ChainType = ac_primitives::ChainType;
149	type Properties = ac_primitives::Properties;
150	type Health = ac_primitives::Health;
151
152	async fn get_system_name(&self) -> Result<String> {
153		let res = self.client().request("system_name", rpc_params![]).await?;
154		Ok(res)
155	}
156
157	async fn get_system_version(&self) -> Result<String> {
158		let res = self.client().request("system_version", rpc_params![]).await?;
159		Ok(res)
160	}
161
162	async fn get_system_chain(&self) -> Result<String> {
163		let res = self.client().request("system_chain", rpc_params![]).await?;
164		Ok(res)
165	}
166
167	async fn get_system_chain_type(&self) -> Result<Self::ChainType> {
168		let res = self.client().request("system_chainType", rpc_params![]).await?;
169		Ok(res)
170	}
171
172	async fn get_system_properties(&self) -> Result<Self::Properties> {
173		let res = self.client().request("system_properties", rpc_params![]).await?;
174		Ok(res)
175	}
176
177	async fn get_system_health(&self) -> Result<Self::Health> {
178		let res = self.client().request("system_health", rpc_params![]).await?;
179		Ok(res)
180	}
181
182	async fn get_system_local_peer_id(&self) -> Result<String> {
183		let res = self.client().request("system_localPeerId", rpc_params![]).await?;
184		Ok(res)
185	}
186
187	async fn get_system_local_listen_addresses(&self) -> Result<Vec<String>> {
188		let res = self.client().request("system_localListenAddresses", rpc_params![]).await?;
189		Ok(res)
190	}
191}