/** * WASM Service - Manages communication with WASM Worker * Similar to Database Service, but for WASM operations */ export class WasmService { private static instance: WasmService; private wasmWorker: Worker | null = null; private messageIdCounter: number = 0; private pendingMessages: Map< string, { resolve: (value: any) => void; reject: (error: any) => void } > = new Map(); // ============================================ // INITIALIZATION & SINGLETON // ============================================ private constructor() { this.initWasmWorker(); } public static async getInstance(): Promise { if (!WasmService.instance) { WasmService.instance = new WasmService(); await WasmService.instance.waitForWorkerReady(); } return WasmService.instance; } // ============================================ // WASM WORKER MANAGEMENT // ============================================ private initWasmWorker(): void { this.wasmWorker = new Worker( new URL("../workers/wasm.worker.ts", import.meta.url), { type: "module" } ); this.wasmWorker.onmessage = (event) => { const { id, type, result, error } = event.data; const pending = this.pendingMessages.get(id); if (pending) { this.pendingMessages.delete(id); if (type === "SUCCESS") { pending.resolve(result); } else if (type === "ERROR") { pending.reject(new Error(error)); } } }; this.wasmWorker.onerror = (error) => { console.error("[WasmService] WASM Worker error:", error); }; } private async waitForWorkerReady(): Promise { return this.sendMessageToWorker("INIT", {}); } private sendMessageToWorker(type: string, payload: any): Promise { return new Promise((resolve, reject) => { if (!this.wasmWorker) { reject(new Error("WASM Worker not initialized")); return; } const id = `wasm_${++this.messageIdCounter}`; this.pendingMessages.set(id, { resolve, reject }); this.wasmWorker.postMessage({ id, type, ...payload, }); // Timeout after 30 seconds setTimeout(() => { if (this.pendingMessages.has(id)) { this.pendingMessages.delete(id); reject(new Error(`WASM Worker message timeout for type: ${type}`)); } }, 30000); }); } // ============================================ // WASM METHOD CALLS // ============================================ /** * Generic method to call any WASM function */ public async callMethod(method: string, ...args: any[]): Promise { return this.sendMessageToWorker("WASM_METHOD", { method, args, }); } // ============================================ // WS MESSAGE PROCESSING METHODS // ============================================ /** * Parse cipher message from WebSocket */ public async parseCipher( msg: string, membersList: any, processes: any ): Promise { return this.callMethod("parse_cipher", msg, membersList, processes); } /** * Parse new transaction message from WebSocket */ public async parseNewTx( msg: string, blockHeight: number, membersList: any ): Promise { return this.callMethod("parse_new_tx", msg, blockHeight, membersList); } // ============================================ // TRANSACTION METHODS // ============================================ /** * Create a transaction */ public async createTransaction( addresses: string[], feeRate: number ): Promise { return this.callMethod("create_transaction", addresses, feeRate); } /** * Sign a partial transaction */ public async signTransaction(partialTx: any): Promise { return this.callMethod("sign_transaction", partialTx); } /** * Get transaction ID */ public async getTxid(transaction: string): Promise { return this.callMethod("get_txid", transaction); } /** * Get OP_RETURN from transaction */ public async getOpReturn(transaction: string): Promise { return this.callMethod("get_opreturn", transaction); } /** * Get prevouts from transaction */ public async getPrevouts(transaction: string): Promise { return this.callMethod("get_prevouts", transaction); } // ============================================ // PROCESS MANIPULATION METHODS // ============================================ /** * Create a new process */ public async createProcess( privateData: any, publicData: any, roles: any, membersList: any ): Promise { return this.callMethod( "create_process", privateData, publicData, roles, membersList ); } /** * Update a process */ public async updateProcess( process: any, privateData: any, publicData: any, roles: any, membersList: any ): Promise { return this.callMethod( "update_process", process, privateData, publicData, roles, membersList ); } /** * Create update message */ public async createUpdateMessage( process: any, stateId: string, membersList: any ): Promise { return this.callMethod("create_update_message", process, stateId, membersList); } /** * Create PRD response */ public async createPrdResponse( process: any, stateId: string, membersList: any ): Promise { return this.callMethod("create_response_prd", process, stateId, membersList); } /** * Validate state */ public async validateState( process: any, stateId: string, membersList: any ): Promise { return this.callMethod("validate_state", process, stateId, membersList); } /** * Refuse state */ public async refuseState(process: any, stateId: string): Promise { return this.callMethod("refuse_state", process, stateId); } /** * Request data from peers */ public async requestData( processId: string, stateIds: string[], roles: any, membersList: any ): Promise { return this.callMethod( "request_data", processId, stateIds, roles, membersList ); } /** * Process commit new state */ public async processCommitNewState( process: any, newStateId: string, newTip: string ): Promise { return this.callMethod("process_commit_new_state", process, newStateId, newTip); } // ============================================ // ENCODING/DECODING METHODS // ============================================ public async encodeJson(data: any): Promise { return this.callMethod("encode_json", data); } public async encodeBinary(data: any): Promise { return this.callMethod("encode_binary", data); } public async decodeValue(value: number[]): Promise { return this.callMethod("decode_value", value); } // ============================================ // WALLET METHODS // ============================================ public async isPaired(): Promise { return this.callMethod("is_paired"); } public async getAvailableAmount(): Promise { return this.callMethod("get_available_amount"); } public async getAddress(): Promise { return this.callMethod("get_address"); } public async getPairingProcessId(): Promise { return this.callMethod("get_pairing_process_id"); } public async createNewDevice(birthday: number, network: string): Promise { return this.callMethod("create_new_device", birthday, network); } public async dumpDevice(): Promise { return this.callMethod("dump_device"); } public async dumpNeuteredDevice(): Promise { return this.callMethod("dump_neutered_device"); } public async dumpWallet(): Promise { return this.callMethod("dump_wallet"); } public async restoreDevice(device: any): Promise { return this.callMethod("restore_device", device); } public async pairDevice(processId: string, spAddresses: string[]): Promise { return this.callMethod("pair_device", processId, spAddresses); } public async unpairDevice(): Promise { return this.callMethod("unpair_device"); } public async resetDevice(): Promise { return this.callMethod("reset_device"); } // ============================================ // CRYPTO METHODS // ============================================ public async hashValue( fileBlob: { type: string; data: Uint8Array }, commitedIn: string, label: string ): Promise { return this.callMethod("hash_value", fileBlob, commitedIn, label); } public async getMerkleProof(processState: any, attributeName: string): Promise { return this.callMethod("get_merkle_proof", processState, attributeName); } public async validateMerkleProof(proof: any, hash: string): Promise { return this.callMethod("validate_merkle_proof", proof, hash); } public async decryptData(key: Uint8Array, data: Uint8Array): Promise { return this.callMethod("decrypt_data", key, data); } // ============================================ // PROCESS CREATION (with relay and fee) // ============================================ public async createNewProcess( privateData: any, roles: any, publicData: any, relayAddress: string, feeRate: number, membersList: any ): Promise { return this.callMethod( "create_new_process", privateData, roles, publicData, relayAddress, feeRate, membersList ); } // ============================================ // SECRETS MANAGEMENT // ============================================ public async setSharedSecrets(secretsJson: string): Promise { return this.callMethod("set_shared_secrets", secretsJson); } // ============================================ // BLOCKCHAIN SCANNING // ============================================ public async scanBlocks(tipHeight: number, blindbitUrl: string): Promise { return this.callMethod("scan_blocks", tipHeight, blindbitUrl); } // ============================================ // UTILITY METHODS // ============================================ public async createFaucetMessage(): Promise { return this.callMethod("create_faucet_msg"); } public async isChildRole(parent: any, child: any): Promise { return this.callMethod("is_child_role", JSON.stringify(parent), JSON.stringify(child)); } } export default WasmService;