ethane_wasm/
lib.rs

1use js_sys::{Array, Promise};
2use wasm_bindgen::prelude::*;
3use wasm_bindgen_futures::future_to_promise;
4
5#[wasm_bindgen]
6pub struct RequestArguments {
7    method: String,
8    params: Array, // NOTE Serialize is not implemented for js_sys::Array
9}
10
11#[wasm_bindgen]
12impl RequestArguments {
13    pub fn new(method: String, params: Array) -> Self {
14        Self { method, params }
15    }
16
17    pub fn as_json_string(&self, id: usize) -> String {
18        let param_vec = self
19            .params
20            .iter()
21            .map(|val| {
22                val.as_string()
23                    .unwrap_or_else(|| "Error: couldn't turn JsValue into String".to_owned())
24            })
25            .collect::<Vec<String>>();
26
27        format!(
28            "{{\"jsonrpc\":\"2.0\",\"method\":{:?},\"params\":{:?},\"id\":{}}}",
29            self.method, param_vec, id
30        )
31    }
32}
33
34#[wasm_bindgen]
35pub struct Web3 {
36    id: usize,
37    client: ethane::AsyncHttp,
38}
39
40#[wasm_bindgen]
41impl Web3 {
42    pub fn new(address: String) -> Self {
43        Self {
44            id: 0,
45            client: ethane::AsyncHttp::new(&address, None),
46        }
47    }
48
49    pub fn call(&mut self, args: RequestArguments) -> Promise {
50        let id = if self.id > 10000 { 1 } else { self.id + 1 };
51        self.id = id;
52        let client = self.client.clone();
53
54        future_to_promise(async move {
55            let result = client.request(args.as_json_string(id)).await;
56            let response = if let Ok(response) = result {
57                response
58            } else {
59                format!("Error: {:?}", result.err().unwrap())
60            };
61            Ok(JsValue::from(response))
62        })
63    }
64}