1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
//! Minimal implementation of Substrate RPC APIs.
//!
//! Formatting rule(s):
//! - All the APIs must be sorted in alphabetic order.
#![deny(missing_docs)]
/// Define a group of APIs.
///
/// Require [serde](https://crates.io/crates/serde) and [serde_json](https://crates.io/crates/serde_json) as the dependencies.
///
/// # Example
/// ```
/// impl_apis! {
/// state {
/// call { params: [name, bytes], opt_params: [hash] }
/// get_keys { params: [prefix], opt_params: [hash] }
/// get_metadata { params: [], opt_params: [hash] }
/// get_pairs { params: [prefix], opt_params: [hash] }
/// get_read_proof { params: [keys], opt_params: [hash] }
/// get_runtime_version { params: [], opt_params: [hash] }
/// get_storage { params: [key], opt_params: [hash] }
/// get_storage_hash { params: [key], opt_params: [hash] }
/// get_storage_size { params: [key], opt_params: [hash] }
/// query_storage { params: [keys, block], opt_params: [hash] }
/// query_storage_at { params: [keys], opt_params: [at] }
/// subscribe_runtime_version { params: [], opt_params: [] }
/// subscribe_storage { params: [], opt_params: [keys] }
/// trace_block { params: [block], opt_params: [targets, storage_keys, methods] }
/// unsubscribe_runtime_version { params: [subscription_id], opt_params: [] }
/// unsubscribe_storage { params: [subscription_id], opt_params: [] }
/// }
/// }
/// ```
#[allow(clippy::tabs_in_doc_comments)]
#[macro_export]
macro_rules! impl_apis {
{
$prefix:ident {
$(
$method:ident {
params: [
$(
$param:ident
),*
],
opt_params: [
$(
$opt_param:ident
),*
]
}
)+
}
} => {
$(
affix::paste! {
/// Check module's Substrate reference(s) for the detail.
pub fn $method(
id: usize,
$($param: impl serde::Serialize,)*
$($opt_param: Option<impl serde::Serialize>,)*
) -> serde_json::Value {
$crate::rpc(
id,
stringify!([<$prefix _ $method:camel>]),
serde_json::json!([
$($param,)*
$($opt_param,)*
])
)
}
#[doc = concat!("Similar to [`", stringify!($method), "`], but return the method name and parameters directly.")]
pub fn [<$method _raw>](
$($param: impl serde::Serialize,)*
$($opt_param: Option<impl serde::Serialize>,)*
) -> (&'static str, serde_json::Value) {
(
stringify!([<$prefix _ $method:camel>]),
serde_json::json!([
$($param,)*
$($opt_param,)*
])
)
}
}
)+
};
}
pub mod author;
pub mod babe;
pub mod chain;
pub mod grandpa;
pub mod net;
pub mod offchain;
pub mod payment;
pub mod rpc;
pub mod state;
pub mod system;
#[cfg(any(feature = "reqwest-client", feature = "ureq-client"))] mod client;
// TODO: optimize the option param
// crates.io
use serde_json::Value;
/// Build a JSONRPC 2.0 call.
pub fn rpc(id: usize, method: &str, params: Value) -> Value {
serde_json::json!({
"jsonrpc": "2.0",
"id": id,
"method": method,
"params": params
})
}
/// A debug wrapper for the RPC payload.
///
/// This will output a trace-level log about the RPC call detail.
#[cfg(feature = "tracing")]
pub fn debug(rpc: Value) -> Value {
tracing::trace!("{rpc:?}");
rpc
}