jsonrpsee-wasm-client
JSON-RPC WASM client
0.26.0
10M downloads/mo
#3090 most downloaded on crates.io
paritytech/jsonrpsee
What this package is like to depend on
Last release 2 months ago
27 May 2026
Release timing varies
gaps range from 9 days to 7 months
Nearly every release is documented
notes for 43 of 47 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
47 releases · first in 2022
2 releases in the last 12 months
see the full history below
Release timeline
47 releases · Apr 2022 to May 2026Releases
latest 47-
0.26.011 Aug 2025Release notes
Open source →[v0.26.0] - 2025-08-11
This is just a small release; the only breaking change is the addition of
max_frame_sizetoWsTransportClientBuilder, which necessitates a minor version bump.The other changes are as follows:
[Changed]
- Fix new Rust 1.89 lifetime warnings and impl ToRpcParams on serde_json::Map (#1594)
- feat(keepalive): expose tcp keep-alive options (#1583)
- chore: expose
TowerServiceNoHttptype (#1588) - chore(deps): update socket2 requirement from 0.5.1 to 0.6.0 (#1587)
- Allow max websocket frame size to be set (#1585)
- chore(deps): update pprof requirement from 0.14 to 0.15 (#1577)
- Expose
jsonrpsee_http_client::RpcService(#1574)
[Fixed]
- fix: Remove username and password from URL after building Authorization header (#1581)
Release notes
Open source →This is just a small release; the only breaking change is the addition of
max_frame_sizetoWsTransportClientBuilder, which necessitates a minor version bump.The other changes are as follows:
[Changed]
- Fix new Rust 1.89 lifetime warnings and impl ToRpcParams on serde_json::Map (#1594)
- feat(keepalive): expose tcp keep-alive options (#1583)
- chore: expose
TowerServiceNoHttptype (#1588) - chore(deps): update socket2 requirement from 0.5.1 to 0.6.0 (#1587)
- Allow max websocket frame size to be set (#1585)
- chore(deps): update pprof requirement from 0.14 to 0.15 (#1577)
- Expose
jsonrpsee_http_client::RpcService(#1574)
[Fixed]
- fix: Remove username and password from URL after building Authorization header (#1581)
-
0.25.124 Apr 2025Release notes
Open source →[v0.25.1] - 2025-04-24
A small follow-up patch release that adds a
Clone implfor the middleware RpcLogger which was missing
and broke the Clone impl for the HttpClient.If you are updating from v0.24, have a look at https://github.com/paritytech/jsonrpsee/releases/tag/v0.25.0 because it contains some breaking changes.
Full Changelog: v0.25.0...v0.25.1
Release notes
Open source →A small follow-up patch release that adds a
Clone implfor the middleware RpcLogger which was missing and broke the Clone impl for the HttpClient. -
0.25.024 Apr 2025Release notes
Open source →[v0.25.0] - 2025-04-24
A new breaking release which has been in the making for a while and the biggest change is that the
RpcServiceT traithas been changed to support both the client and server side:pub trait RpcServiceT { /// Response type for `RpcServiceT::call`. type MethodResponse; /// Response type for `RpcServiceT::notification`. type NotificationResponse; /// Response type for `RpcServiceT::batch`. type BatchResponse; /// Processes a single JSON-RPC call, which may be a subscription or regular call. fn call<'a>(&self, request: Request<'a>) -> impl Future<Output = Self::MethodResponse> + Send + 'a; /// Processes multiple JSON-RPC calls at once, similar to `RpcServiceT::call`. /// /// This method wraps `RpcServiceT::call` and `RpcServiceT::notification`, /// but the root RPC service does not inherently recognize custom implementations /// of these methods. /// /// As a result, if you have custom logic for individual calls or notifications, /// you must duplicate that implementation in this method or no middleware will be applied /// for calls inside the batch. fn batch<'a>(&self, requests: Batch<'a>) -> impl Future<Output = Self::BatchResponse> + Send + 'a; /// Similar to `RpcServiceT::call` but processes a JSON-RPC notification. fn notification<'a>(&self, n: Notification<'a>) -> impl Future<Output = Self::NotificationResponse> + Send + 'a; }
The reason for this change is to make it work for the client-side as well as make it easier to
implement performantly by relying onimpl Futureinstead of requiring an associated type for theFuture(which in many cases requires boxing).The downside of this change is that one has to duplicate the logic in the
batchandcallmethod to achieve the same
functionality as before. Thus,callornotificationis not being invoked in thebatchmethod and one has to implement
them separately.
For example now it's possible to write middleware that counts the number of method calls as follows (both client and server):#[derive(Clone)] pub struct Counter<S> { service: S, count: Arc<AtomicUsize>, role: &'static str, } impl<S> RpcServiceT for Counter<S> where S: RpcServiceT + Send + Sync + Clone + 'static, { type MethodResponse = S::MethodResponse; type NotificationResponse = S::NotificationResponse; type BatchResponse = S::BatchResponse; fn call<'a>(&self, req: Request<'a>) -> impl Future<Output = Self::MethodResponse> + Send + 'a { let count = self.count.clone(); let service = self.service.clone(); let role = self.role; async move { let rp = service.call(req).await; count.fetch_add(1, Ordering::SeqCst); println!("{role} processed calls={} on the connection", count.load(Ordering::SeqCst)); rp } } fn batch<'a>(&self, batch: Batch<'a>) -> impl Future<Output = Self::BatchResponse> + Send + 'a { let len = batch.len(); self.count.fetch_add(len, Ordering::SeqCst); println!("{} processed calls={} on the connection", self.role, self.count.load(Ordering::SeqCst)); self.service.batch(batch) } fn notification<'a>(&self, n: Notification<'a>) -> impl Future<Output = Self::NotificationResponse> + Send + 'a { self.service.notification(n) } }
In addition because this middleware is quite powerful it's possible to
modify requests and specifically the request ID which should be avoided
because it may break the response verification especially for the client-side.
See #1565 for further information.There are also a couple of other changes see the detailed changelog below.
[Added]
- middleware: RpcServiceT distinct return types for notif, batch, call (#1564)
- middleware: add support for client-side (#1521)
- feat: add namespace_separator option for RPC methods (#1544)
- feat: impl Into for Infallible (#1542)
- client: add
request timeoutgetter (#1533) - server: add example how to close a connection from a rpc handler (method call or subscription) (#1488)
- server: add missing
ServerConfigBuilder::build(#1484)
[Fixed]
- chore(macros): fix typo in proc-macro example (#1482)
- chore(macros): fix typo in internal type name (#1507)
- http middleware: preserve the URI query in ProxyGetRequest::call (#1512)
- http middlware: send original error in ProxyGetRequest (#1516)
- docs: update comment for TOO_BIG_BATCH_RESPONSE_CODE error (#1531)
- fix
http request bodylog (#1540)
[Changed]
- unify usage of JSON via
Box<RawValue>(#1545) - server:
ServerConfigBuilder/ServerConfigreplacesServerBuilderduplicate setter methods (#1487) - server: make
ProxyGetRequestLayerhttp middleware support multiple path-method pairs (#1492) - server: propagate extensions in http response (#1514)
- server: add assert set_message_buffer_capacity (#1530)
- client: add #[derive(Clone)] for HttpClientBuilder (#1498)
- client: add Error::Closed for ws close (#1497)
- client: use native async fn in traits instead async_trait crate (#1551)
- refactor: move to rust edition 2024 (MSRV 1.85) (#1528)
- chore(deps): update tower requirement from 0.4.13 to 0.5.1 (#1455)
- chore(deps): update tower-http requirement from 0.5.2 to 0.6.1 (#1463)
- chore(deps): update pprof requirement from 0.13 to 0.14 (#1493)
- chore(deps): update rustls-platform-verifier requirement from 0.3 to 0.4 (#1489)
- chore(deps): update thiserror requirement from 1 to 2 (#1491)
- chore(deps): bump soketto to 0.8.1 (#1501)
- chore(deps): update rustls-platform-verifier requirement from 0.4 to 0.5 (#1506)
- chore(deps): update fast-socks5 requirement from 0.9.1 to 0.10.0 (#1505)
- chore(deps): tokio ^1.42 (#1511)
- chore: use cargo workspace dependencies (#1502)
- chore(deps): update rand requirement from 0.8 to 0.9 (#1523)
New Contributors
- @Pana made their first contribution in #1482
- @HaoranYi made their first contribution in #1507
- @king-11 made their first contribution in #1519
- @AlexZhenWang made their first contribution in #1531
- @emhane made their first contribution in #1533
- @hai-rise made their first contribution in #1540
- @YakupAltay made their first contribution in #1544
- @Hack666r made their first contribution in #1552
- @petryshkaCODE made their first contribution in #1553
- @mdqst made their first contribution in #1556
Full Changelog: v0.24.9...v0.25.0
Release notes
Open source →A new breaking release which has been in the making for a while and the biggest change is that the
RpcServiceT traithas been changed to support both the client and server side:pub trait RpcServiceT { /// Response type for `RpcServiceT::call`. type MethodResponse; /// Response type for `RpcServiceT::notification`. type NotificationResponse; /// Response type for `RpcServiceT::batch`. type BatchResponse; /// Processes a single JSON-RPC call, which may be a subscription or regular call. fn call<'a>(&self, request: Request<'a>) -> impl Future<Output = Self::MethodResponse> + Send + 'a; /// Processes multiple JSON-RPC calls at once, similar to `RpcServiceT::call`. /// /// This method wraps `RpcServiceT::call` and `RpcServiceT::notification`, /// but the root RPC service does not inherently recognize custom implementations /// of these methods. /// /// As a result, if you have custom logic for individual calls or notifications, /// you must duplicate that implementation in this method or no middleware will be applied /// for calls inside the batch. fn batch<'a>(&self, requests: Batch<'a>) -> impl Future<Output = Self::BatchResponse> + Send + 'a; /// Similar to `RpcServiceT::call` but processes a JSON-RPC notification. fn notification<'a>(&self, n: Notification<'a>) -> impl Future<Output = Self::NotificationResponse> + Send + 'a; }The reason for this change is to make it work for the client-side as well as make it easier to implement performantly by relying on
impl Futureinstead of requiring an associated type for theFuture(which in many cases requires boxing).The downside of this change is that one has to duplicate the logic in the
batchandcallmethod to achieve the same functionality as before. Thus,callornotificationis not being invoked in thebatchmethod and one has to implement them separately. For example now it's possible to write middleware that counts the number of method calls as follows (both client and server):#[derive(Clone)] pub struct Counter<S> { service: S, count: Arc<AtomicUsize>, role: &'static str, } impl<S> RpcServiceT for Counter<S> where S: RpcServiceT + Send + Sync + Clone + 'static, { type MethodResponse = S::MethodResponse; type NotificationResponse = S::NotificationResponse; type BatchResponse = S::BatchResponse; fn call<'a>(&self, req: Request<'a>) -> impl Future<Output = Self::MethodResponse> + Send + 'a { let count = self.count.clone(); let service = self.service.clone(); let role = self.role; async move { let rp = service.call(req).await; count.fetch_add(1, Ordering::SeqCst); println!("{role} processed calls={} on the connection", count.load(Ordering::SeqCst)); rp } } fn batch<'a>(&self, batch: Batch<'a>) -> impl Future<Output = Self::BatchResponse> + Send + 'a { let len = batch.len(); self.count.fetch_add(len, Ordering::SeqCst); println!("{} processed calls={} on the connection", self.role, self.count.load(Ordering::SeqCst)); self.service.batch(batch) } fn notification<'a>(&self, n: Notification<'a>) -> impl Future<Output = Self::NotificationResponse> + Send + 'a { self.service.notification(n) } }In addition because this middleware is quite powerful it's possible to modify requests and specifically the request ID which should be avoided because it may break the response verification especially for the client-side. See https://github.com/paritytech/jsonrpsee/issues/1565 for further information.
There are also a couple of other changes see the detailed changelog below.
[Added]
- middleware: RpcServiceT distinct return types for notif, batch, call (#1564)
- middleware: add support for client-side (#1521)
- feat: add namespace_separator option for RPC methods (#1544)
- feat: impl Into<ErrorObject> for Infallible (#1542)
- client: add
request timeoutgetter (#1533) - server: add example how to close a connection from a rpc handler (method call or subscription) (#1488)
- server: add missing
ServerConfigBuilder::build(#1484)
[Fixed]
- chore(macros): fix typo in proc-macro example (#1482)
- chore(macros): fix typo in internal type name (#1507)
- http middleware: preserve the URI query in ProxyGetRequest::call (#1512)
- http middlware: send original error in ProxyGetRequest (#1516)
- docs: update comment for TOO_BIG_BATCH_RESPONSE_CODE error (#1531)
- fix
http request bodylog (#1540)
[Changed]
- unify usage of JSON via
Box<RawValue>(#1545) - server:
ServerConfigBuilder/ServerConfigreplacesServerBuilderduplicate setter methods (#1487) - server: make
ProxyGetRequestLayerhttp middleware support multiple path-method pairs (#1492) - server: propagate extensions in http response (#1514)
- server: add assert set_message_buffer_capacity (#1530)
- client: add #[derive(Clone)] for HttpClientBuilder (#1498)
- client: add Error::Closed for ws close (#1497)
- client: use native async fn in traits instead async_trait crate (#1551)
- refactor: move to rust edition 2024 (MSRV 1.85) (#1528)
- chore(deps): update tower requirement from 0.4.13 to 0.5.1 (#1455)
- chore(deps): update tower-http requirement from 0.5.2 to 0.6.1 (#1463)
- chore(deps): update pprof requirement from 0.13 to 0.14 (#1493)
- chore(deps): update rustls-platform-verifier requirement from 0.3 to 0.4 (#1489)
- chore(deps): update thiserror requirement from 1 to 2 (#1491)
- chore(deps): bump soketto to 0.8.1 (#1501)
- chore(deps): update rustls-platform-verifier requirement from 0.4 to 0.5 (#1506)
- chore(deps): update fast-socks5 requirement from 0.9.1 to 0.10.0 (#1505)
- chore(deps): tokio ^1.42 (#1511)
- chore: use cargo workspace dependencies (#1502)
- chore(deps): update rand requirement from 0.8 to 0.9 (#1523)
-
0.24.1127 May 2026Nothing published for this version
-
0.24.1022 Oct 2025Nothing published for this version
-
0.24.917 Mar 2025Release notes
Open source →[v0.24.9] - 2024-03-17
This is a non-breaking release that updates the dependency
rust-platform-verifierto v0.5 to fix that
thatrust-platform-verifierv0.3 didn't enable thestd featureinrustlswhich caused a compilation error.See #1536 for further information.
Thanks to the external contributor @prestwich who spotted and fixed this issue.
Release notes
Open source →This is a non-breaking release that updates the dependency
rust-platform-verifierto v0.5 to fix that thatrust-platform-verifierv0.3 didn't enable thestd featureinrustlswhich caused a compilation error. See https://github.com/paritytech/jsonrpsee/issues/1536 for further information.Thanks to the external contributor @prestwich who spotted and fixed this issue.
-
0.24.824 Jan 2025Release notes
Open source →[v0.24.8] - 2024-01-24
This is a non-breaking release that decreases the MSRV to 1.74.0.
[Changed]
- reduce MSRV to 1.74.0 (#1519)
Full Changelog: v0.24.7...v0.24.8
Release notes
Open source →This is a non-breaking release that decreases the MSRV to 1.74.0.
[Changed]
- reduce MSRV to 1.74.0 (#1519)
-
0.24.716 Oct 2024Release notes
Open source →[v0.24.7] - 2024-10-16
This is a patch release that mainly fixes the tower::Service implementation to be generic over the HttpBody to work with all middleware layers. For instance, this makes
tower_http::compression::CompressionLayerwork, which didn't compile before.[Added]
- http client: add
max_concurrent_requests(#1473)
[Fixed]
- fix(server): make tower::Service impl generic over HttpBody (#1475)
New Contributors
- @hanabi1224 made their first contribution in #1475
Full Changelog: v0.24.6...v0.24.7
Release notes
Open source →This is a patch release that mainly fixes the tower::Service implementation to be generic over the HttpBody to work with all middleware layers. For instance, this makes
tower_http::compression::CompressionLayerwork, which didn't compile before.[Added]
- http client: add
max_concurrent_requests(#1473)
[Fixed]
- fix(server): make tower::Service impl generic over HttpBody (#1475)
Thanks to the external contributor @hanabi1224 who contributed to this release.
- http client: add
-
0.24.607 Oct 2024Release notes
Open source →[v0.24.6] - 2024-10-07
This is a bug-fix release that fixes that the
ConnectionGuardwas dropped before the future was resolved which,
could lead to that HTTP calls were not counted correctly in theConnectionGuard. This impacts only the server.[Fixed]
- fix(server): count http calls in connection guard (#1468)
Full Changelog: v0.24.5...v0.24.6
Release notes
Open source →This is a bug-fix release that fixes that the
ConnectionGuardwas dropped before the future was resolved which, could lead to that HTTP calls were not counted correctly in theConnectionGuard. This impacts only the server.[Fixed]
- fix(server): count http calls in connection guard (#1468)
-
0.24.526 Sep 2024Release notes
Open source →[v0.24.5] - 2024-09-26
This is a patch release that mainly fixes a compilation issue for the server because the feature
tower/utilwas not enabled.[Fixed]
- server: Enable tower util feature (#1464)
[Changed]
- server: change
http method_not_allowedmessage (#1452)
New Contributors
- @IkerAlus made their first contribution in #1454
- @dcfreire made their first contribution in #1452
- @FabianLars made their first contribution in #1464
Full Changelog: v0.24.4...v0.24.5
Release notes
Open source →This is a patch release that mainly fixes a compilation issue for the server because the feature
tower/utilwas not enabled.[Fixed]
- server: Enable tower util feature (#1464)
[Changed]
- server: change
http method_not_allowedmessage (#1452)
-
0.24.411 Sep 2024Release notes
Open source →This is non-breaking release that changes the error variants to be
thiserror(transparent)for wrapped errors and adds ConnectionGuard to the extensions to make it possible to get the number of active connections.[Added]
- server: expose ConnectionGuard as request extension (#1443)
[Fixed]
- types: use error(transparent) for wrapped errors when possible (#1449)
-
0.24.314 Aug 2024Release notes
Open source →This is a small release that adds two new APIs to inject data via the extensions to the
RpcModule/Methodsand it only impacts users that are using RpcModule directly viaMethods::call/subscribe/raw_json_request(e.g., unit testing) and not the server itself.[Added]
- feat(server): add
Methods::extensions/extensions_mut(#1440)
- feat(server): add
-
0.24.202 Aug 2024Release notes
Open source →Another small release that fixes:
- Notifications without params were not handled correctly in the client, which been has been fixed.
- Improve compile times and reduce code-generation in the proc macro crate.
[Fixed]
Thanks to the external contributor @DaniPopes who contributed to this release.
-
0.24.130 Jul 2024Release notes
Open source →This is a small release that forces jsonrpsee
rustlsto use the crypto backend ring which may panic if bothringandaws-lcfeatures are enabled. See https://github.com/rustls/rustls/issues/1877 for further information.This has no impact on the default configuration of jsonrpsee which was already using
ringas the default.[Changed]
- chore(deps): update gloo-net requirement from 0.5.0 to 0.6.0 (#1428)
[Fixed]
- fix: Explicitly set rustls provider before using rustls (#1424)
-
0.24.009 Jul 2024Release notes
Open source →A breaking release that mainly changes:
tlsfeature for the client has been divided intotlsandtls-platform-verifierwhere thetlsfeature will only includerustlsand no specific certificate store but the default one is stilltls-rustls-platform-verifier. This is useful if one wants to avoid bring on openssl dependencies.- Remove dependencies
anyhowandbeeffrom the codebase.
[Changed]
-
0.23.226 Jun 2024Release notes
Open source →This a small patch release that fixes a couple of bugs and adds a couple of new APIs.
The bug fixes are:
- The
server::ws::on_connectwas not working properly due to a merge nit when upgrading to hyper v1.0 This impacts only users that are using the low-level API and not the server itself. WsTransport::build_with_streamshouldn't not resolve the socket addresses and it's fixed now, see #1411 for further info. This impacts users that are inject their own TcpStream directly into theWsTransport.
[Added]
- server: add
RpcModule::remove(#1416) - server: add
capacity and max_capacityto the subscription API (#1414) - server: add
PendingSubscriptionSink::method_name(#1413)
[Fixed]
- The
-
0.23.110 Jun 2024Release notes
Open source →This is a patch release that injects the ConnectionId in the extensions when using a RpcModule without a server. This impacts users that are using RpcModule directly (e.g., unit testing) and not the server itself.
[Changed]
- types: remove anyhow dependency (#1398)
[Fixed]
- rpc module: inject ConnectionId in extensions (#1399)
-
0.23.007 Jun 2024Release notes
Open source →This is a new breaking release, and let's go through the changes.
hyper v1.0
jsonrpsee has been upgraded to use hyper v1.0 and this mainly impacts users that are using the low-level API and rely on the
hyper::service::make_service_fnwhich has been removed, and from now on you need to manage the socket yourself.The
hyper::service::make_service_fncan be replaced by the following example template:async fn start_server() { let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); loop { let sock = tokio::select! { res = listener.accept() => { match res { Ok((stream, _remote_addr)) => stream, Err(e) => { tracing::error!("failed to accept v4 connection: {:?}", e); continue; } } } _ = per_conn.stop_handle.clone().shutdown() => break, }; let svc = tower::service_fn(move |req: hyper::Request<hyper::body::Incoming>| { let mut jsonrpsee_svc = svc_builder .set_rpc_middleware(rpc_middleware) .build(methods, stop_handle); // https://github.com/rust-lang/rust/issues/102211 the error type can't be inferred // to be `Box<dyn std::error::Error + Send + Sync>` so we need to convert it to a concrete type // as workaround. jsonrpsee_svc .call(req) .await .map_err(|e| anyhow::anyhow!("{:?}", e)) }); tokio::spawn(jsonrpsee::server::serve_with_graceful_shutdown( sock, svc, stop_handle.clone().shutdown(), )); } }Also, be aware that
tower::service_fnandhyper::service::service_fnare different and it's recommended to usetower::service_fnfrom now.Extensions
Because it was not possible/easy to share state between RPC middleware layers jsonrpsee has added
Extensionsto the Request and Response. To allow users to inject arbitrary data that can be accessed in the RPC middleware and RPC handlers.Please be careful when injecting large amounts of data into the extensions because It's cloned for each RPC call, which can increase memory usage significantly.
The connection ID from the jsonrpsee-server is injected in the extensions by default. and it is possible to fetch it as follows:
struct LogConnectionId<S>(S); impl<'a, S: RpcServiceT<'a>> RpcServiceT<'a> for LogConnectionId<S> { type Future = S::Future; fn call(&self, request: jsonrpsee::types::Request<'a>) -> Self::Future { let conn_id = request.extensions().get::<ConnectionId>().unwrap(); tracing::info!("Connection ID {}", conn_id.0); self.0.call(request) } }In addition the
Extensionsis not added in the proc-macro API by default and one has to enablewith_extensionsattr for that to be available:#[rpc(client, server)] pub trait Rpc { // legacy #[method(name = "foo"]) async fn async_method(&self) -> u16>; // with extensions #[method(name = "with_ext", with_extensions)] async fn f(&self) -> bool; } impl RpcServer for () { async fn async_method(&self) -> u16 { 12 } // NOTE: ext is injected just after self in the API async fn f(&self, ext: &Extensions: b: String) -> { ext.get::<u32>().is_ok() } }client - TLS certificate store changed
The default TLS certificate store has been changed to
rustls-platform-verifierto decide the best certificate store for each platform.In addition it's now possible to inject a custom certificate store if one wants need some special certificate store.
client - Subscription API modified
The subscription API has been modified:
- The error type has been changed to
serde_json::Errorto indicate that error can only occur if the decoding of T fails. - It has been some confusion when the subscription is closed which can occur if the client "lagged" or the connection is closed.
Now it's possible to call
Subscription::close_reasonafter the subscription closed (i.e. has return None) to know why.
If one wants to replace old messages in case of lagging it is recommended to write your own adaptor on top of the subscription:
fn drop_oldest_when_lagging<T: Clone + DeserializeOwned + Send + Sync + 'static>( mut sub: Subscription<T>, buffer_size: usize, ) -> impl Stream<Item = Result<T, BroadcastStreamRecvError>> { let (tx, rx) = tokio::sync::broadcast::channel(buffer_size); tokio::spawn(async move { // Poll the subscription which ignores errors while let Some(n) = sub.next().await { let msg = match n { Ok(msg) => msg, Err(e) => { tracing::error!("Failed to decode the subscription message: {e}"); continue; } }; // Only fails if the receiver has been dropped if tx.send(msg).is_err() { return; } } }); BroadcastStream::new(rx) }[Added]
- server: add
serveandserve_with_graceful_shutdownhelpers (#1382) - server: pass
extensionsfrom http layer (#1389) - macros: add macro attr
with_extensions(#1380) - server: inject connection id in extensions (#1381)
- feat: add
Extensionsto Request/MethodResponse (#1306) - proc-macros: rename parameter names (#1365)
- client: add
Subscription::close_reason(#1320)
[Changed]
- chore(deps): tokio ^1.23.1 (#1393)
- server: use
ConnectionIdin subscription APIs (#1392) - server: add logs when connection closed by
ws ping/pong(#1386) - client: set
authorization headerfrom the URL (#1384) - client: use rustls-platform-verifier cert store (#1373)
- client: remove MaxSlots limit (#1377)
- upgrade to hyper v1.0 (#1368)
- The error type has been changed to
-
0.22.529 Apr 2024Release notes
Open source →A small bug-fix release, see each commit below for further information.
[Fixed]
-
0.22.408 Apr 2024Release notes
Open source →Yet another rather small release that fixes a cancel-safety issue that could cause an unexpected panic when reading disconnect reason from the background task.
Also this makes the API
Client::disconnect_reasoncancel-safe.[Added]
[Changed]
- client: downgrade logs from error/warn -> debug (#1343)
[Fixed]
-
0.22.320 Mar 2024Release notes
Open source →Another small release that adds a new API for RpcModule if one already has the state in an
Arcand a couple of bug fixes.[Added]
- add
RpcModule::from_arc(#1324)
[Fixed]
- Revert "fix(server): return err on WS handshake err (#1288)" (#1326)
- export
AlreadyStoppedError(#1325)
Thanks to the external contributors @mattsse and @aatifsyed who contributed to this release.
- add
-
0.22.205 Mar 2024Release notes
Open source →This is a small patch release that exposes the connection details in server method implementations without breaking changes. We plan to extend this functionality in jsonrpsee v1.0, although this will necessitate a breaking change.
[Added]
- server: Register raw method with connection ID (#1297)
[Changed]
- Update Syn 1.0 -> 2.0 (#1304)
-
0.22.119 Feb 2024Release notes
Open source →This is a small patch release that internally changes
AtomicU64toAtomicUsizeto support more targets.[Fixed]
-
0.22.007 Feb 2024Release notes
Open source →Another breaking release where a new
ResponsePayloadtype is introduced in order to make it possible to determine whether a response has been processed.Unfortunately, the
IntoResponse traitwas modified to enable that and some minor changes were made to make more fields private to avoid further breakage.Example of the async
ResponsePayload API#[rpc(server)] pub trait Api { #[method(name = "x")] fn x(&self) -> ResponsePayload<'static, String>; } impl RpcServer for () { fn x(&self) -> ResponsePayload<'static, String> { let (rp, rp_done) = ResponsePayload::success("ehheeheh".to_string()).notify_on_completion(); tokio::spawn(async move { if rp_done.await.is_ok() { do_task_that_depend_x(); } }); rp } }Roadmap
We are getting closer to releasing jsonrpsee v1.0 and the following work is planned:
- Native async traits
- Upgrade hyper to v1.0
- Better subscription API for the client.
Thanks to the external contributor @dan-starkware who contributed to this release.
[Added]
- feat(server): add
TowerService::on_session_close(#1284) - feat(server): async API when
Responsehas been processed. (#1281)
[Changed]
-
0.21.013 Dec 2023Release notes
Open source →This release contains big changes and let's go over the main ones:
JSON-RPC specific middleware
After getting plenty of feedback regarding a JSON-RPC specific middleware, this release introduces a composable "tower-like" middleware that applies per JSON-RPC method call. The new middleware also replaces the old
RpcLoggerwhich may break some use-cases, such as if JSON-RPC was made on a WebSocket or HTTP transport, but it's possible to implement that by usingjsonrpsee as a tower serviceorthe low-level server API.An example how write such middleware:
#[derive(Clone)] pub struct ModifyRequestIf<S>(S); impl<'a, S> RpcServiceT<'a> for ModifyRequestIf<S> where S: Send + Sync + RpcServiceT<'a>, { type Future = S::Future; fn call(&self, mut req: Request<'a>) -> Self::Future { // Example how to modify the params in the call. if req.method == "say_hello" { // It's a bit awkward to create new params in the request // but this shows how to do it. let raw_value = serde_json::value::to_raw_value("myparams").unwrap(); req.params = Some(StdCow::Owned(raw_value)); } // Re-direct all calls that isn't `say_hello` to `say_goodbye` else if req.method != "say_hello" { req.method = "say_goodbye".into(); } self.0.call(req) } } async fn run_server() { // Construct our middleware and build the server. let rpc_middleware = RpcServiceBuilder::new().layer_fn(|service| ModifyRequestIf(service)); let server = Server::builder().set_rpc_middleware(rpc_middleware).build("127.0.0.1:0").await.unwrap(); // Start the server. let mut module = RpcModule::new(()); module.register_method("say_hello", |_, _| "lo").unwrap(); module.register_method("say_goodbye", |_, _| "goodbye").unwrap(); let handle = server.start(module); handle.stopped().await; }jsonrpsee server as a tower service
For users who want to get full control of the HTTP request, it's now possible to utilize jsonrpsee as a tower service example here
jsonrpsee server low-level API
For users who want to get low-level access and for example to disconnect misbehaving peers that is now possible as well example here
Logging in the server
Logging of RPC calls has been disabled by default, but it's possible to enable that with the RPC logger middleware or provide your own middleware for that.
let rpc_middleware = RpcServiceBuilder::new().rpc_logger(1024); let server = Server::builder().set_rpc_middleware(rpc_middleware).build("127.0.0.1:0").await?;WebSocket ping/pong API
The WebSocket ping/pong APIs have been refactored to be able to disconnect inactive connections both by from the server and client-side.
Thanks to the external contributors @oleonardolima and @venugopv who contributed to this release.
[Changed]
- chore(deps): update tokio-rustls requirement from 0.24 to 0.25 (#1256)
- chore(deps): update gloo-net requirement from 0.4.0 to 0.5.0 (#1260)
- chore(deps): update async-lock requirement from 2.4 to 3.0 (#1226)
- chore(deps): update proc-macro-crate requirement from 1 to 2 (#1211)
- chore(deps): update console-subscriber requirement from 0.1.8 to 0.2.0 (#1210)
- refactor: split client and server errors (#1122)
- refactor(ws client): impl tokio:{AsyncRead, AsyncWrite} for EitherStream (#1249)
- refactor(http client): enable all http versions (#1252)
- refactor(server): change ws ping API (#1248)
- refactor(ws client): generic over data stream (#1168)
- refactor(client): unify ws ping/pong API with the server (#1258
- refactor: set
tcp_nodelay == trueby default ([#1263])(https://github.com/paritytech/jsonrpsee/pull/1263)
[Added]
- feat(client): add
disconnect_reasonAPI (#1246) - feat(server): jsonrpsee as
serviceandlow-level API for more fine-grained API to disconnect peers etc(#1224) - feat(server): JSON-RPC specific middleware (#1215)
- feat(middleware): add
HostFilterLayer::disable(#1213)
[Fixed]
- fix(host filtering): support hosts with multiple ports (#1227)
-
0.20.424 Aug 2024Nothing published for this version
-
0.20.324 Oct 2023Release notes
Open source →This release fixes a cancel-safety issue in the server's graceful shutdown which could lead to high CPU usage.
[Fixed]
-
0.20.213 Oct 2023Release notes
Open source →This release removes the bounded buffer check which was intended to provide backpressure all the way down to the TCP layer but it didn't work well.
For subscriptions the backpressure will be handled by implementation itself and just rely on that.
[Changed]
- server: remove bounded channel check (#1209)
-
0.20.115 Sep 2023Release notes
Open source →This release adds support for
synchronous subscriptionsand fixes a leak in WebSocket server where FuturesUnordered was not getting polled until shutdown, so it was accumulating tasks forever.[Changed]
- client: downgrade log for unknown subscription to DEBUG (#1185)
- refactor(http client): use HTTP connector on http URLs (#1187)
- refactor(server): less alloc per method call (#1188)
[Fixed]
- fix: remove needless clone in ws background task (#1203)
- async client: save latest Waker (#1198)
- chore(deps): bump actions/checkout from 3.6.0 to 4.0.0 (#1197)
- fix(server): fix leak in FuturesUnordered (#1204)
[Added]
- feat(server): add sync subscription API
register_subscription_raw(#1182)
-
0.20.011 Aug 2023Release notes
Open source →Another breaking release where the major changes are:
host filteringhas been moved to tower middleware instead of the server API.- the clients now supports default port number such
wss://my.server.com - the background task for the async client has been refactored to multiplex send and read operations.
Regarding host filtering prior to this release one had to do:
let acl = AllowHosts::Only(vec!["http://localhost:*".into(), "http://127.0.0.1:*".into()]); let server = ServerBuilder::default().set_host_filtering(acl).build("127.0.0.1:0").await.unwrap();After this release then one have to do:
let middleware = tower::ServiceBuilder::new().layer(HostFilterLayer::new(["example.com"]).unwrap()); let server = Server::builder().set_middleware(middleware).build("127.0.0.1:0".parse::<SocketAddr>()?).await?;Thanks to the external contributors @polachok, @bobs4462 and @aj3n that contributed to this release.
[Added]
- feat(server): add
SubscriptionMessage::new(#1176) - feat(server): add
SubscriptionSink::connection_id(#1175) - feat(server): add
Params::get(#1173) - feat(server): add
PendingSubscriptionSink::connection_id(#1163)
[Fixed]
- fix(server): host filtering URI read authority (#1178)
[Changed]
- refactor: make ErrorObject::borrowed accept
&str(#1160) - refactor(client): support default port number (#1172)
- refactor(server): server host filtering (#1174)
- refactor(client): refactor background task (#1145)
- refactor: use
RootCertStore::add_trust_anchors(#1165) - chore(deps): update criterion v0.5 and pprof 0.12 (#1161)
- chore(deps): update webpki-roots requirement from 0.24 to 0.25 (#1158)
- refactor(server): move host filtering to tower middleware (#1179)
-
0.19.024 Jul 2023Release notes
Open source →[Fixed]
- Fixed connections processing await on server shutdown (#1153)
- fix: include error code in RpcLogger (#1135)
- fix: downgrade more logs to
debug(#1127) - fix(server): remove
MethodSinkPermitto fix backpressure issue on concurrent subscriptions (#1126) - fix readme links (#1152)
[Changed]
-
0.18.211 May 2023Release notes
Open source →This release improves error message for
too big batch responseand exposes theBatchRequestConfig typein order to make it possible to useServerBuilder::set_batch_request_config[Fixed]
-
0.18.127 Apr 2023Release notes
Open source →This release fixes a couple bugs and improves the ergonomics for the HTTP client when no tower middleware is enabled.
[Changed]
- http client: add default generic param for the backend (#1099)
[Fixed]
-
0.18.024 Apr 2023Release notes
Open source →This is a breaking release that removes the
CallErrorwhich was used to represent a JSON-RPC error object that could happen during JSON-RPC method call and one could assign application specific error code, message and data in a specific implementation.Previously jsonrpsee provided
CallErrorthat could be converted to/fromjsonrpsee::core::Errorand in some scenarios the error code was automatically assigned by jsonrpsee. After jsonrpsee added support for custom error types theCallErrordoesn't provide any benefit because one has to implementInto<ErrorObjectOwned>on the error type anyway.Thus,
jsonrpsee::core::Errorcan't be used in the proc macro API anymore and the type aliasRpcResulthas been modified toResult<(), ErrorObjectOwned>instead.Before it was possible to do:
#[derive(thiserror::Error)] enum Error { A, B, } #[rpc(server, client)] pub trait Rpc { #[method(name = "getKeys")] async fn keys(&self) -> Result<String, jsonrpsee::core::Error> { Err(jsonrpsee::core::Error::to_call_error(Error::A)) // or jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned(1, "a", None::<()>))) } }After this change one has to do:
pub enum Error { A, B, } impl From<Error> for ErrorObjectOwned { fn from(e: Error) -> Self { match e { Error::A => ErrorObject::owned(1, "a", None::<()>), Error::B => ErrorObject::owned(2, "b", None::<()>), } } } #[rpc(server, client)] pub trait Rpc { // Use a custom error type that implements `Into<ErrorObject>` #[method(name = "custom_err_ty")] async fn custom_err_type(&self) -> Result<String, Error> { Err(Error::A) } // Use `ErrorObject` as error type directly. #[method(name = "err_obj")] async fn error_obj(&self) -> RpcResult<String> { Err(ErrorObjectOwned::owned(1, "c", None::<()>)) } }[Changed]
- remove
CallError(#1087)
[Fixed]
- fix(proc macros): support parsing params !Result (#1094)
- remove
-
0.17.121 Apr 2023Release notes
Open source →This release fixes HTTP graceful shutdown for the server.
[Fixed]
- server: fix http graceful shutdown (#1090)
-
0.17.018 Apr 2023Release notes
Open source →This is a significant release and the major breaking changes to be aware of are:
Server backpressure
This release changes the server to be "backpressured" and it mostly concerns subscriptions. New APIs has been introduced because of that and the API
pipe_from_streamhas been removed.Before it was possible to do:
module .register_subscription("sub", "s", "unsub", |_, sink, _| async move { let stream = stream_of_integers(); tokio::spawn(async move { sink.pipe_from_stream(stream) }); }) .unwrap();After this release one must do something like:
// This is just a example helper. // // Other examples: // - <https://github.com/paritytech/jsonrpsee/blob/master/examples/examples/ws_pubsub_broadcast.rs> // - <https://github.com/paritytech/jsonrpsee/blob/master/examples/examples/ws_pubsub_with_params.rs> async fn pipe_from_stream<T: Serialize>( pending: PendingSubscriptionSink, mut stream: impl Stream<Item = T> + Unpin, ) -> Result<(), anyhow::Error> { let mut sink = pending.accept().await?; loop { tokio::select! { _ = sink.closed() => break Ok(()), maybe_item = stream.next() => { let Some(item) = match maybe_item else { break Ok(()), }; let msg = SubscriptionMessage::from_json(&item)?; if let Err(e) = sink.send_timeout(msg, Duration::from_secs(60)).await { match e { // The subscription or connection was closed. SendTimeoutError::Closed(_) => break Ok(()), /// The subscription send timeout expired /// the message is returned and you could save that message /// and retry again later. SendTimeoutError::Timeout(_) => break Err(anyhow::anyhow!("Subscription timeout expired")), } } } } } } module .register_subscription("sub", "s", "unsub", |_, pending, _, _| async move { let stream = stream(); pipe_from_stream(sink, stream).await }) .unwrap();Method call return type is more flexible
This release also introduces a trait called
IntoResponsewhich is makes it possible to return custom types and/or error types instead of enforcing everything to returnResult<T, jsonrpsee::core::Error>This affects the APIs
RpcModule::register_method,RpcModule::register_async_methodandRpcModule::register_blocking_methodand when these are used in the proc macro API are affected by this change. Be aware that the client APIs don't support this yetThe
IntoResponsetrait is already implemented forResult<T, jsonrpsee::core::Error>and for the primitive typesBefore it was possible to do:
// This would return Result<&str, jsonrpsee::core::Error> module.register_method("say_hello", |_, _| Ok("lo"))?;After this release it's possible to do:
// Note, this method call is infallible and you might not want to return Result. module.register_method("say_hello", |_, _| "lo")?;Subscription API is changed.
jsonrpsee now spawns the subscriptions via
tokio::spawnand it's sufficient to provide an async block inregister_subscriptionFurther, the subscription API had an explicit close API for closing subscriptions which was hard to understand and to get right. This has been removed and everything is handled by the return value/type of the async block instead.
Example:
module .register_subscription::<RpcResult<(), _, _>::("sub", "s", "unsub", |_, pending, _, _| async move { // This just answers the RPC call and if this fails => no close notification is sent out. pending.accept().await?; // This is sent out as a `close notification/message`. Err(anyhow::anyhow!("The subscription failed"))?; }) .unwrap();The return value in the example above needs to implement
IntoSubscriptionCloseResponseand any value that is returned after that the subscription has been accepted will be treated as aIntoSubscriptionCloseResponse.Because
Result<(), E>is used here the close notification will be sent out as error notification but it's possible to disable the subscription close response by using()instead ofResult<(), E>or implementIntoSubscriptionCloseResponsefor other behaviour.[Added]
- feat(server): configurable limit for batch requests. (#1073)
- feat(http client): add tower middleware (#981)
[Fixed]
- add tests for ErrorObject (#1078)
- fix: tokio v1.27 (#1062)
- fix: remove needless
Semaphore::(u32::MAX)(#1051) - fix server: don't send error on JSON-RPC notifications (#1021)
- fix: add
max_log_lengthAPIs and use missing configs (#956) - fix(rpc module): subscription close bug (#1011)
- fix: customized server error codes (#1004)
[Changed]
- docs: introduce workspace attributes and add keywords (#1077)
- refactor(server): downgrade connection log (#1076)
- chore(deps): update webpki-roots and tls (#1068)
- rpc module: refactor subscriptions to return
impl IntoSubscriptionResponse(#1034) - add
IntoResponsetrait for method calls (#1057) - Make
jsonrpcprotocol version field inResponseasOption(#1046) - server: remove dependency http (#1037)
- chore(deps): update tower-http requirement from 0.3.4 to 0.4.0 (#1033)
- chore(deps): update socket2 requirement from 0.4.7 to 0.5.1 (#1032)
- Update bound type name (#1029)
- rpc module: remove
SubscriptionAnswer(#1025) - make verify_and_insert pub (#1028)
- update MethodKind (#1026)
- remove batch response (#1020)
- remove debug log (#1024)
- client: rename
max_notifs_per_subscriptiontomax_buffer_capacity_per_subscription(#1012) - client: feature gate tls cert store (#994)
- server: bounded channels and backpressure (#962)
- client: use tokio channels (#999)
- chore: update gloo-net ^0.2.6 (#978)
- Custom errors (#977)
- client: distinct APIs to configure max request and response sizes (#967)
- server: replace
FutureDriverwithtokio::spawn(#1080) - server: uniform whitespace handling in rpc calls (#1082)
-
0.16.323 Aug 2023Nothing published for this version
-
0.16.201 Dec 2022 -
0.16.118 Nov 2022Release notes
Open source →v0.16.1 is release that adds two new APIs to server
http_onlyandws_onlyto make it possible to allow only HTTP respectively WebSocket.Both HTTP and WebSocket are still enabled by default.
[Fixed]
- docs: remove outdated features (#938)
- docs: http client url typo in examples (#940)
- core: remove unused dependency
async-channel(#940)
[Added]
- server: make it possible to enable ws/http only (#939)
-
0.16.009 Nov 2022Release notes
Open source →v0.16.0 is a breaking release and the major changes are:
- The server now support WS and HTTP on the same socket and the
jsonrpsee-http-serverandjsonrpsee-ws-servercrates are moved to thejsonrpsee-servercrate instead. - The client batch request API is improved such as the errors and valid responses can be iterated over.
- The server has
tower middlewaresupport. - The server now adds a tracing span for each connection to distinguish logs per connection.
- CORS has been moved to
tower middleware.
[Fixed]
- server: read accepted conns properly (#929)
- server: proper handling of batch errors and mixed calls (#917)
- jsonrpsee: add
typesto server feature (#891) - http client: more user-friendly error messages when decoding fails (#853)
- http_server: handle http2 requests host filtering correctly (#866)
- server:
RpcModule::calldecode response correctly (#839)
[Added]
- proc macro: support camelCase & snake_case for object params (#921)
- server: add connection span (#922)
- server: Expose the subscription ID (#900)
- jsonrpsee wrapper crate: add feature async_wasm_client (#893)
- server: add
transport protocol detailsto the logger trait (#886) - middleware: Implement proxy URI paths to RPC methods (#859)
- client: Implement
notify_on_disconnect(#837) - Add
bytes_len()to Params (#848) - Benchmarks for different HTTP header sizes (#824)
[Changed]
- replace
WS and HTTP serverswith a server that supports bothWS and HTTP(#863) - Optimize serialization for client parameters (#864)
- Uniform log messages (#855)
- Move CORS logic to tower middleware CorsLayer (#851)
- server: add log for the http request (#854)
- server: add
towersupport (#831) - jsonrpsee: less deps when defining RPC API. (#849)
- server: rename
MiddlewaretoLogger(#845) - client: adjust TransportSenderT (#852)
- client: improve batch request API (#910)
- server: Optimize sending for
SubscriptionSink::pipe_from_stream(#901) - ws-client: downgrade connection log to debug (#865)
- use tracing instrument macro (#846)
- The server now support WS and HTTP on the same socket and the
-
0.15.129 Jul 2022Release notes
Open source →This release fixes some incorrect tracing spans.
[Fixed]
- [Bug Fix] - Incorrect trace caused by use of Span::enter in asynchronous code #835
-
0.15.021 Jul 2022Release notes
Open source →v0.15.0 is a breaking release. The main changes are:
- It's now possible to apply resource limits to subscriptions as well as regular calls.
- We now allow trait bounds to be overridden in the proc macros. See
examples/examples/proc_macro_bounds.rsfor examples. - We've tidied up the subscription API, removing the
PendingSinkconcept (you can still manually accept or reject a sink, but otherwise it'll be accepted automatically if you send a message down it) (#799). - Our logging
Middlewaretrait has been split intoHttpMiddlewareandWsMiddlewareto better capture the differences between the two. if you use custom middleware, you'll need to implement one or the other trait on it depending on your used transport method (#793). We also provide params and the method type to middleware calls now, too (#820). - We've consistified the API for setting headers across HTTP and WS clients (#799).
Here's the full list of changes:
[Fixed]
- Fix client generation with param_kind = map #805
- ws-server: Handle soketto::Incoming::Closed frames #815
- fix(ws server): reply HTTP 403 on all failed conns #819
- fix clippy #817
[Added]
- Add resource limiting for Subscriptions #786
- feat(logging): add tracing span per JSON-RPC call #722
- feat(clients): add explicit unsubscribe API #789
- Allow trait bounds to be overridden in macro #808
[Changed]
- Point to a new v1.0 milestone in the README.md #801
- chore(deps): upgrade tracing v0.1.34 #800
- Replace cargo-nextest with cargo-test for running tests #802
- Remove deny_unknown_fields from Request and Response #803
- substrate-subxt -> subxt #807
- chore(deps): update pprof requirement from 0.9 to 0.10 #810
- Return error from subscription callbacks #799
- middleware refactoring #793
- feat(middleware): expose type of the method call #820
- Uniform API for custom headers between clients #814
- Update links to client directories. #822
-
0.14.014 Jun 2022Release notes
Open source →v0.14.0 is breaking release which changes the
health and access control APIsand a bunch of bug fixes.[Fixed]
- fix(servers): more descriptive errors when calls fail #790
- fix(ws server): support
*in host and origin filtering #781 - fix(rpc module): register failed
unsubscribe callsin middleware #792 - fix(http server): omit jsonrpc details in health API #785
- fix(servers): skip leading whitespace in JSON deserialization #783
- fix(ws-server): Submit ping regardless of WS messages #788
- fix(rpc_module): remove expect in
fn call#774
[Added]
- feat(ws-client):
ping-pongfor WebSocket clients #772 - feat(ws-server): Implement
ping-pongfor WebSocket server #782
[Changed]
-
0.13.113 May 2022Release notes
Open source →v0.13.1 is a release that fixes the documentation for feature-gated items on
docs.rs.[Fixed]
- fix: generate docs for all features on docs.rs #767
[Changed]
- chore(deps): update pprof requirement from 0.8 to 0.9 #761
-
0.13.011 May 2022Release notes
Open source →v0.13.0 is release that adds health API support for the HTTP server and a few bug fixes.
[Added]
feat: add http health API #763
[Fixed]
-
0.12.006 May 2022Release notes
Open source →v0.12.0 is mainly a patch release with some minor features added.
[Added]
- Make it possible to disable batch requests support #744
- feat: add a way to limit the number of subscriptions per connection #739
[Fixed]
- fix(http client): use https connector for https #750
- fix(rpc module): close subscription task when a subscription is
unsubscribedvia theunsubscribe call#743 - fix(jsonrpsee): generate docs behind features #741
[Changed]
-
0.11.021 Apr 2022Release notes
Open source →v0.11.0 is a breaking release that reworks how subscriptions are handled by the servers where the users have to explicitly reject or accept each subscription. The reason for this is that the actual params in the subscription is passed to the callback and if the application decides the params are invalid and the server can't know if the call is going to fail or pass when dispatching the call. Thus, the actual subscription method call is only answered when the subscription is accepted or rejected.
Additionally, the servers before sent a
SubscriptionClosed messagewhich is now disabled by default because it might break other implementations. It is still possible to respond with aSubscriptionClosed messagebut one has to match on the result fromSubscriptionSink::pipe_from_stream.This release also adds support for
JSON-RPC WASM clientusing web-sys bindings.[Added]
- feat: WASM client via web-sys transport #648
[Changed]
- CI: bump Swatinem/rust-cache from 1.3.0 to 1.4.0 #730
[Fixed]
- fix(rpc module): fail subscription calls with bad params #728