fedimint_client_wasm/
lib.rs1#![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 async 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 let connectors = fedimint_connectors::ConnectorRegistry::build_from_client_defaults()
35 .bind()
36 .await
37 .unwrap();
38
39 let state = Arc::new(RpcGlobalState::new(connectors, database));
40
41 Self { state }
42 }
43
44 #[wasm_bindgen]
45 pub fn rpc(&self, request: String, cb: js_sys::Function) -> Result<(), JsError> {
46 let request: RpcRequest = serde_json::from_str(&request)
47 .map_err(|e| JsError::new(&format!("Failed to parse request: {}", e)))?;
48
49 let handled = self
50 .state
51 .clone()
52 .handle_rpc(request, JsFunctionWrapper(cb));
53
54 if let Some(task) = handled.task {
55 wasm_bindgen_futures::spawn_local(task);
56 }
57 Ok(())
58 }
59}