use crate::error::Error; use futures::executor::block_on;
use jsonrpsee::{
client_transport::ws::{Uri, WsTransportClientBuilder},
core::{
client::{Client, ClientBuilder, ClientT, SubscriptionClientT},
traits::ToRpcParams,
},
};
use serde::de::DeserializeOwned;
use serde_json::value::RawValue;
use std::sync::Arc;
use crate::jsonrpseeclient::subscription::Request;
use crate::jsonrpseeclient::subscription::Subscribe;
pub use rpcstuff::RpcParams;
pub use subscription::SubscriptionWrapper;
pub mod rpcstuff;
pub mod subscription;
pub use subscription::Result;
#[derive(Clone)]
pub struct JsonrpseeClient {
inner: Arc<Client>,
}
impl JsonrpseeClient {
pub fn new(url: &str) -> Result<Self> {
block_on(Self::async_new(url))
}
pub fn with_default_url() -> Result<Self> {
Self::new("ws://127.0.0.1:9944")
}
pub fn edgeware_default_url() -> Result<Self> {
Self::new("wss://edgeware.jelliedowl.net:443")
}
pub fn polkadot_default_url() -> Result<Self> {
Self::new("wss://polkadot-rpc-tn.dwellir.com:443")
}
pub fn kusama_default_url() -> Result<Self> {
Self::new("wss://kusama-rpc-tn.dwellir.com:443")
}
pub fn sora_default_url() -> Result<Self> {
Self::new("wss://ws.mof.sora.org:443")
}
pub fn get_metadata_version() -> Result<u32> {
Ok(1u32)
}
async fn async_new(url: &str) -> Result<Self> {
let uri: Uri = url.parse().map_err(|_e| Error::ConnectionClosed)?; let (tx, rx) = WsTransportClientBuilder::default()
.build(uri)
.await
.map_err(|_e| Error::ConnectionClosed)?;
let client = ClientBuilder::default()
.max_notifs_per_subscription(4096)
.build_with_tokio(tx, rx);
Ok(Self {
inner: Arc::new(client),
})
}
}
#[maybe_async::async_impl(?Send)]
impl Request for JsonrpseeClient {
async fn request<R: DeserializeOwned>(&self, method: &str, params: RpcParams) -> Result<R> {
let future = self.inner.request(method, RpcParamsWrapper(params)).await;
future.map_err(|_e| Error::ConnectionClosed)
}
}
#[maybe_async::sync_impl]
impl Request for JsonrpseeClient {
fn request<R: DeserializeOwned>(&self, method: &str, params: RpcParams) -> Result<R> {
block_on(self.inner.request(method, RpcParamsWrapper(params)))
.map_err(|e| Error::ConnectionClosed)
}
}
impl Subscribe for JsonrpseeClient {
type Subscription<Notification> = SubscriptionWrapper<Notification> where Notification: DeserializeOwned;
fn subscribe<Notification: DeserializeOwned>(
&self,
sub: &str,
params: RpcParams,
unsub: &str,
) -> Result<Self::Subscription<Notification>> {
block_on(self.inner.subscribe(sub, RpcParamsWrapper(params), unsub))
.map(|sub| sub.into())
.map_err(|_e| Error::ConnectionSubscriptionProblem) }
}
struct RpcParamsWrapper(crate::jsonrpseeclient::rpcstuff::RpcParams);
impl ToRpcParams for RpcParamsWrapper {
fn to_rpc_params(self) -> core::result::Result<Option<Box<RawValue>>, jsonrpsee::core::Error> {
if let Some(json) = self.0.build() {
RawValue::from_string(json)
.map(Some)
.map_err(jsonrpsee::core::Error::ParseError)
} else {
Ok(None)
}
}
}