// Copyright 2019-2025 Parity Technologies (UK) Ltd. // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. use super::{RawRpcFuture, RawRpcSubscription, RpcClientT}; use crate::Error; use futures::stream::{StreamExt, TryStreamExt}; use jsonrpsee::{ core::{ client::{Error as JsonrpseeError, Client, ClientT, SubscriptionClientT, SubscriptionKind}, traits::ToRpcParams, }, types::SubscriptionId, }; use serde_json::value::RawValue; struct Params(Option>); impl ToRpcParams for Params { fn to_rpc_params(self) -> Result>, serde_json::Error> { Ok(self.0) } } impl RpcClientT for Client { fn request_raw<'a>( &'a self, method: &'a str, params: Option>, ) -> RawRpcFuture<'a, Box> { Box::pin(async move { let res = ClientT::request(self, method, Params(params)).await?; Ok(res) }) } fn subscribe_raw<'a>( &'a self, sub: &'a str, params: Option>, unsub: &'a str, ) -> RawRpcFuture<'a, RawRpcSubscription> { Box::pin(async move { let stream = SubscriptionClientT::subscribe::, _>( self, sub, Params(params), unsub, ).await?; let id = match stream.kind() { SubscriptionKind::Subscription(SubscriptionId::Str(id)) => { Some(id.clone().into_owned()) } _ => None, }; let stream = stream .map_err(|e| Error::Client(Box::new(e))) .boxed(); Ok(RawRpcSubscription { stream, id }) }) } } // Convert a JsonrpseeError into the RPC error in this crate. // The main reason for this is to capture user errors so that // they can be represented/handled without casting. impl From for Error { fn from(error: JsonrpseeError) -> Self { match error { JsonrpseeError::Call(e) => { Error::User(crate::UserError { code: e.code(), message: e.message().to_owned(), data: e.data().map(|d| d.to_owned()) }) }, e => { Error::Client(Box::new(e)) } } } }