// Simple non-module JavaScript for browser extension popup
document.addEventListener('DOMContentLoaded', async function() {
const root = document.getElementById('root');
root.innerHTML = `
Modular Vault Extension
Loading WASM module...
Active Session
Current keyspace:
`;
// DOM elements
const statusEl = document.getElementById('status');
const keyspaceFormEl = document.getElementById('keyspace-form');
const sessionInfoEl = document.getElementById('session-info');
const currentKeyspaceEl = document.getElementById('current-keyspace');
const keyspaceInput = document.getElementById('keyspace');
const passwordInput = document.getElementById('password');
const unlockBtn = document.getElementById('unlock-btn');
const createBtn = document.getElementById('create-btn');
const lockBtn = document.getElementById('lock-btn');
const createKeypairBtn = document.getElementById('create-keypair-btn');
const keypairListEl = document.getElementById('keypair-list');
const signSectionEl = document.getElementById('sign-section');
const messageInput = document.getElementById('message');
const signBtn = document.getElementById('sign-btn');
const signatureOutput = document.getElementById('signature');
const copyBtn = document.getElementById('copy-btn');
// State
let wasmModule = null;
let currentKeyspace = null;
let keypairs = [];
let selectedKeypairId = null;
// Initialize
init();
async function init() {
try {
// Get session state from background
const sessionState = await getSessionState();
if (sessionState.currentKeyspace) {
// We have an active session
currentKeyspace = sessionState.currentKeyspace;
keypairs = sessionState.keypairs || [];
selectedKeypairId = sessionState.selectedKeypair;
updateUI();
}
statusEl.textContent = 'Ready';
} catch (error) {
statusEl.textContent = 'Error: ' + (error.message || 'Unknown error');
}
}
function updateUI() {
if (currentKeyspace) {
// Show session info
keyspaceFormEl.classList.add('hidden');
sessionInfoEl.classList.remove('hidden');
currentKeyspaceEl.textContent = currentKeyspace;
// Update keypair list
updateKeypairList();
// Show/hide sign section based on selected keypair
if (selectedKeypairId) {
signSectionEl.classList.remove('hidden');
} else {
signSectionEl.classList.add('hidden');
}
} else {
// Show keyspace form
keyspaceFormEl.classList.remove('hidden');
sessionInfoEl.classList.add('hidden');
}
}
function updateKeypairList() {
// Clear list
keypairListEl.innerHTML = '';
// Add each keypair
keypairs.forEach(keypair => {
const item = document.createElement('div');
item.className = 'list-item' + (selectedKeypairId === keypair.id ? ' selected' : '');
item.innerHTML = `
${keypair.label || keypair.id}
`;
keypairListEl.appendChild(item);
// Add select handler
item.querySelector('.select-btn').addEventListener('click', async () => {
try {
statusEl.textContent = 'Selecting keypair...';
// Use background service to select keypair for now
await chrome.runtime.sendMessage({
action: 'update_session',
type: 'keypair_selected',
data: keypair.id
});
selectedKeypairId = keypair.id;
updateUI();
statusEl.textContent = 'Keypair selected: ' + keypair.id;
} catch (error) {
statusEl.textContent = 'Error selecting keypair: ' + (error.message || 'Unknown error');
}
});
});
}
// Get session state from background
async function getSessionState() {
return new Promise((resolve) => {
chrome.runtime.sendMessage({ action: 'get_session' }, (response) => {
resolve(response || { currentKeyspace: null, keypairs: [], selectedKeypair: null });
});
});
}
// Event handlers
unlockBtn.addEventListener('click', async () => {
const keyspace = keyspaceInput.value.trim();
const password = passwordInput.value;
if (!keyspace || !password) {
statusEl.textContent = 'Please enter keyspace and password';
return;
}
statusEl.textContent = 'Unlocking session...';
try {
// For now, use the background service worker mock
await chrome.runtime.sendMessage({
action: 'update_session',
type: 'keyspace',
data: keyspace
});
currentKeyspace = keyspace;
updateUI();
statusEl.textContent = 'Session unlocked!';
// Refresh state
const state = await getSessionState();
keypairs = state.keypairs || [];
selectedKeypairId = state.selectedKeypair;
updateUI();
} catch (error) {
statusEl.textContent = 'Error unlocking session: ' + (error.message || 'Unknown error');
}
});
createBtn.addEventListener('click', async () => {
const keyspace = keyspaceInput.value.trim();
const password = passwordInput.value;
if (!keyspace || !password) {
statusEl.textContent = 'Please enter keyspace and password';
return;
}
statusEl.textContent = 'Creating keyspace...';
try {
// For now, use the background service worker mock
await chrome.runtime.sendMessage({
action: 'update_session',
type: 'keyspace',
data: keyspace
});
currentKeyspace = keyspace;
updateUI();
statusEl.textContent = 'Keyspace created and unlocked!';
} catch (error) {
statusEl.textContent = 'Error creating keyspace: ' + (error.message || 'Unknown error');
}
});
lockBtn.addEventListener('click', async () => {
statusEl.textContent = 'Locking session...';
try {
await chrome.runtime.sendMessage({
action: 'update_session',
type: 'session_locked'
});
currentKeyspace = null;
keypairs = [];
selectedKeypairId = null;
updateUI();
statusEl.textContent = 'Session locked';
} catch (error) {
statusEl.textContent = 'Error locking session: ' + (error.message || 'Unknown error');
}
});
createKeypairBtn.addEventListener('click', async () => {
statusEl.textContent = 'Creating keypair...';
try {
// Generate a mock keypair ID
const keyId = 'key-' + Date.now().toString(16);
const newKeypair = {
id: keyId,
label: `Secp256k1-Key-${keypairs.length + 1}`
};
await chrome.runtime.sendMessage({
action: 'update_session',
type: 'keypair_added',
data: newKeypair
});
// Refresh state
const state = await getSessionState();
keypairs = state.keypairs || [];
updateUI();
statusEl.textContent = 'Keypair created: ' + keyId;
} catch (error) {
statusEl.textContent = 'Error creating keypair: ' + (error.message || 'Unknown error');
}
});
signBtn.addEventListener('click', async () => {
const message = messageInput.value.trim();
if (!message) {
statusEl.textContent = 'Please enter a message to sign';
return;
}
if (!selectedKeypairId) {
statusEl.textContent = 'Please select a keypair first';
return;
}
statusEl.textContent = 'Signing message...';
try {
// For now, generate a mock signature
const mockSignature = Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join('');
signatureOutput.value = mockSignature;
statusEl.textContent = 'Message signed!';
} catch (error) {
statusEl.textContent = 'Error signing message: ' + (error.message || 'Unknown error');
}
});
copyBtn.addEventListener('click', () => {
signatureOutput.select();
document.execCommand('copy');
statusEl.textContent = 'Signature copied to clipboard!';
});
});