429 lines
11 KiB
TypeScript
429 lines
11 KiB
TypeScript
/**
|
|
* 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<WasmService> {
|
|
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<void> {
|
|
return this.sendMessageToWorker("INIT", {});
|
|
}
|
|
|
|
private sendMessageToWorker<T = any>(type: string, payload: any): Promise<T> {
|
|
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<any> {
|
|
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<any> {
|
|
return this.callMethod("parse_cipher", msg, membersList, processes);
|
|
}
|
|
|
|
/**
|
|
* Parse new transaction message from WebSocket
|
|
*/
|
|
public async parseNewTx(
|
|
msg: string,
|
|
blockHeight: number,
|
|
membersList: any
|
|
): Promise<any> {
|
|
return this.callMethod("parse_new_tx", msg, blockHeight, membersList);
|
|
}
|
|
|
|
// ============================================
|
|
// TRANSACTION METHODS
|
|
// ============================================
|
|
|
|
/**
|
|
* Create a transaction
|
|
*/
|
|
public async createTransaction(
|
|
addresses: string[],
|
|
feeRate: number
|
|
): Promise<any> {
|
|
return this.callMethod("create_transaction", addresses, feeRate);
|
|
}
|
|
|
|
/**
|
|
* Sign a partial transaction
|
|
*/
|
|
public async signTransaction(partialTx: any): Promise<any> {
|
|
return this.callMethod("sign_transaction", partialTx);
|
|
}
|
|
|
|
/**
|
|
* Get transaction ID
|
|
*/
|
|
public async getTxid(transaction: string): Promise<string> {
|
|
return this.callMethod("get_txid", transaction);
|
|
}
|
|
|
|
/**
|
|
* Get OP_RETURN from transaction
|
|
*/
|
|
public async getOpReturn(transaction: string): Promise<string> {
|
|
return this.callMethod("get_opreturn", transaction);
|
|
}
|
|
|
|
/**
|
|
* Get prevouts from transaction
|
|
*/
|
|
public async getPrevouts(transaction: string): Promise<string[]> {
|
|
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<any> {
|
|
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<any> {
|
|
return this.callMethod(
|
|
"update_process",
|
|
process,
|
|
privateData,
|
|
publicData,
|
|
roles,
|
|
membersList
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create update message
|
|
*/
|
|
public async createUpdateMessage(
|
|
process: any,
|
|
stateId: string,
|
|
membersList: any
|
|
): Promise<any> {
|
|
return this.callMethod("create_update_message", process, stateId, membersList);
|
|
}
|
|
|
|
/**
|
|
* Create PRD response
|
|
*/
|
|
public async createPrdResponse(
|
|
process: any,
|
|
stateId: string,
|
|
membersList: any
|
|
): Promise<any> {
|
|
return this.callMethod("create_response_prd", process, stateId, membersList);
|
|
}
|
|
|
|
/**
|
|
* Validate state
|
|
*/
|
|
public async validateState(
|
|
process: any,
|
|
stateId: string,
|
|
membersList: any
|
|
): Promise<any> {
|
|
return this.callMethod("validate_state", process, stateId, membersList);
|
|
}
|
|
|
|
/**
|
|
* Refuse state
|
|
*/
|
|
public async refuseState(process: any, stateId: string): Promise<any> {
|
|
return this.callMethod("refuse_state", process, stateId);
|
|
}
|
|
|
|
/**
|
|
* Request data from peers
|
|
*/
|
|
public async requestData(
|
|
processId: string,
|
|
stateIds: string[],
|
|
roles: any,
|
|
membersList: any
|
|
): Promise<any> {
|
|
return this.callMethod(
|
|
"request_data",
|
|
processId,
|
|
stateIds,
|
|
roles,
|
|
membersList
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Process commit new state
|
|
*/
|
|
public async processCommitNewState(
|
|
process: any,
|
|
newStateId: string,
|
|
newTip: string
|
|
): Promise<void> {
|
|
return this.callMethod("process_commit_new_state", process, newStateId, newTip);
|
|
}
|
|
|
|
// ============================================
|
|
// ENCODING/DECODING METHODS
|
|
// ============================================
|
|
|
|
public async encodeJson(data: any): Promise<any> {
|
|
return this.callMethod("encode_json", data);
|
|
}
|
|
|
|
public async encodeBinary(data: any): Promise<any> {
|
|
return this.callMethod("encode_binary", data);
|
|
}
|
|
|
|
public async decodeValue(value: number[]): Promise<any> {
|
|
return this.callMethod("decode_value", value);
|
|
}
|
|
|
|
// ============================================
|
|
// WALLET METHODS
|
|
// ============================================
|
|
|
|
public async isPaired(): Promise<boolean> {
|
|
return this.callMethod("is_paired");
|
|
}
|
|
|
|
public async getAvailableAmount(): Promise<BigInt> {
|
|
return this.callMethod("get_available_amount");
|
|
}
|
|
|
|
public async getAddress(): Promise<string> {
|
|
return this.callMethod("get_address");
|
|
}
|
|
|
|
public async getPairingProcessId(): Promise<string> {
|
|
return this.callMethod("get_pairing_process_id");
|
|
}
|
|
|
|
public async createNewDevice(birthday: number, network: string): Promise<string> {
|
|
return this.callMethod("create_new_device", birthday, network);
|
|
}
|
|
|
|
public async dumpDevice(): Promise<any> {
|
|
return this.callMethod("dump_device");
|
|
}
|
|
|
|
public async dumpNeuteredDevice(): Promise<any> {
|
|
return this.callMethod("dump_neutered_device");
|
|
}
|
|
|
|
public async dumpWallet(): Promise<any> {
|
|
return this.callMethod("dump_wallet");
|
|
}
|
|
|
|
public async restoreDevice(device: any): Promise<void> {
|
|
return this.callMethod("restore_device", device);
|
|
}
|
|
|
|
public async pairDevice(processId: string, spAddresses: string[]): Promise<void> {
|
|
return this.callMethod("pair_device", processId, spAddresses);
|
|
}
|
|
|
|
public async unpairDevice(): Promise<void> {
|
|
return this.callMethod("unpair_device");
|
|
}
|
|
|
|
public async resetDevice(): Promise<void> {
|
|
return this.callMethod("reset_device");
|
|
}
|
|
|
|
// ============================================
|
|
// CRYPTO METHODS
|
|
// ============================================
|
|
|
|
public async hashValue(
|
|
fileBlob: { type: string; data: Uint8Array },
|
|
commitedIn: string,
|
|
label: string
|
|
): Promise<string> {
|
|
return this.callMethod("hash_value", fileBlob, commitedIn, label);
|
|
}
|
|
|
|
public async getMerkleProof(processState: any, attributeName: string): Promise<any> {
|
|
return this.callMethod("get_merkle_proof", processState, attributeName);
|
|
}
|
|
|
|
public async validateMerkleProof(proof: any, hash: string): Promise<boolean> {
|
|
return this.callMethod("validate_merkle_proof", proof, hash);
|
|
}
|
|
|
|
public async decryptData(key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
|
|
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<any> {
|
|
return this.callMethod(
|
|
"create_new_process",
|
|
privateData,
|
|
roles,
|
|
publicData,
|
|
relayAddress,
|
|
feeRate,
|
|
membersList
|
|
);
|
|
}
|
|
|
|
// ============================================
|
|
// SECRETS MANAGEMENT
|
|
// ============================================
|
|
|
|
public async setSharedSecrets(secretsJson: string): Promise<void> {
|
|
return this.callMethod("set_shared_secrets", secretsJson);
|
|
}
|
|
|
|
// ============================================
|
|
// BLOCKCHAIN SCANNING
|
|
// ============================================
|
|
|
|
public async scanBlocks(tipHeight: number, blindbitUrl: string): Promise<void> {
|
|
return this.callMethod("scan_blocks", tipHeight, blindbitUrl);
|
|
}
|
|
|
|
// ============================================
|
|
// UTILITY METHODS
|
|
// ============================================
|
|
|
|
public async createFaucetMessage(): Promise<string> {
|
|
return this.callMethod("create_faucet_msg");
|
|
}
|
|
|
|
public async isChildRole(parent: any, child: any): Promise<boolean> {
|
|
return this.callMethod("is_child_role", JSON.stringify(parent), JSON.stringify(child));
|
|
}
|
|
}
|
|
|
|
export default WasmService;
|
|
|