fedimint_client_wasm/
lib.rs
1#![cfg(target_family = "wasm")]
2
3use std::sync::Arc;
4
5use fedimint_client_rpc::{RpcGlobalState, RpcRequest, RpcResponse, RpcResponseHandler};
6use fedimint_core::db::Database;
7use fedimint_cursed_redb::MemAndRedb;
8use wasm_bindgen::prelude::{JsError, JsValue, wasm_bindgen};
9use web_sys::FileSystemSyncAccessHandle;
10
11struct JsFunctionWrapper(js_sys::Function);
12
13impl RpcResponseHandler for JsFunctionWrapper {
14 fn handle_response(&self, response: RpcResponse) {
15 let _ = self.0.call1(
16 &JsValue::null(),
17 &JsValue::from_str(&serde_json::to_string(&response).unwrap()),
18 );
19 }
20}
21
22#[wasm_bindgen]
23struct RpcHandler {
24 state: Arc<RpcGlobalState>,
25}
26
27#[wasm_bindgen]
28impl RpcHandler {
29 #[wasm_bindgen(constructor)]
30 pub fn new(sync_handle: FileSystemSyncAccessHandle) -> Self {
31 let cursed_db = MemAndRedb::new(sync_handle).unwrap();
33 let database = Database::new(cursed_db, Default::default());
34
35 let state = Arc::new(RpcGlobalState::new(database));
36
37 Self { state }
38 }
39
40 #[wasm_bindgen]
41 pub fn rpc(&self, request: String, cb: js_sys::Function) -> Result<(), JsError> {
42 let request: RpcRequest = serde_json::from_str(&request)
43 .map_err(|e| JsError::new(&format!("Failed to parse request: {}", e)))?;
44
45 let handled = self
46 .state
47 .clone()
48 .handle_rpc(request, JsFunctionWrapper(cb));
49
50 if let Some(task) = handled.task {
51 wasm_bindgen_futures::spawn_local(task);
52 }
53 Ok(())
54 }
55}