sal-modular/hero_vault_extension/src/wasm/wasmHelper.ts

140 lines
3.7 KiB
TypeScript

/**
* WASM Helper for Hero Vault Extension
*
* This module handles loading and initializing the WASM module,
* and provides a typed interface to the WASM functions.
*/
// Import types for TypeScript
interface WasmModule {
// Session management
init_session: (keyspace: string, password: string) => Promise<void>;
create_keyspace: (keyspace: string, password: string) => Promise<void>;
lock_session: () => void;
is_unlocked: () => boolean;
// Keypair management
add_keypair: (key_type: string | undefined, metadata: string | undefined) => Promise<string>;
list_keypairs: () => Promise<string>;
select_keypair: (key_id: string) => Promise<void>;
current_keypair_metadata: () => Promise<any>;
current_keypair_public_key: () => Promise<Uint8Array>;
// Cryptographic operations
sign: (message: Uint8Array) => Promise<string>;
verify: (message: Uint8Array, signature: string) => Promise<boolean>;
encrypt_data: (data: Uint8Array) => Promise<Uint8Array>;
decrypt_data: (encrypted: Uint8Array) => Promise<Uint8Array>;
// Rhai scripting
init_rhai_env: () => void;
run_rhai: (script: string) => Promise<string>;
}
// Global reference to the WASM module
let wasmModule: WasmModule | null = null;
let isInitializing = false;
let initPromise: Promise<void> | null = null;
/**
* Initialize the WASM module
* This should be called before any other WASM functions
*/
export const initWasm = async (): Promise<void> => {
if (wasmModule) {
return Promise.resolve(); // Already initialized
}
if (isInitializing && initPromise) {
return initPromise; // Already initializing
}
isInitializing = true;
initPromise = new Promise<void>(async (resolve, reject) => {
try {
try {
// Import the WASM module
// Use a relative path that will be resolved by Vite during build
const wasmImport = await import('../../public/wasm/wasm_app.js');
// Initialize the WASM module
await wasmImport.default();
// Store the WASM module globally
wasmModule = wasmImport as unknown as WasmModule;
console.log('WASM module initialized successfully');
resolve();
} catch (error) {
console.error('Failed to initialize WASM module:', error);
reject(error);
}
} finally {
isInitializing = false;
}
});
return initPromise;
};
/**
* Get the WASM module
* This will initialize the module if it hasn't been initialized yet
*/
export const getWasmModule = async (): Promise<WasmModule> => {
if (!wasmModule) {
await initWasm();
}
if (!wasmModule) {
throw new Error('WASM module failed to initialize');
}
return wasmModule;
};
/**
* Check if the WASM module is initialized
*/
export const isWasmInitialized = (): boolean => {
return wasmModule !== null;
};
/**
* Helper to convert string to Uint8Array
*/
export const stringToUint8Array = (str: string): Uint8Array => {
const encoder = new TextEncoder();
return encoder.encode(str);
};
/**
* Helper to convert Uint8Array to string
*/
export const uint8ArrayToString = (array: Uint8Array): string => {
const decoder = new TextDecoder();
return decoder.decode(array);
};
/**
* Helper to convert hex string to Uint8Array
*/
export const hexToUint8Array = (hex: string): Uint8Array => {
const bytes = new Uint8Array(hex.length / 2);
for (let i = 0; i < hex.length; i += 2) {
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
}
return bytes;
};
/**
* Helper to convert Uint8Array to hex string
*/
export const uint8ArrayToHex = (array: Uint8Array): string => {
return Array.from(array)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
};