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
pub mod author;
pub mod chain;
pub mod grandpa;
pub mod state;
pub mod system;

#[cfg(feature = "sender")]
pub mod sender {
	// --- crates.io ---
	use isahc::{
		http::{
			header::CONTENT_TYPE, request::Builder as RequestBuilder, Method as HttpMethod,
			Response,
		},
		AsyncBody as IsahcAsyncBody, Body as IsahcBody, Error as IsahcError,
	};
	use serde_json::{Error as RawSerdeJsonError, Value};
	use thiserror::Error as ThisError;
	use tracing::trace;

	pub type SubrpcerResult<T> = Result<T, Error>;
	pub type IsahcResponse = Response<IsahcBody>;
	pub type IsahcAsyncResponse = Response<IsahcAsyncBody>;

	#[derive(Debug, ThisError)]
	#[error("{0}")]
	pub enum Error {
		SerdeJson(#[from] SerdeJsonError),
		Isahc(#[from] IsahcError),
	}

	#[derive(Debug, ThisError)]
	#[error("{0}")]
	pub enum SerdeJsonError {
		Raw(#[from] RawSerdeJsonError),
	}

	pub fn send_rpc(uri: impl AsRef<str>, body: Value) -> SubrpcerResult<IsahcResponse> {
		let mut request_builder = RequestBuilder::new()
			.method(HttpMethod::POST)
			.uri(uri.as_ref());

		request_builder.headers_mut().unwrap().append(
			CONTENT_TYPE,
			"application/json;charset=utf-8".parse().unwrap(),
		);

		let request = request_builder
			.body(serde_json::to_vec(&body).map_err(SerdeJsonError::from)?)
			.unwrap();
		let result = isahc::send(request)?;

		trace!("{:#?}", result);

		Ok(result)
	}

	pub async fn send_rpc_async(
		uri: impl AsRef<str>,
		body: Value,
	) -> SubrpcerResult<IsahcAsyncResponse> {
		let mut request_builder = RequestBuilder::new()
			.method(HttpMethod::POST)
			.uri(uri.as_ref());

		request_builder.headers_mut().unwrap().append(
			CONTENT_TYPE,
			"application/json;charset=utf-8".parse().unwrap(),
		);

		let request = request_builder
			.body(serde_json::to_vec(&body).map_err(SerdeJsonError::from)?)
			.unwrap();
		let result = isahc::send_async(request).await?;

		trace!("{:#?}", result);

		Ok(result)
	}
}

#[cfg(feature = "sender")]
pub use sender::*;

// --- crates.io ---
use serde::Serialize;
use serde_json::{json, Value};

const DEFAULT_ID: u8 = 1;

pub fn rpc(id: impl Serialize, method: impl Serialize, params: impl Serialize) -> Value {
	json!({
		"jsonrpc": "2.0",
		"id": id,
		"method": method,
		"params": params
	})
}

#[cfg(feature = "tracing")]
pub fn debug_rpc(rpc: Value) -> Value {
	tracing::debug!("{}", rpc);

	rpc
}