async function loadUi () {
console.log('loading ui')
+ const dialogs = document.querySelectorAll('dialog')
+ for (const dialog of dialogs) {
+ const cancelButtons = dialog.querySelectorAll('button.cancel')
+ for (const cancelButton of cancelButtons) {
+ cancelButton.addEventListener('click', (event) => {
+ cancelDialog(dialog.id)
+ })
+ }
+ }
+ const clearStorageButton = document.querySelector('#clear-storage-button')
+ clearStorageButton.addEventListener('click', (event) => {
+ if (event.detail === 1) {
+ clearStorage()
+ }
+ })
setTimeout(() => {
document.getElementsByTagName('body')[0].style.visibility = 'visible'
}, 250)
_show: (msg, color) => {
const container = document.querySelector('#notifications')
const notification = document.createElement('dialog')
-
notification.innerText = msg
notification.style.color = color ?? notification.style.color
-
+ notification.addEventListener('click', (event) => {
+ notification.close()
+ notification.remove()
+ })
container.appendChild(notification)
notification.show()
},
info: (msg) => notify._show(`ℹ️ ${msg}`),
- ok: (msg) => notify._show(`☑️ ${msg}`, 'Cyan'),
+ ok: (msg) => notify._show(`☑️ ${msg}`),
error: (msg) => notify._show(`⚠️ ${msg}`, 'Gold')
}
const select = document.querySelector('#wallet')
switch (select.value) {
case '': {
- await updateAccountSelect(null)
+ await updateAccountSelect('')
return
}
case '_new': {
}
}
default: {
- const wallets = await getFromStorage('wallets')
- const walletData = wallets.find(w => {
- const { id, algorithm } = JSON.parse(w)
- return id === select.value
- })
- const { id, algorithm } = JSON.parse(walletData)
- const walletClass = getWalletClass(algorithm)
- const wallet = await walletClass.restore(id)
- await updateAccountSelect(wallet)
- return wallet
- }
- }
- }
-
- async function updateAccountSelect (wallet) {
- const accountSelect = document.querySelector('#account')
- if (wallet == null || wallet === '') {
- accountSelect.value = ''
- accountSelect.setAttribute('disabled', '')
- return
- }
- switch (accountSelect.value) {
- case '': {
- accountSelect.removeAttribute('disabled')
- return
- }
- case '_new': {
try {
- return await document.querySelector('#account-new').showModal()
+ const wallet = await loadWallet(select.value)
+ await updateAccountSelect(wallet)
} catch (err) {
- accountSelect.value = ''
- notify.error(`Error creating account: ${err}`)
+ select.value = ''
+ notify.error(`Error loading wallet: ${err}`)
return
}
}
- default: {
- accountSelect.removeAttribute('disabled')
- return await wallet.accounts(accountSelect.value)
- }
}
}
+ async function loadWallet (walletId) {
+ walletId ??= document.querySelector('#wallet')?.value
+ if (!walletId) {
+ throw new TypeError(`Wallet ID not found`)
+ }
+ const wallets = await getFromStorage('wallets')
+ const walletData = wallets.find(w => {
+ const { id, algorithm } = JSON.parse(w)
+ return id === walletId
+ })
+ const { id, algorithm } = JSON.parse(walletData)
+ const walletClass = getWalletClass(algorithm)
+ const wallet = await walletClass.restore(id)
+ return wallet
+ }
+
async function createWallet () {
const walletSelect = document.querySelector('#wallet')
const form = document.querySelector('#wallet-new')
}
}
- async function createAccount () {
- const wallet = await updateWalletSelect()
+ function updateWalletForm (id) {
+ const form = document.querySelector(id)
+ if (!form) {
+ notify.error(`Form ID not found, contact developer`)
+ return
+ }
+ const algorithmContainer = document.querySelector(`${id} -algorithm`)
+ const algorithm = document.querySelector(`${id} -algorithm select`)
+ const typeContainer = document.querySelector(`${id} -type`)
+ const type = document.querySelector(`${id} -type select`)
+ const saltContainer = document.querySelector(`${id} -salt`)
+ const salt = document.querySelector(`${id} -salt input`)
+ if (algorithm.value === 'bip44' && type?.value !== 'seed') {
+ saltContainer.classList.remove('hide')
+ } else {
+ saltContainer.classList.add('hide')
+ }
+ const importValue = document.querySelector(`${id} -value input`)
+ const importValueLabel = document.querySelector(`${id} -value label`)
+ if (importValueLabel) {
+ importValueLabel.innerText = type.value
+ }
+ }
+
+ async function updateAccountSelect (wallet) {
+ const accountSelect = document.querySelector('#account')
+ wallet ??= loadWallet()
+ if (wallet == null || wallet === '') {
+ accountSelect.value = ''
+ accountSelect.setAttribute('disabled', '')
+ return
+ }
+ switch (accountSelect.value) {
+ case '': {
+ accountSelect.removeAttribute('disabled')
+ return
+ }
+ case '_new': {
+ try {
+ return await document.querySelector('#account-new').showModal()
+ } catch (err) {
+ accountSelect.value = ''
+ notify.error(`Error creating account: ${err}`)
+ return
+ }
+ }
+ default: {
+ accountSelect.removeAttribute('disabled')
+ return await wallet.accounts(accountSelect.value)
+ }
+ }
+ }
+
+ async function createAccount (wallet) {
const accountSelect = document.querySelector('#account')
+ try {
+ wallet ??= await loadWallet()
+ } catch (err) {
+ notify.error(`Error creating account: ${err}`)
+ return
+ }
const form = document.querySelector('#account-new')
const name = form.querySelector('#account-new-name input').value
if (name.substring(0, 1) === '_') {
}
const index = form.querySelector('#account-new-index input')?.value
const password = form.querySelector('#account-new-password input')?.value
- let account
try {
- console.log('locking')
- console.log(await wallet.unlock(password))
- account = await wallet.accounts(index)
- console.log('locking')
- console.log(await wallet.lock(password))
+ console.log(`locked wallet: ${wallet}`)
+ const unlockResult = await wallet.unlock(password)
+ console.log(`unlockResult: ${unlockResult}`)
+ console.log(`unlocked wallet: ${wallet}`)
+ const account = await wallet.accounts(index)
+ console.log(`account: ${account}`)
+ const lockResult = await wallet.lock(password)
+ console.log(`lockResult: ${lockResult}`)
+ console.log(`locked wallet: ${wallet}`)
const accountData = {
id: index,
name: name || index
}
await addToStorage(`accounts`, JSON.stringify(accountData))
- const select = document.querySelector('#account')
const option = new Option(accountData.name, accountData.id, false, true)
select.add(option)
await updateAccountSelect(wallet)
}
}
- function updateWalletForm (id) {
- const form = document.querySelector(id)
- if (!form) {
- notify.error(`Form ID not found, contact developer`)
- return
- }
- const algorithmContainer = document.querySelector(`${id}-algorithm`)
- const algorithm = document.querySelector(`${id}-algorithm select`)
- const typeContainer = document.querySelector(`${id}-type`)
- const type = document.querySelector(`${id}-type select`)
- const saltContainer = document.querySelector(`${id}-salt`)
- const salt = document.querySelector(`${id}-salt input`)
- if (algorithm.value === 'bip44' && type?.value !== 'seed') {
- saltContainer.classList.remove('hide')
- } else {
- saltContainer.classList.add('hide')
- }
- const importValue = document.querySelector(`${id}-value input`)
- const importValueLabel = document.querySelector(`${id}-value label`)
- if (importValueLabel) {
- importValueLabel.innerText = type.value
- }
- }
-
- async function formCancel (id) {
- const form = document.querySelector(id)
- const inputs = form.querySelectorAll('input')
- for (const input of inputs) {
- input.value = ''
+ async function cancelDialog (id) {
+ const dialog = document.getElementById(id)
+ const fields = dialog.querySelectorAll('input, select')
+ for (const field of fields) {
+ field.value = ''
}
const wallet = document.querySelector('#wallet')
if (wallet.value.substring(0, 1) === '_') {
wallet.value = ''
}
- await form.close()
+ const account = document.querySelector('#account')
+ if (account.value.substring(0, 1) === '_') {
+ account.value = ''
+ }
+ await dialog.close()
}
async function showWallets () {
for (const wallet of wallets) {
const walletElement = document.createElement('label')
await wallet.unlock('password')
- walletElement.innerText = `${wallet.name}: ${wallet.mnemonic}`
+ walletElement.innerText = `${wallet.name}: ${wallet.mnemonic} `
await wallet.lock('password')
walletElements.push(walletElement)
}
}
async function clearStorage () {
+ const btn = document.querySelector('#clear-storage-button')
+ btn.setAttribute('disabled', '')
sessionStorage.clear()
const options = document.querySelectorAll('#wallet option, #account option')
for (const option of options) {
document.querySelector('#wallet').value = ''
document.querySelector('#account').value = ''
await updateWalletSelect()
- notify.info(`Session storage cleared`)
+ notify.ok(`Session storage cleared`)
+ btn.removeAttribute('disabled')
}
</script>
<style>
margin-right: 0.5em;
}
#notifications {
+ align-items: center;
display: flex;
flex-direction: column;
- justify-content: center;
+ margin: 0 auto;
+ pointer-events: none;
position: fixed;
top: 1rem;
- width: 100%;
- z-index: 100;
+ width: 100%;
}
- #notifications > dialog {
- align-items: center;
+ #notifications > dialog[open] {
+ background-color: var(--color-blue);
+ border: 1px solid var(--color-black);
+ border-radius: 0.5rem;
+ color: var(--color-light);
display: flex;
- margin: 1px 0px;
+ justify-content: center;
+ margin: 0.5rem 0;
+ pointer-events: auto;
+ position: relative;
padding: 0.5rem;
- width: auto;
+ width: fit-content;
+ z-index: 100;
}
.page {
display: none;
}
h1 {
text-align: center;
- }
- dialog {
- padding: 1rem !important;
}
label:has(+ :required)::after {
color: red;
<!-- Wallet Select -->
<div id="wallets" class="grid-x">
- <label for="wallet" class="grid x-2">Wallet</label>
- <select id="wallet" class="grid x-10" onchange="updateWalletSelect()">
+ <label for="wallet" class="grid x-3">Wallet</label>
+ <select id="wallet" class="grid x-9" onchange="updateWalletSelect()">
<option disabled selected value>Choose...</option>
<hr />
<option value="_new">New</option>
<hr />
<div class="grid-x">
<div class="grid x-4"></div>
- <button class="grid x-4" onclick="formCancel('#wallet-new')">
- Cancel
- </button>
- <button class="grid x-4" onclick="createWallet().then(w => { console.log(w);showWallets() })">
- OK
- </button>
+ <button id="wallet-new-cancel" class="cancel grid x-4">Cancel</button>
+ <button id="wallet-new-ok" class="grid x-4" onclick="createWallet().then(w => { console.log(w) })">OK</button>
</div>
</div>
</dialog>
<hr />
<div class="grid-x">
<div class="grid x-4"></div>
- <button class="grid x-4" onclick="formCancel('#wallet-import')">
- Cancel
- </button>
- <button class="grid x-4" onclick="importWallet().then(w => { console.log(w);showWallets() })">
- OK
- </button>
+ <button id="wallet-import-cancel" class="cancel grid x-4">Cancel</button>
+ <button id="wallet-import-ok" class="grid x-4" onclick="importWallet().then(w => { console.log(w);showWallets() })">OK</button>
</div>
</div>
</dialog>
<!-- Account Select -->
<div id="accounts" class="grid-x">
- <label for="account" class="grid x-2">Account</label>
- <select id="account" class="grid x-10" disabled onchange="updateWalletSelect()">
+ <label for="account" class="grid x-3">Account</label>
+ <select id="account" class="grid x-9" disabled onchange="updateAccountSelect()">
<option disabled selected value>Choose...</option>
<hr />
<option value="_new">New</option>
</div>
<div id="account-new-index" class="flex x-left x-mid">
<label for="account-new-index-input">Index</label>
- <input id="account-new-index-input" name="account-new-index" type="number" autocomplete="off" min="0" max="2147483647" />
+ <input id="account-new-index-input" name="account-new-index" type="number" autocomplete="off" min="0" max="2147483647" required />
</div>
<div id="account-new-password" class="flex x-left x-mid">
<label for="account-new-password-input">Unlock</label>
</div>
<div class="grid-x">
<div class="grid x-4"></div>
- <button class="grid x-4" onclick="formCancel('#account-new')">
- Cancel
- </button>
- <button class="grid x-4" onclick="createAccount().then(w => { console.log(w);showWallets() })">
- OK
- </button>
+ <button id="account-new-cancel" class="cancel grid x-4">Cancel</button>
+ <button id="account-new-ok" class="grid x-4" onclick="createAccount().then(w => { console.log(w) })">OK</button>
</div>
</div>
</dialog>
<div id="settings" class="page">
<h1>Settings</h1>
- <button onclick="clearStorage()">
+ <button id="clear-storage-button">
Clear Storage
</button>
</div>