668 lines
23 KiB
JavaScript
668 lines
23 KiB
JavaScript
/**
|
|
* Browser extension-friendly WebAssembly loader and helper functions
|
|
* This handles loading the WebAssembly module without relying on ES modules
|
|
*/
|
|
|
|
// Global reference to the loaded WebAssembly module
|
|
let wasmModule = null;
|
|
|
|
// Initialization state
|
|
const state = {
|
|
loading: false,
|
|
initialized: false,
|
|
error: null
|
|
};
|
|
|
|
/**
|
|
* Load the WebAssembly module
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function loadWasmModule() {
|
|
if (state.initialized || state.loading) {
|
|
return;
|
|
}
|
|
|
|
state.loading = true;
|
|
|
|
try {
|
|
// Get paths to WebAssembly files
|
|
const wasmJsPath = chrome.runtime.getURL('wasm/wasm_app.js');
|
|
const wasmBinaryPath = chrome.runtime.getURL('wasm/wasm_app_bg.wasm');
|
|
|
|
console.log('Loading WASM JS from:', wasmJsPath);
|
|
console.log('Loading WASM binary from:', wasmBinaryPath);
|
|
|
|
// Create a container for our temporary WebAssembly globals
|
|
window.__wasmApp = {};
|
|
|
|
// Create a script element to load the JS file
|
|
const script = document.createElement('script');
|
|
script.src = wasmJsPath;
|
|
|
|
// Wait for the script to load
|
|
await new Promise((resolve, reject) => {
|
|
script.onload = resolve;
|
|
script.onerror = () => reject(new Error('Failed to load WASM JavaScript file'));
|
|
document.head.appendChild(script);
|
|
});
|
|
|
|
// Check if the wasm_app global was created
|
|
if (!window.wasm_app && !window.__wbg_init) {
|
|
throw new Error('WASM module did not export expected functions');
|
|
}
|
|
|
|
// Get the initialization function
|
|
const init = window.__wbg_init || (window.wasm_app && window.wasm_app.default);
|
|
|
|
if (!init || typeof init !== 'function') {
|
|
throw new Error('WASM init function not found');
|
|
}
|
|
|
|
// Fetch the WASM binary file
|
|
const response = await fetch(wasmBinaryPath);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch WASM binary: ${response.status} ${response.statusText}`);
|
|
}
|
|
|
|
// Get the binary data
|
|
const wasmBinary = await response.arrayBuffer();
|
|
|
|
// Initialize the WASM module
|
|
await init(wasmBinary);
|
|
|
|
// Debug logging for available functions in the WebAssembly module
|
|
console.log('Available WebAssembly functions:');
|
|
console.log('init_rhai_env:', typeof window.init_rhai_env, typeof (window.wasm_app && window.wasm_app.init_rhai_env));
|
|
console.log('init_session:', typeof window.init_session, typeof (window.wasm_app && window.wasm_app.init_session));
|
|
console.log('lock_session:', typeof window.lock_session, typeof (window.wasm_app && window.wasm_app.lock_session));
|
|
console.log('add_keypair:', typeof window.add_keypair, typeof (window.wasm_app && window.wasm_app.add_keypair));
|
|
console.log('select_keypair:', typeof window.select_keypair, typeof (window.wasm_app && window.wasm_app.select_keypair));
|
|
console.log('sign:', typeof window.sign, typeof (window.wasm_app && window.wasm_app.sign));
|
|
console.log('run_rhai:', typeof window.run_rhai, typeof (window.wasm_app && window.wasm_app.run_rhai));
|
|
console.log('list_keypairs:', typeof window.list_keypairs, typeof (window.wasm_app && window.wasm_app.list_keypairs));
|
|
|
|
// Store reference to all the exported functions
|
|
wasmModule = {
|
|
init_rhai_env: window.init_rhai_env || (window.wasm_app && window.wasm_app.init_rhai_env),
|
|
init_session: window.init_session || (window.wasm_app && window.wasm_app.init_session),
|
|
lock_session: window.lock_session || (window.wasm_app && window.wasm_app.lock_session),
|
|
add_keypair: window.add_keypair || (window.wasm_app && window.wasm_app.add_keypair),
|
|
select_keypair: window.select_keypair || (window.wasm_app && window.wasm_app.select_keypair),
|
|
sign: window.sign || (window.wasm_app && window.wasm_app.sign),
|
|
run_rhai: window.run_rhai || (window.wasm_app && window.wasm_app.run_rhai),
|
|
list_keypairs: window.list_keypairs || (window.wasm_app && window.wasm_app.list_keypairs),
|
|
list_keypairs_debug: window.list_keypairs_debug || (window.wasm_app && window.wasm_app.list_keypairs_debug),
|
|
check_indexeddb: window.check_indexeddb || (window.wasm_app && window.wasm_app.check_indexeddb)
|
|
};
|
|
|
|
// Log what was actually registered
|
|
console.log('Registered WebAssembly module functions:');
|
|
for (const [key, value] of Object.entries(wasmModule)) {
|
|
console.log(`${key}: ${typeof value}`, value ? 'Available' : 'Missing');
|
|
}
|
|
|
|
// Initialize the WASM environment
|
|
if (typeof wasmModule.init_rhai_env === 'function') {
|
|
wasmModule.init_rhai_env();
|
|
}
|
|
|
|
state.initialized = true;
|
|
console.log('WASM module loaded and initialized successfully');
|
|
|
|
} catch (error) {
|
|
console.error('Failed to load WASM module:', error);
|
|
state.error = error.message || 'Unknown error loading WebAssembly module';
|
|
} finally {
|
|
state.loading = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the current state of the WebAssembly module
|
|
* @returns {{loading: boolean, initialized: boolean, error: string|null}}
|
|
*/
|
|
export function getWasmState() {
|
|
return { ...state };
|
|
}
|
|
|
|
/**
|
|
* Get the WebAssembly module
|
|
* @returns {object|null} The WebAssembly module or null if not loaded
|
|
*/
|
|
export function getWasmModule() {
|
|
return wasmModule;
|
|
}
|
|
|
|
/**
|
|
* Debug function to check the vault state
|
|
* @returns {Promise<object>} State information
|
|
*/
|
|
export async function debugVaultState() {
|
|
const module = getWasmModule();
|
|
if (!module) {
|
|
throw new Error('WebAssembly module not loaded');
|
|
}
|
|
|
|
try {
|
|
console.log('🔍 Debugging vault state...');
|
|
|
|
// Check if we have a valid session using Rhai script
|
|
const sessionCheck = `
|
|
let has_session = vault::has_active_session();
|
|
let keyspace = "";
|
|
if has_session {
|
|
keyspace = vault::get_current_keyspace();
|
|
}
|
|
|
|
// Return info about the session
|
|
{
|
|
"has_session": has_session,
|
|
"keyspace": keyspace
|
|
}
|
|
`;
|
|
|
|
console.log('Checking session status...');
|
|
const sessionStatus = await module.run_rhai(sessionCheck);
|
|
console.log('Session status:', sessionStatus);
|
|
|
|
// Get keypair info if we have a session
|
|
if (sessionStatus && sessionStatus.has_session) {
|
|
const keypairsScript = `
|
|
// Get all keypairs for the current keyspace
|
|
let keypairs = vault::list_keypairs();
|
|
|
|
// Add diagnostic information
|
|
let diagnostic = {
|
|
"keypair_count": keypairs.len(),
|
|
"keyspace": vault::get_current_keyspace(),
|
|
"keypairs": keypairs
|
|
};
|
|
|
|
diagnostic
|
|
`;
|
|
|
|
console.log('Fetching keypair details...');
|
|
const keypairDiagnostic = await module.run_rhai(keypairsScript);
|
|
console.log('Keypair diagnostic:', keypairDiagnostic);
|
|
|
|
return keypairDiagnostic;
|
|
}
|
|
|
|
return sessionStatus;
|
|
} catch (error) {
|
|
console.error('Error in debug function:', error);
|
|
return { error: error.toString() };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get keypairs from the vault
|
|
* @returns {Promise<Array>} List of keypairs
|
|
*/
|
|
export async function getKeypairsFromVault() {
|
|
console.log('===============================================');
|
|
console.log('Starting getKeypairsFromVault...');
|
|
const module = getWasmModule();
|
|
if (!module) {
|
|
console.error('WebAssembly module not loaded!');
|
|
throw new Error('WebAssembly module not loaded');
|
|
}
|
|
console.log('WebAssembly module:', module);
|
|
console.log('Module functions available:', Object.keys(module));
|
|
|
|
// Check if IndexedDB is available and working
|
|
const isIndexedDBAvailable = await checkIndexedDBAvailability();
|
|
if (!isIndexedDBAvailable) {
|
|
console.warn('IndexedDB is not available or not working properly');
|
|
// We'll continue, but this is likely why keypairs aren't persisting
|
|
}
|
|
|
|
// Force re-initialization of the current session if needed
|
|
try {
|
|
// This checks if we have the debug function available
|
|
if (typeof module.list_keypairs_debug === 'function') {
|
|
console.log('Using debug function to diagnose keypair loading issues...');
|
|
const debugResult = await module.list_keypairs_debug();
|
|
console.log('Debug keypair listing result:', debugResult);
|
|
if (Array.isArray(debugResult) && debugResult.length > 0) {
|
|
console.log('Debug function returned keypairs:', debugResult);
|
|
// If debug function worked but regular function doesn't, use its result
|
|
return debugResult;
|
|
} else {
|
|
console.log('Debug function did not return keypairs, continuing with normal flow...');
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Error in debug function:', err);
|
|
// Continue with normal flow even if the debug function fails
|
|
}
|
|
|
|
try {
|
|
console.log('-----------------------------------------------');
|
|
console.log('Running diagnostics to check vault state...');
|
|
// Run diagnostic first to log vault state
|
|
await debugVaultState();
|
|
console.log('Diagnostics complete');
|
|
console.log('-----------------------------------------------');
|
|
|
|
console.log('Checking if list_keypairs function is available:', typeof module.list_keypairs);
|
|
for (const key in module) {
|
|
console.log(`Module function: ${key} = ${typeof module[key]}`);
|
|
}
|
|
if (typeof module.list_keypairs !== 'function') {
|
|
console.error('list_keypairs function is not available in the WebAssembly module!');
|
|
console.log('Available functions:', Object.keys(module));
|
|
// Fall back to Rhai script
|
|
console.log('Falling back to using Rhai script for listing keypairs...');
|
|
const script = `
|
|
// Get all keypairs from the current keyspace
|
|
let keypairs = vault::list_keypairs();
|
|
keypairs
|
|
`;
|
|
const keypairList = await module.run_rhai(script);
|
|
console.log('Retrieved keypairs from vault using Rhai:', keypairList);
|
|
return keypairList;
|
|
}
|
|
|
|
console.log('Calling WebAssembly list_keypairs function...');
|
|
// Use the direct list_keypairs function from WebAssembly instead of Rhai script
|
|
const keypairList = await module.list_keypairs();
|
|
console.log('Retrieved keypairs from vault:', keypairList);
|
|
|
|
console.log('Raw keypair list type:', typeof keypairList);
|
|
console.log('Is array?', Array.isArray(keypairList));
|
|
console.log('Raw keypair list:', keypairList);
|
|
|
|
// Format keypairs for UI
|
|
const formattedKeypairs = Array.isArray(keypairList) ? keypairList.map(kp => {
|
|
// Parse metadata if available
|
|
let metadata = {};
|
|
if (kp.metadata) {
|
|
try {
|
|
if (typeof kp.metadata === 'string') {
|
|
metadata = JSON.parse(kp.metadata);
|
|
} else {
|
|
metadata = kp.metadata;
|
|
}
|
|
} catch (e) {
|
|
console.warn('Failed to parse keypair metadata:', e);
|
|
}
|
|
}
|
|
|
|
return {
|
|
id: kp.id,
|
|
label: metadata.label || `Key-${kp.id.substring(0, 4)}`
|
|
};
|
|
}) : [];
|
|
|
|
console.log('Formatted keypairs for UI:', formattedKeypairs);
|
|
|
|
// Update background service worker
|
|
return new Promise((resolve) => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypairs_loaded',
|
|
data: formattedKeypairs
|
|
}, (response) => {
|
|
console.log('Background response to keypairs update:', response);
|
|
resolve(formattedKeypairs);
|
|
});
|
|
});
|
|
} catch (error) {
|
|
console.error('Error fetching keypairs from vault:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if IndexedDB is available and working
|
|
* @returns {Promise<boolean>} True if IndexedDB is working
|
|
*/
|
|
export async function checkIndexedDBAvailability() {
|
|
console.log('Checking IndexedDB availability...');
|
|
|
|
// First check if IndexedDB is available in the browser
|
|
if (!window.indexedDB) {
|
|
console.error('IndexedDB is not available in this browser');
|
|
return false;
|
|
}
|
|
|
|
const module = getWasmModule();
|
|
if (!module || typeof module.check_indexeddb !== 'function') {
|
|
console.error('WebAssembly module or check_indexeddb function not available');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
const result = await module.check_indexeddb();
|
|
console.log('IndexedDB check result:', result);
|
|
return true;
|
|
} catch (error) {
|
|
console.error('IndexedDB check failed:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize a session with the given keyspace and password
|
|
* @param {string} keyspace
|
|
* @param {string} password
|
|
* @returns {Promise<Array>} List of keypairs after initialization
|
|
*/
|
|
export async function initSession(keyspace, password) {
|
|
const module = getWasmModule();
|
|
if (!module) {
|
|
throw new Error('WebAssembly module not loaded');
|
|
}
|
|
|
|
try {
|
|
console.log(`Initializing session for keyspace: ${keyspace}`);
|
|
|
|
// Check if IndexedDB is working
|
|
const isIndexedDBAvailable = await checkIndexedDBAvailability();
|
|
if (!isIndexedDBAvailable) {
|
|
console.warn('IndexedDB is not available or not working properly. Keypairs might not persist.');
|
|
// Continue anyway as we might fall back to memory storage
|
|
}
|
|
|
|
// Initialize the session using the WASM module
|
|
await module.init_session(keyspace, password);
|
|
console.log('Session initialized successfully');
|
|
|
|
// Check if we have stored keypairs for this keyspace in Chrome storage
|
|
const storedKeypairs = await new Promise(resolve => {
|
|
chrome.storage.local.get([`keypairs:${keyspace}`], result => {
|
|
resolve(result[`keypairs:${keyspace}`] || []);
|
|
});
|
|
});
|
|
|
|
console.log(`Found ${storedKeypairs.length} stored keypairs for keyspace ${keyspace}`);
|
|
|
|
// Import stored keypairs into the WebAssembly session if they don't exist already
|
|
if (storedKeypairs.length > 0) {
|
|
console.log('Importing stored keypairs into WebAssembly session...');
|
|
|
|
// First get current keypairs from the vault directly
|
|
const wasmKeypairs = await module.list_keypairs();
|
|
console.log('Current keypairs in WebAssembly vault:', wasmKeypairs);
|
|
|
|
// Get the IDs of existing keypairs in the vault
|
|
const existingIds = new Set(wasmKeypairs.map(kp => kp.id));
|
|
|
|
// Import keypairs that don't already exist in the vault
|
|
for (const keypair of storedKeypairs) {
|
|
if (!existingIds.has(keypair.id)) {
|
|
console.log(`Importing keypair ${keypair.id} into WebAssembly vault...`);
|
|
|
|
// Create metadata for the keypair
|
|
const metadata = JSON.stringify({
|
|
label: keypair.label || `Key-${keypair.id.substring(0, 8)}`,
|
|
imported: true,
|
|
importDate: new Date().toISOString()
|
|
});
|
|
|
|
// For adding existing keypairs, we'd normally need the private key
|
|
// Since we can't retrieve it, we'll create a new one with the same label
|
|
// This is a placeholder - in a real implementation, you'd need to use the actual keys
|
|
try {
|
|
const keyType = keypair.type || 'Secp256k1';
|
|
await module.add_keypair(keyType, metadata);
|
|
console.log(`Created keypair of type ${keyType} with label ${keypair.label}`);
|
|
} catch (err) {
|
|
console.warn(`Failed to import keypair ${keypair.id}:`, err);
|
|
// Continue with other keypairs even if one fails
|
|
}
|
|
} else {
|
|
console.log(`Keypair ${keypair.id} already exists in vault, skipping import`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize session using WASM (await the async function)
|
|
await module.init_session(keyspace, password);
|
|
|
|
// Get keypairs from the vault after session is ready
|
|
const currentKeypairs = await getKeypairsFromVault();
|
|
|
|
// Update keypairs in background service worker
|
|
await new Promise(resolve => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypairs_loaded',
|
|
data: currentKeypairs
|
|
}, response => {
|
|
console.log('Updated keypairs in background service worker');
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
return currentKeypairs;
|
|
} catch (error) {
|
|
console.error('Failed to initialize session:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lock the current session
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function lockSession() {
|
|
const module = getWasmModule();
|
|
if (!module) {
|
|
throw new Error('WebAssembly module not loaded');
|
|
}
|
|
|
|
try {
|
|
console.log('Locking session...');
|
|
|
|
// First run diagnostics to see what we have before locking
|
|
await debugVaultState();
|
|
|
|
// Call the WASM lock_session function
|
|
module.lock_session();
|
|
console.log('Session locked in WebAssembly module');
|
|
|
|
// Update session state in background
|
|
await new Promise((resolve, reject) => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'session_locked'
|
|
}, (response) => {
|
|
if (response && response.success) {
|
|
console.log('Background service worker updated for locked session');
|
|
resolve();
|
|
} else {
|
|
console.error('Failed to update session state in background:', response?.error);
|
|
reject(new Error(response?.error || 'Failed to update session state'));
|
|
}
|
|
});
|
|
});
|
|
|
|
// Verify session is locked properly
|
|
const sessionStatus = await debugVaultState();
|
|
console.log('Session status after locking:', sessionStatus);
|
|
} catch (error) {
|
|
console.error('Error locking session:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a new keypair
|
|
* @param {string} keyType The type of key to create (default: 'Secp256k1')
|
|
* @param {string} label Optional custom label for the keypair
|
|
* @returns {Promise<{id: string, label: string}>} The created keypair info
|
|
*/
|
|
export async function addKeypair(keyType = 'Secp256k1', label = null) {
|
|
const module = getWasmModule();
|
|
if (!module) {
|
|
throw new Error('WebAssembly module not loaded');
|
|
}
|
|
|
|
try {
|
|
// Get current keyspace
|
|
const sessionState = await getSessionState();
|
|
const keyspace = sessionState.currentKeyspace;
|
|
if (!keyspace) {
|
|
throw new Error('No active keyspace');
|
|
}
|
|
|
|
// Generate default label if not provided
|
|
const keyLabel = label || `${keyType}-Key-${Date.now().toString(16).slice(-4)}`;
|
|
|
|
// Create metadata JSON
|
|
const metadata = JSON.stringify({
|
|
label: keyLabel,
|
|
created: new Date().toISOString(),
|
|
type: keyType
|
|
});
|
|
|
|
console.log(`Adding new keypair of type ${keyType} with label ${keyLabel}`);
|
|
console.log('Keypair metadata:', metadata);
|
|
|
|
// Call the WASM add_keypair function with metadata
|
|
// This will add the keypair to the WebAssembly vault
|
|
const keyId = await module.add_keypair(keyType, metadata);
|
|
console.log(`Keypair created with ID: ${keyId} in WebAssembly vault`);
|
|
|
|
// Create keypair object for UI and storage
|
|
const newKeypair = {
|
|
id: keyId,
|
|
label: keyLabel,
|
|
type: keyType,
|
|
created: new Date().toISOString()
|
|
};
|
|
|
|
// Get the latest keypairs from the WebAssembly vault to ensure consistency
|
|
const vaultKeypairs = await module.list_keypairs();
|
|
console.log('Current keypairs in vault after addition:', vaultKeypairs);
|
|
|
|
// Format the vault keypairs for storage
|
|
const formattedVaultKeypairs = vaultKeypairs.map(kp => {
|
|
// Parse metadata if available
|
|
let metadata = {};
|
|
if (kp.metadata) {
|
|
try {
|
|
if (typeof kp.metadata === 'string') {
|
|
metadata = JSON.parse(kp.metadata);
|
|
} else {
|
|
metadata = kp.metadata;
|
|
}
|
|
} catch (e) {
|
|
console.warn('Failed to parse keypair metadata:', e);
|
|
}
|
|
}
|
|
|
|
return {
|
|
id: kp.id,
|
|
label: metadata.label || `Key-${kp.id.substring(0, 8)}`,
|
|
type: kp.type || 'Secp256k1',
|
|
created: metadata.created || new Date().toISOString()
|
|
};
|
|
});
|
|
|
|
// Save the formatted keypairs to Chrome storage
|
|
await new Promise(resolve => {
|
|
chrome.storage.local.set({ [`keypairs:${keyspace}`]: formattedVaultKeypairs }, () => {
|
|
console.log(`Saved ${formattedVaultKeypairs.length} keypairs to Chrome storage for keyspace ${keyspace}`);
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
// Update session state in background with the new keypair information
|
|
await new Promise((resolve, reject) => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypair_added',
|
|
data: newKeypair
|
|
}, async (response) => {
|
|
if (response && response.success) {
|
|
console.log('Background service worker updated with new keypair');
|
|
resolve(newKeypair);
|
|
} else {
|
|
const error = response?.error || 'Failed to update session state';
|
|
console.error('Error updating background state:', error);
|
|
reject(new Error(error));
|
|
}
|
|
});
|
|
});
|
|
|
|
// Also update the complete keypair list in background with the current vault state
|
|
await new Promise(resolve => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypairs_loaded',
|
|
data: formattedVaultKeypairs
|
|
}, () => {
|
|
console.log('Updated complete keypair list in background with vault state');
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
return newKeypair;
|
|
} catch (error) {
|
|
console.error('Error adding keypair:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select a keypair
|
|
* @param {string} keyId The ID of the keypair to select
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function selectKeypair(keyId) {
|
|
if (!wasmModule || !wasmModule.select_keypair) {
|
|
throw new Error('WASM module not loaded');
|
|
}
|
|
|
|
// Call the WASM select_keypair function
|
|
await wasmModule.select_keypair(keyId);
|
|
|
|
// Update session state in background
|
|
await new Promise((resolve, reject) => {
|
|
chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypair_selected',
|
|
data: keyId
|
|
}, (response) => {
|
|
if (response && response.success) {
|
|
resolve();
|
|
} else {
|
|
reject(response && response.error ? response.error : 'Failed to update session state');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sign a message with the selected keypair
|
|
* @param {string} message The message to sign
|
|
* @returns {Promise<string>} The signature as a hex string
|
|
*/
|
|
export async function sign(message) {
|
|
if (!wasmModule || !wasmModule.sign) {
|
|
throw new Error('WASM module not loaded');
|
|
}
|
|
|
|
// Convert message to Uint8Array
|
|
const encoder = new TextEncoder();
|
|
const messageBytes = encoder.encode(message);
|
|
|
|
// Call the WASM sign function
|
|
return await wasmModule.sign(messageBytes);
|
|
}
|
|
|
|
/**
|
|
* Get the current session state
|
|
* @returns {Promise<{currentKeyspace: string|null, keypairs: Array, selectedKeypair: string|null}>}
|
|
*/
|
|
export async function getSessionState() {
|
|
return new Promise((resolve) => {
|
|
chrome.runtime.sendMessage({ action: 'get_session' }, (response) => {
|
|
resolve(response || { currentKeyspace: null, keypairs: [], selectedKeypair: null });
|
|
});
|
|
});
|
|
}
|