diff --git a/Cargo.lock b/Cargo.lock index 03cf3f1b..7c6f5da6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1658,6 +1658,27 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "gloo-timers" version = "0.2.6" @@ -1682,6 +1703,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "h2" version = "0.3.24" @@ -1870,9 +1904,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -2057,6 +2091,7 @@ dependencies = [ "jsonrpsee-http-client", "jsonrpsee-proc-macros", "jsonrpsee-types", + "jsonrpsee-wasm-client", "jsonrpsee-ws-client", "tracing", ] @@ -2067,7 +2102,9 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "310f9566a32ec8db214805127c4f17e7e8e91015e4a1407fc1d0e84df0086a73" dependencies = [ + "futures-channel", "futures-util", + "gloo-net", "http", "jsonrpsee-core", "pin-project", @@ -2101,6 +2138,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "wasm-bindgen-futures", ] [[package]] @@ -2150,6 +2188,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051742038473f3aaada8fc1eb19c76a5354e37e886999d60061f1f303cfc45e8" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + [[package]] name = "jsonrpsee-ws-client" version = "0.20.0" @@ -4078,9 +4127,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.5", ] @@ -4129,11 +4178,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 99096ad5..60004578 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -30,6 +30,9 @@ tracing = "0.1.37" http = "0.2.9" jsonrpsee = { version = "0.20", features = ["http-client", "ws-client"] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +jsonrpsee = { version = "0.20", features = ["wasm-client"] } + [dev-dependencies] libp2p = { workspace = true, features = [ "tokio", diff --git a/rpc/src/client.rs b/rpc/src/client.rs index 3bca86c2..d2ce8913 100644 --- a/rpc/src/client.rs +++ b/rpc/src/client.rs @@ -152,5 +152,86 @@ mod native { #[cfg(target_arch = "wasm32")] mod wasm { - // TODO: implement HttpClient with `fetch` + use std::fmt; + use std::result::Result as StdResult; + + use crate::Result; + use async_trait::async_trait; + use jsonrpsee::core::client::{BatchResponse, ClientT, Subscription, SubscriptionClientT}; + use jsonrpsee::core::params::BatchRequestBuilder; + use jsonrpsee::core::traits::ToRpcParams; + use jsonrpsee::core::Error as JrpcError; + use jsonrpsee::wasm_client::{Client, WasmClientBuilder}; + use serde::de::DeserializeOwned; + + pub struct WasmClient { + client: Client, + } + + impl WasmClient { + pub async fn new(_conn_str: &str) -> Result { + let client = WasmClientBuilder::default().build(_conn_str).await?; + Ok(WasmClient { client }) + } + } + + #[async_trait] + impl ClientT for WasmClient { + async fn notification( + &self, + method: &str, + params: Params, + ) -> StdResult<(), JrpcError> + where + Params: ToRpcParams + Send, + { + self.client.notification(method, params).await + } + + async fn request(&self, method: &str, params: Params) -> StdResult + where + R: DeserializeOwned, + Params: ToRpcParams + Send, + { + self.client.request(method, params).await + } + + async fn batch_request<'a, R>( + &self, + batch: BatchRequestBuilder<'a>, + ) -> StdResult, JrpcError> + where + R: DeserializeOwned + fmt::Debug + 'a, + { + self.client.batch_request(batch).await + } + } + + #[async_trait] + impl SubscriptionClientT for WasmClient { + async fn subscribe<'a, N, Params>( + &self, + subscribe_method: &'a str, + params: Params, + unsubscribe_method: &'a str, + ) -> StdResult, JrpcError> + where + Params: ToRpcParams + Send, + N: DeserializeOwned, + { + self.client + .subscribe(subscribe_method, params, unsubscribe_method) + .await + } + + async fn subscribe_to_method<'a, N>( + &self, + method: &'a str, + ) -> StdResult, JrpcError> + where + N: DeserializeOwned, + { + self.client.subscribe_to_method(method).await + } + } }