From 9fbbc812c07399819869fd0777ebdafafaaa51dc Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Fri, 18 Oct 2024 00:27:24 -0700 Subject: [PATCH] Begin overhaul of wallet and account selection system. --- app/pages/nemo-wallet.html | 248 ++++++++++++++++++++++++++++++------- 1 file changed, 202 insertions(+), 46 deletions(-) diff --git a/app/pages/nemo-wallet.html b/app/pages/nemo-wallet.html index 4b83da0..0b2d2eb 100644 --- a/app/pages/nemo-wallet.html +++ b/app/pages/nemo-wallet.html @@ -59,28 +59,96 @@ } } } - async function createWallet (elm, type) { - const label = elm.firstElementChild + + async function updateWallet () { + const wallet = document.getElementById('wallet').value + if (wallet !== '_new' && wallet !== '_import' && wallet !== '_ledger') { + return await updateAccount() + } + if (wallet === '_ledger') { + return await LedgerWallet.create() + } + const form = document.getElementById('wallet-form') + const walletType = document.getElementById('wallet-form-wallet-type') + const importType = document.getElementById('wallet-form-import-type') + const importValue = document.getElementById('wallet-form-import-value') + const salt = document.getElementById('wallet-form-salt') + walletType.querySelector('x-radios').value = null + importType.querySelector('x-select').value = null + importValue.querySelector('x-input').value = null + salt.querySelector('x-input').value = null + if (wallet.value === '_new') { + importType.classList.add('hide') + importValue.classList.add('hide') + salt.classList.remove('hide') + } + if (wallet.value === '_import') { + importType.classList.remove('hide') + importValue.classList.remove('hide') + salt.classList.add('hide') + } + return await form.showModal() + } + + function spinner (btn) { + const label = btn.firstElementChild const spinner = document.createElement('x-throbber') spinner.size = 'small' spinner.style.width = `${label.scrollWidth}px` - elm.replaceChildren(spinner) + btn.replaceChildren(spinner) + // at some point then... + // btn.replaceChildren(label) + } + + async function createWallet () { + const walletSelect = document.getElementById('wallet') + const form = document.getElementById('wallet-form') + const name = form.querySelector('#wallet-form-name x-input').value + if (name === '_new' || name === '_import' || name === '_ledger') { + walletSelect.value = null + notify.warn(`Invalid wallet name "${name}".`) + return + } + const type = form.querySelector('#wallet-form-wallet-type x-radios').value const walletType = getWalletType(type) + const salt = form.querySelector('#wallet-form-salt x-input')?.value + const password = form.querySelector('#wallet-form-password x-input')?.value + if (!password) { + walletSelect.value = null + notify.error('Password is required') + return + } let wallet try { - wallet = await walletType.create('password') + wallet = await walletType.create(password, salt) const walletData = { id: wallet.id, + name: name || wallet.id, type } - addToStorage(`wallets`, JSON.stringify(walletData)) + await addToStorage(`wallets`, JSON.stringify(walletData)) + + const menu = document.querySelector('#wallet > x-menu') + const menuitem = document.createElement('x-menuitem') + menuitem.value = walletData.id + if (menu.childElementCount >= 0) { + menu.appendChild(menuitem) + } + const label = document.createElement('x-label') + label.innerText = walletData.name + menuitem.appendChild(label) + walletSelect.value = walletData.id } catch (err) { + label?.remove() + menuitem?.remove() + walletSelect.value = null notify.error(err.msg) } finally { - elm.replaceChildren(label) + await form.close() return wallet } } + function addToStorage (key, value) { if (typeof value !== 'string') { throw new TypeError(`Cannot add ${typeof value} to storage`) @@ -90,7 +158,29 @@ throw new TypeError(`Storage item is not an array`) } item.push(value) - sessionStorage.setItem(key, JSON.stringify(item)) + return new Promise((resolve, reject) => { + try { + sessionStorage.setItem(key, JSON.stringify(item)) + resolve() + } catch (err) { + console.error(err) + reject(err) + } + }) + } + function updateWalletForm () { + const form = document.getElementById('wallet-form') + const walletTypeContainer = document.getElementById('wallet-form-wallet-type') + const walletType = walletTypeContainer.firstChild + const importTypeContainer = document.getElementById('wallet-form-import-type') + const importType = importTypeContainer.firstChild + const saltContainer = document.getElementById('wallet-form-salt') + if (walletType.value === 'bip44' && importType.value === 'mnemonic') { + saltContainer.classList.remove('hide') + } else { + saltContainer.classList.add('hide') + } + document.querySelector('#wallet-form-import-value x-label').innerText = importType.value } async function showWallets () { const card = document.getElementById('walletCard') @@ -99,7 +189,7 @@ for (const walletData of storedWalletData) { const w = JSON.parse(walletData) console.dir(w) - if (w.id && w.type) { + if (w.id && w.name && w.type) { const walletType = getWalletType(w.type) wallets.push(await walletType.restore(w.id)) } @@ -108,12 +198,18 @@ for (const wallet of wallets) { const walletElement = document.createElement('x-label') await wallet.unlock('password') - walletElement.innerText = wallet.mnemonic + walletElement.innerText = `${wallet.name}: ${wallet.mnemonic}` await wallet.lock('password') walletElements.push(walletElement) } card.replaceChildren(...walletElements) } + + async function deriveAccounts () { + const wallet = document.querySelector('#wallet').value + const form = btn.querySelector('#account-form') + await console.log('deriveAccounts') + } async function clearStorage () { sessionStorage.clear() notify.info(`Session storage cleared`) @@ -138,8 +234,6 @@ - -