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