diff --git a/www/js/ethereum.js b/www/js/ethereum.js index 0880ef1..dfd3cba 100644 --- a/www/js/ethereum.js +++ b/www/js/ethereum.js @@ -33,17 +33,107 @@ function hexToBuffer(hex) { return bytes; } -// LocalStorage functions for Ethereum wallets -const ETH_WALLET_PREFIX = 'eth_wallet_'; +// IndexedDB setup for Ethereum wallets +const DB_NAME = 'EthWalletDB'; +const DB_VERSION = 1; +const STORE_NAME = 'ethWallets'; -// Save Ethereum wallet to localStorage -function saveEthWalletToStorage(address, privateKey) { - localStorage.setItem(`${ETH_WALLET_PREFIX}${address}`, privateKey); +// Initialize the database +function initDatabase() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(DB_NAME, DB_VERSION); + + request.onerror = (event) => { + console.error('Error opening Ethereum wallet database:', event.target.error); + reject('Error opening database: ' + event.target.error); + }; + + request.onsuccess = (event) => { + const db = event.target.result; + resolve(db); + }; + + request.onupgradeneeded = (event) => { + const db = event.target.result; + // Create object store for Ethereum wallets if it doesn't exist + if (!db.objectStoreNames.contains(STORE_NAME)) { + const store = db.createObjectStore(STORE_NAME, { keyPath: 'address' }); + store.createIndex('address', 'address', { unique: true }); + } + }; + }); } -// Get Ethereum wallet from localStorage -function getEthWalletFromStorage(address) { - return localStorage.getItem(`${ETH_WALLET_PREFIX}${address}`); +// Get database connection +function getDB() { + return initDatabase(); +} + +// Save Ethereum wallet to IndexedDB +async function saveEthWalletToStorage(address, privateKey) { + try { + const db = await getDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + + const wallet = { + address: address, + privateKey: privateKey, + created: new Date() + }; + + const request = store.put(wallet); + + request.onsuccess = () => { + resolve(); + }; + + request.onerror = (event) => { + console.error('Error saving Ethereum wallet:', event.target.error); + reject('Error saving wallet: ' + event.target.error); + }; + + transaction.oncomplete = () => { + db.close(); + }; + }); + } catch (error) { + console.error('Database error in saveEthWalletToStorage:', error); + } +} + +// Get Ethereum wallet from IndexedDB +async function getEthWalletFromStorage(address) { + try { + const db = await getDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.get(address); + + request.onsuccess = (event) => { + const wallet = event.target.result; + if (wallet) { + resolve(wallet.privateKey); + } else { + resolve(null); + } + }; + + request.onerror = (event) => { + console.error('Error retrieving Ethereum wallet:', event.target.error); + reject('Error retrieving wallet: ' + event.target.error); + }; + + transaction.oncomplete = () => { + db.close(); + }; + }); + } catch (error) { + console.error('Database error in getEthWalletFromStorage:', error); + return null; + } } // Session state @@ -147,13 +237,20 @@ async function performCreateEthereumWallet() { } try { + // Show loading state + document.getElementById('ethereum-wallet-result').textContent = 'Creating wallet...'; + // Create Ethereum wallet + console.log('Creating Ethereum wallet from keypair:', selectedKeypair); const result = create_ethereum_wallet(); + console.log('Create Ethereum wallet result:', result); + if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); + console.log('Generated Ethereum address:', address); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key @@ -163,14 +260,22 @@ async function performCreateEthereumWallet() { // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); - // Save the wallet to localStorage - saveEthWalletToStorage(address, privateKey); - - document.getElementById('ethereum-wallet-result').textContent = 'Successfully created Ethereum wallet'; + try { + // Save the wallet to IndexedDB + console.log('Saving wallet to IndexedDB:', address); + await saveEthWalletToStorage(address, privateKey); + console.log('Wallet saved successfully'); + + document.getElementById('ethereum-wallet-result').textContent = 'Successfully created Ethereum wallet'; + } catch (saveError) { + console.error('Error saving wallet to IndexedDB:', saveError); + document.getElementById('ethereum-wallet-result').textContent = 'Wallet created but failed to save to storage'; + } } else { document.getElementById('ethereum-wallet-result').textContent = `Error creating Ethereum wallet: ${result}`; } } catch (e) { + console.error('Error in performCreateEthereumWallet:', e); document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } @@ -190,13 +295,20 @@ async function performCreateEthereumWalletFromName() { } try { + // Show loading state + document.getElementById('ethereum-wallet-result').textContent = 'Creating wallet...'; + // Create Ethereum wallet from name + console.log('Creating Ethereum wallet from name:', name); const result = create_ethereum_wallet_from_name(name); + console.log('Create Ethereum wallet from name result:', result); + if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); + console.log('Generated Ethereum address:', address); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key @@ -206,14 +318,22 @@ async function performCreateEthereumWalletFromName() { // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); - // Save the wallet to localStorage - saveEthWalletToStorage(address, privateKey); - - document.getElementById('ethereum-wallet-result').textContent = `Successfully created Ethereum wallet from name "${name}"`; + try { + // Save the wallet to IndexedDB + console.log('Saving wallet to IndexedDB:', address); + await saveEthWalletToStorage(address, privateKey); + console.log('Wallet saved successfully'); + + document.getElementById('ethereum-wallet-result').textContent = `Successfully created Ethereum wallet from name "${name}"`; + } catch (saveError) { + console.error('Error saving wallet to IndexedDB:', saveError); + document.getElementById('ethereum-wallet-result').textContent = 'Wallet created but failed to save to storage'; + } } else { document.getElementById('ethereum-wallet-result').textContent = `Error creating Ethereum wallet: ${result}`; } } catch (e) { + console.error('Error in performCreateEthereumWalletFromName:', e); document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } @@ -228,13 +348,20 @@ async function performCreateEthereumWalletFromPrivateKey() { } try { + // Show loading state + document.getElementById('ethereum-wallet-result').textContent = 'Creating wallet...'; + // Create Ethereum wallet from private key + console.log('Creating Ethereum wallet from private key'); const result = create_ethereum_wallet_from_private_key(privateKey); + console.log('Create Ethereum wallet from private key result:', result); + if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); + console.log('Generated Ethereum address:', address); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key @@ -244,14 +371,22 @@ async function performCreateEthereumWalletFromPrivateKey() { // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); - // Save the wallet to localStorage - saveEthWalletToStorage(address, displayPrivateKey); - - document.getElementById('ethereum-wallet-result').textContent = 'Successfully imported Ethereum wallet from private key'; + try { + // Save the wallet to IndexedDB + console.log('Saving wallet to IndexedDB:', address); + await saveEthWalletToStorage(address, displayPrivateKey); + console.log('Wallet saved successfully'); + + document.getElementById('ethereum-wallet-result').textContent = 'Successfully imported Ethereum wallet from private key'; + } catch (saveError) { + console.error('Error saving wallet to IndexedDB:', saveError); + document.getElementById('ethereum-wallet-result').textContent = 'Wallet imported but failed to save to storage'; + } } else { document.getElementById('ethereum-wallet-result').textContent = `Error importing Ethereum wallet: ${result}`; } } catch (e) { + console.error('Error in performCreateEthereumWalletFromPrivateKey:', e); document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } diff --git a/www/js/index.js b/www/js/index.js index 6adaf9a..f49ec20 100644 --- a/www/js/index.js +++ b/www/js/index.js @@ -140,32 +140,37 @@ async function saveSpaceToStorage(spaceName, encryptedData) { // Get encrypted space from IndexedDB async function getSpaceFromStorage(spaceName) { - const db = await getDB(); - return new Promise((resolve, reject) => { - const transaction = db.transaction([STORE_NAME], 'readonly'); - const store = transaction.objectStore(STORE_NAME); - const request = store.get(spaceName); - - request.onsuccess = (event) => { - const space = event.target.result; - if (space) { - // Update last accessed timestamp - updateLastAccessed(spaceName).catch(console.error); - resolve(space.encryptedData); - } else { - resolve(null); - } - }; - - request.onerror = (event) => { - console.error('Error retrieving space:', event.target.error); - reject('Error retrieving space: ' + event.target.error); - }; - - transaction.oncomplete = () => { - db.close(); - }; - }); + try { + const db = await getDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.get(spaceName); + + request.onsuccess = (event) => { + const space = event.target.result; + if (space) { + // Update last accessed timestamp + updateLastAccessed(spaceName).catch(console.error); + resolve(space.encryptedData); + } else { + resolve(null); + } + }; + + request.onerror = (event) => { + console.error('Error retrieving space:', event.target.error); + reject('Error retrieving space: ' + event.target.error); + }; + + transaction.oncomplete = () => { + db.close(); + }; + }); + } catch (error) { + console.error('Database error in getSpaceFromStorage:', error); + return null; + } } // Update last accessed timestamp @@ -253,7 +258,7 @@ let currentSpace = null; let selectedKeypair = null; // Update UI based on login state -function updateLoginUI() { +async function updateLoginUI() { const loginForm = document.getElementById('login-form'); const logoutForm = document.getElementById('logout-form'); const loginStatus = document.getElementById('login-status'); @@ -274,7 +279,11 @@ function updateLoginUI() { } // Update the spaces list - updateSpacesList(); + try { + await updateSpacesList(); + } catch (e) { + console.error('Error updating spaces list in UI:', e); + } } // Update the spaces dropdown list @@ -323,24 +332,33 @@ async function performLogin() { return; } - // Decrypt the space - const result = decrypt_key_space(encryptedSpace, password); - if (result === 0) { - isLoggedIn = true; - currentSpace = spaceName; - updateLoginUI(); - updateKeypairsList(); - document.getElementById('space-result').textContent = `Successfully logged in to space "${spaceName}"`; + console.log('Retrieved space from IndexedDB:', { spaceName, encryptedDataLength: encryptedSpace.length }); + + try { + // Decrypt the space - this is a synchronous WebAssembly function + const result = decrypt_key_space(encryptedSpace, password); + console.log('Decrypt result:', result); - // Setup auto-logout - updateActivity(); - setupAutoLogout(); - - // Add activity listeners - document.addEventListener('click', updateActivity); - document.addEventListener('keypress', updateActivity); - } else { - document.getElementById('space-result').textContent = `Error logging in: ${result}`; + if (result === 0) { + isLoggedIn = true; + currentSpace = spaceName; + await updateLoginUI(); + updateKeypairsList(); + document.getElementById('space-result').textContent = `Successfully logged in to space "${spaceName}"`; + + // Setup auto-logout + updateActivity(); + setupAutoLogout(); + + // Add activity listeners + document.addEventListener('click', updateActivity); + document.addEventListener('keypress', updateActivity); + } else { + document.getElementById('space-result').textContent = `Error logging in: ${result}`; + } + } catch (decryptErr) { + console.error('Decryption error:', decryptErr); + document.getElementById('space-result').textContent = `Decryption error: ${decryptErr}`; } } catch (e) { console.error('Login error:', e); @@ -369,31 +387,50 @@ async function performCreateSpace() { return; } - // Create new space - const result = create_key_space(spaceName); - if (result === 0) { - // Encrypt and save the space - const encryptedSpace = encrypt_key_space(password); - await saveSpaceToStorage(spaceName, encryptedSpace); + try { + // Create new space + console.log('Creating new space:', spaceName); + const result = create_key_space(spaceName); + console.log('Create space result:', result); - isLoggedIn = true; - currentSpace = spaceName; - updateLoginUI(); - updateKeypairsList(); - document.getElementById('space-result').textContent = `Successfully created space "${spaceName}"`; - - // Setup auto-logout - updateActivity(); - setupAutoLogout(); - - // Add activity listeners - document.addEventListener('click', updateActivity); - document.addEventListener('keypress', updateActivity); - } else { - document.getElementById('space-result').textContent = `Error creating space: ${result}`; + if (result === 0) { + try { + // Encrypt and save the space + console.log('Encrypting space with password'); + const encryptedSpace = encrypt_key_space(password); + console.log('Encrypted space length:', encryptedSpace.length); + + // Save to IndexedDB + console.log('Saving to IndexedDB'); + await saveSpaceToStorage(spaceName, encryptedSpace); + console.log('Save completed'); + + isLoggedIn = true; + currentSpace = spaceName; + await updateLoginUI(); + updateKeypairsList(); + document.getElementById('space-result').textContent = `Successfully created space "${spaceName}"`; + + // Setup auto-logout + updateActivity(); + setupAutoLogout(); + + // Add activity listeners + document.addEventListener('click', updateActivity); + document.addEventListener('keypress', updateActivity); + } catch (encryptError) { + console.error('Error encrypting or saving space:', encryptError); + document.getElementById('space-result').textContent = `Error saving space: ${encryptError}`; + } + } else { + document.getElementById('space-result').textContent = `Error creating space: ${result}`; + } + } catch (createError) { + console.error('Error in WebAssembly create_key_space:', createError); + document.getElementById('space-result').textContent = `Error creating key space: ${createError}`; } } catch (e) { - console.error('Error creating space:', e); + console.error('Error checking existing space:', e); document.getElementById('space-result').textContent = `Error: ${e}`; } }