Skip to content

Commit 8510517

Browse files
authored
Add unstable rpc api calls example (#736)
* add new example * fix example * fix example * add subscription example * fix description
1 parent b44ac6b commit 8510517

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

.github/workflows/ci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ jobs:
174174
staking_batch_payout,
175175
subscribe_events,
176176
sudo,
177+
unstable_rpc_api_calls,
177178
transfer_with_tungstenite_client,
178179
transfer_with_ws_client,
179180
author_tests,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
Copyright 2024 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+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
//! This example shows how to call the unstable rpc api with self defined functions.
17+
//! This includes simple requests as well as subscription.
18+
19+
use codec::Encode;
20+
use serde_json::Value;
21+
use sp_core::Bytes;
22+
use sp_keyring::AccountKeyring;
23+
use substrate_api_client::{
24+
ac_compose_macros::rpc_params,
25+
ac_primitives::AssetRuntimeConfig,
26+
extrinsic::BalancesExtrinsics,
27+
rpc::{HandleSubscription, JsonrpseeClient, Request, Subscribe},
28+
Api,
29+
};
30+
31+
// To test this example with CI we run it against the Substrate kitchensink node, which uses the asset pallet.
32+
// Therefore, we need to use the `AssetRuntimeConfig` in this example.
33+
// ! However, most Substrate runtimes do not use the asset pallet at all. So if you run an example against your own node
34+
// you most likely should use `DefaultRuntimeConfig` instead.
35+
36+
#[tokio::main]
37+
async fn main() {
38+
env_logger::init();
39+
40+
// Initialize api and set the signer (sender) that is used to sign the extrinsics.
41+
let signer = AccountKeyring::Alice.pair();
42+
let client = JsonrpseeClient::with_default_url().await.unwrap();
43+
let mut api = Api::<AssetRuntimeConfig, _>::new(client).await.unwrap();
44+
api.set_signer(signer.into());
45+
46+
// Retrieve all available rpc methods:
47+
let json_value: Value = api.client().request("rpc_methods", rpc_params![]).await.unwrap();
48+
let json_string = serde_json::to_string(&json_value).unwrap();
49+
println!("Available methods: {json_string} \n");
50+
51+
// Since it's an unstable api and might change anytime, we first check if our calls are still
52+
// available:
53+
let chain_name_request = "chainSpec_unstable_chainName";
54+
let chain_genesis_hash_request = "chainSpec_unstable_genesisHash";
55+
let transaction_submit_watch = "transaction_unstable_submitAndWatch";
56+
let transaction_unwatch = "transaction_unstable_unwatch";
57+
58+
let request_vec = [
59+
chain_name_request,
60+
chain_genesis_hash_request,
61+
transaction_submit_watch,
62+
transaction_unwatch,
63+
];
64+
for request in request_vec {
65+
if !json_string.contains(request) {
66+
panic!("Api has changed, please update the call {request}.");
67+
}
68+
}
69+
70+
// Submit the above defiend rpc requests:
71+
let chain_name: String = api.client().request(chain_name_request, rpc_params![]).await.unwrap();
72+
println!("Our chain is called: {chain_name}");
73+
74+
let genesishash: String =
75+
api.client().request(chain_genesis_hash_request, rpc_params![]).await.unwrap();
76+
println!("Chain genesis Hash: {genesishash}");
77+
78+
// Submit and watch a transaction:
79+
let bob = AccountKeyring::Bob.to_account_id();
80+
let encoded_extrinsic: Bytes = api
81+
.balance_transfer_allow_death(bob.into(), 1000)
82+
.await
83+
.unwrap()
84+
.encode()
85+
.into();
86+
87+
let mut subscription = api
88+
.client()
89+
.subscribe::<Value>(
90+
transaction_submit_watch,
91+
rpc_params![encoded_extrinsic],
92+
transaction_unwatch,
93+
)
94+
.await
95+
.unwrap();
96+
while let Some(notification) = subscription.next().await {
97+
let notification = notification.unwrap();
98+
println!("Subscription notification: {notification:?}");
99+
let event_object_string = notification["event"].as_str().unwrap();
100+
//let event_object_string = serde_json::from_string().unwrap();
101+
match event_object_string {
102+
"finalized" => break,
103+
"bestChainBlockIncluded" | "validated" => println!("Got {event_object_string} event"),
104+
_ => panic!("Unexpected event: {event_object_string}"),
105+
};
106+
}
107+
println!("Transaction got finalized, unsubscribing.");
108+
subscription.unsubscribe().await.unwrap();
109+
}

0 commit comments

Comments
 (0)