Skip to content

Commit 3d3a144

Browse files
committed
feat: support RpcProvider in wasm environment
1 parent 1198766 commit 3d3a144

File tree

1 file changed

+20
-48
lines changed

1 file changed

+20
-48
lines changed

crates/wasm_client_solana/src/providers/http_provider.rs

+20-48
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,6 @@ mod ssr_http_provider {
5858
.await?;
5959

6060
Ok(result)
61-
62-
// if let Ok(response) = serde_json::from_value::<R>(result.clone())
63-
// { Ok(response)
64-
// } else {
65-
// match serde_json::from_value::<RpcError>(result) {
66-
// Ok(error) => Err(error.into()),
67-
// Err(error) => Err(ClientError::Other(error.to_string())),
68-
// }
69-
// }
7061
}
7162
}
7263

@@ -107,7 +98,6 @@ mod ssr_http_provider {
10798

10899
#[cfg(not(feature = "ssr"))]
109100
mod wasm_http_provider {
110-
#![allow(unsafe_code)]
111101

112102
use std::pin::Pin;
113103
use std::task::Context;
@@ -118,36 +108,20 @@ mod wasm_http_provider {
118108
use pin_project::pinned_drop;
119109
use send_wrapper::SendWrapper;
120110
use wasm_bindgen::prelude::*;
121-
use wasm_bindgen_futures::JsFuture;
122111
use web_sys::AbortController;
123-
use web_sys::Headers;
124-
use web_sys::Request;
125-
use web_sys::RequestInit;
126-
use web_sys::Response;
127112

128113
use super::*;
129114
use crate::ClientError;
130115

131-
#[wasm_bindgen]
132-
extern "C" {
133-
// Create a separate binding for `fetch` as a global, rather than using the
134-
// existing Window/WorkerGlobalScope bindings defined by web_sys, for
135-
// greater efficiency.
136-
//
137-
// https://github.com/rustwasm/wasm-bindgen/discussions/3863
138-
#[wasm_bindgen(js_name = "fetch")]
139-
fn fetch_with_request(request: &Request) -> js_sys::Promise;
140-
}
141-
142116
#[pin_project(PinnedDrop)]
143-
struct AbortableRequest<F: Future<Output = Result<JsValue, JsValue>>> {
117+
struct AbortableRequest<F: Future<Output = Result<gloo_net::http::Response, gloo_net::Error>>> {
144118
#[pin]
145119
fut: F,
146120
controller: AbortController,
147121
pending: bool,
148122
}
149123

150-
impl<F: Future<Output = Result<JsValue, JsValue>>> AbortableRequest<F> {
124+
impl<F: Future<Output = Result<gloo_net::http::Response, gloo_net::Error>>> AbortableRequest<F> {
151125
fn new(fut: F, controller: AbortController) -> Self {
152126
Self {
153127
fut,
@@ -157,8 +131,10 @@ mod wasm_http_provider {
157131
}
158132
}
159133

160-
impl<F: Future<Output = Result<JsValue, JsValue>>> Future for AbortableRequest<F> {
161-
type Output = Result<JsValue, JsValue>;
134+
impl<F: Future<Output = Result<gloo_net::http::Response, gloo_net::Error>>> Future
135+
for AbortableRequest<F>
136+
{
137+
type Output = Result<gloo_net::http::Response, gloo_net::Error>;
162138

163139
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
164140
let mut this = self.project();
@@ -175,7 +151,9 @@ mod wasm_http_provider {
175151
}
176152

177153
#[pinned_drop]
178-
impl<F: Future<Output = Result<JsValue, JsValue>>> PinnedDrop for AbortableRequest<F> {
154+
impl<F: Future<Output = Result<gloo_net::http::Response, gloo_net::Error>>> PinnedDrop
155+
for AbortableRequest<F>
156+
{
179157
fn drop(self: Pin<&mut Self>) {
180158
if self.pending {
181159
// only abort the fetch if it is still pending.
@@ -203,23 +181,12 @@ mod wasm_http_provider {
203181
let future = async move {
204182
let controller = AbortController::new().unwrap_throw();
205183
let signal = controller.signal();
206-
let headers = Headers::new()?;
207-
let options = RequestInit::new();
208-
let json = serde_json::to_string(&client_request).unwrap_throw();
209-
210-
headers.set("Content-Type", "application/json")?;
211-
options.set_signal(Some(&signal));
212-
options.set_headers(&headers.into());
213-
options.set_body(&json.into());
214-
let request = Request::new_with_str_and_init(&self.0, &options)?;
215-
let fetch_promise = fetch_with_request(&request);
216-
let response_value =
217-
AbortableRequest::new(JsFuture::from(fetch_promise), controller).await?;
218-
let response = response_value.dyn_into::<Response>()?;
219-
220-
let json_promise = response.json()?;
221-
let json_value = JsFuture::from(json_promise).await?;
222-
let value: Value = serde_wasm_bindgen::from_value(json_value)?;
184+
let request = gloo_net::http::Request::post(&self.0)
185+
.abort_signal(Some(&signal))
186+
.json(&client_request)?;
187+
let response = AbortableRequest::new(request.send(), controller).await?;
188+
let value = response.json().await?;
189+
223190
Ok::<Value, ClientError>(value)
224191
};
225192

@@ -240,6 +207,11 @@ mod wasm_http_provider {
240207
Self::Other(value.to_string())
241208
}
242209
}
210+
impl From<gloo_net::Error> for ClientError {
211+
fn from(value: gloo_net::Error) -> Self {
212+
Self::Other(value.to_string())
213+
}
214+
}
243215

244216
impl From<JsValue> for ClientError {
245217
fn from(error: JsValue) -> Self {

0 commit comments

Comments
 (0)