From 91eefa1667722bbaa43f24ea7814d4620fc56bbb Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:15:35 -0800 Subject: [PATCH 01/13] fix: use grey well for contract address display in address-token view - Replace border-b styling with bg-hover + dashed border for visual distinction from wallet address - Rename label from "Token Contract" to "Contract Address" - Addresses feedback on #9 --- src/popup/index.html | 2 +- src/popup/views/addressToken.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index 889aa51..30a7536 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -361,7 +361,7 @@ diff --git a/src/popup/views/addressToken.js b/src/popup/views/addressToken.js index 2701963..11f377e 100644 --- a/src/popup/views/addressToken.js +++ b/src/popup/views/addressToken.js @@ -143,7 +143,7 @@ function show() { const dot = addressDotHtml(tokenId); const tokenLink = `https://etherscan.io/token/${escapeHtml(tokenId)}`; let infoHtml = - `
Token Contract
` + + `
Contract Address
` + `
${dot}` + `${escapeHtml(tokenId)}` + `${EXT_ICON}` + From 7b004ddda494344edb5f878388d7b1c6232859d5 Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:26:24 -0800 Subject: [PATCH 02/13] fix: rework contract info well per review feedback - Remove border, add rounded corners and horizontal margin - Each attribute on its own line (key: value format) - Move well below send/receive buttons - Add project/token URL from tokenlist when available - Import TOKEN_BY_ADDRESS for URL lookup --- src/popup/index.html | 12 ++++++------ src/popup/views/addressToken.js | 28 +++++++++++----------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index 30a7536..ba10b29 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -358,12 +358,6 @@
- - -
+ + +
diff --git a/src/popup/views/addressToken.js b/src/popup/views/addressToken.js index 11f377e..e7763df 100644 --- a/src/popup/views/addressToken.js +++ b/src/popup/views/addressToken.js @@ -142,30 +142,24 @@ function show() { const tokenHolders = tb && tb.holders != null ? tb.holders : null; const dot = addressDotHtml(tokenId); const tokenLink = `https://etherscan.io/token/${escapeHtml(tokenId)}`; - let infoHtml = - `
Contract Address
` + - `
${dot}` + + const knownToken = TOKEN_BY_ADDRESS.get(tokenId.toLowerCase()); + const projectUrl = knownToken && knownToken.url ? knownToken.url : null; + let infoHtml = `
Contract Address
`; + infoHtml += + `
${dot}` + `${escapeHtml(tokenId)}` + `${EXT_ICON}` + `
`; - const details = []; if (tokenName) - details.push(`Name: ${tokenName}`); + infoHtml += `
Name: ${tokenName}
`; if (tokenSymbol) - details.push( - `Symbol: ${tokenSymbol}`, - ); + infoHtml += `
Symbol: ${tokenSymbol}
`; if (tokenDecimals != null) - details.push( - `Decimals: ${tokenDecimals}`, - ); + infoHtml += `
Decimals: ${tokenDecimals}
`; if (tokenHolders != null) - details.push( - `Holders: ${Number(tokenHolders).toLocaleString()}`, - ); - if (details.length > 0) { - infoHtml += `
${details.join("")}
`; - } + infoHtml += `
Holders: ${Number(tokenHolders).toLocaleString()}
`; + if (projectUrl) + infoHtml += ``; contractInfo.innerHTML = infoHtml; contractInfo.classList.remove("hidden"); } else { From 8332570758569f77ad44629b58224f000b5f8d1b Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:27:23 -0800 Subject: [PATCH 03/13] fix: increase well horizontal margin to mx-4 per review --- src/popup/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/index.html b/src/popup/index.html index ba10b29..e6562c2 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -377,7 +377,7 @@ From 8b7d73cc35db4c6c729f74a4f88532f740eb8d28 Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:34:23 -0800 Subject: [PATCH 04/13] fix: pass UUID approval ID as string, not parseInt (closes #4) The approval ID was changed from sequential integers to crypto.randomUUID() strings for security, but the popup still called parseInt() on it, which converted the UUID to NaN. This caused every approval lookup to fail, preventing the confirmation popup from displaying pending tx/sign requests. --- src/popup/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/index.js b/src/popup/index.js index 9413805..5a12180 100644 --- a/src/popup/index.js +++ b/src/popup/index.js @@ -189,7 +189,7 @@ async function init() { const params = new URLSearchParams(window.location.search); const approvalId = params.get("approval"); if (approvalId) { - approval.show(parseInt(approvalId, 10)); + approval.show(approvalId); showView("approve-site"); return; } From 3b419c7517e7c15270bd23d039d3d956a46cbcf3 Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:50:26 -0800 Subject: [PATCH 05/13] fix: add missing TOKEN_BY_ADDRESS import in addressToken view --- src/popup/views/addressToken.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/popup/views/addressToken.js b/src/popup/views/addressToken.js index e7763df..1284029 100644 --- a/src/popup/views/addressToken.js +++ b/src/popup/views/addressToken.js @@ -11,6 +11,7 @@ const { balanceLine, } = require("./helpers"); const { state, currentAddress, saveState } = require("../../shared/state"); +const { TOKEN_BY_ADDRESS } = require("../../shared/tokenList"); const { formatUsd, getPrice, From 689bcbf1717c2884f521f74653bf3b452380c4ad Mon Sep 17 00:00:00 2001 From: user Date: Fri, 27 Feb 2026 12:11:46 -0800 Subject: [PATCH 06/13] feat: add wallet deletion from settings (closes #13) --- src/popup/index.html | 53 ++++++++++++++++++++++++++++ src/popup/views/settings.js | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/src/popup/index.html b/src/popup/index.html index 889aa51..68edf66 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -843,6 +843,59 @@

+ +
+

Danger Zone

+

+ Permanently delete the currently selected wallet. This + cannot be undone. Make sure you have backed up your + recovery phrase before proceeding. +

+ +
+ +
diff --git a/src/popup/views/settings.js b/src/popup/views/settings.js index 8562b96..eb01cf3 100644 --- a/src/popup/views/settings.js +++ b/src/popup/views/settings.js @@ -2,6 +2,7 @@ const { $, showView, showFlash, escapeHtml } = require("./helpers"); const { state, saveState } = require("../../shared/state"); const { ETHEREUM_MAINNET_CHAIN_ID } = require("../../shared/constants"); const { log, debugFetch } = require("../../shared/log"); +const { decryptWithPassword } = require("../../shared/vault"); const runtime = typeof browser !== "undefined" ? browser.runtime : chrome.runtime; @@ -192,6 +193,74 @@ function init(ctx) { ctx.renderWalletList(); showView("main"); }); + + $("btn-delete-wallet").addEventListener("click", () => { + if (state.selectedWallet === null || state.wallets.length === 0) { + showFlash("No wallet selected."); + return; + } + const wallet = state.wallets[state.selectedWallet]; + $("delete-wallet-name").textContent = wallet.name || "this wallet"; + $("delete-wallet-password").value = ""; + $("delete-wallet-confirm").classList.remove("hidden"); + }); + + $("btn-delete-wallet-cancel").addEventListener("click", () => { + $("delete-wallet-confirm").classList.add("hidden"); + $("delete-wallet-password").value = ""; + }); + + $("btn-delete-wallet-confirm").addEventListener("click", async () => { + const pw = $("delete-wallet-password").value; + if (!pw) { + showFlash("Password required."); + return; + } + + const walletIdx = state.selectedWallet; + const wallet = state.wallets[walletIdx]; + + // Verify password against the wallet's encrypted data + try { + await decryptWithPassword(wallet.encrypted, pw); + } catch (_e) { + showFlash("Wrong password."); + return; + } + + // Collect addresses to clean up from allowedSites/deniedSites + const addresses = (wallet.addresses || []).map((a) => a.address); + + // Remove wallet + state.wallets.splice(walletIdx, 1); + + // Clean up site permissions for deleted addresses + for (const addr of addresses) { + delete state.allowedSites[addr]; + delete state.deniedSites[addr]; + } + + if (state.wallets.length === 0) { + // No wallets left — reset selection and show welcome + state.selectedWallet = null; + state.selectedAddress = null; + state.activeAddress = null; + await saveState(); + $("delete-wallet-confirm").classList.add("hidden"); + showView("welcome"); + } else { + // Switch to first wallet if deleted wallet was active + state.selectedWallet = 0; + state.selectedAddress = 0; + state.activeAddress = + state.wallets[0].addresses[0]?.address || null; + await saveState(); + $("delete-wallet-confirm").classList.add("hidden"); + showFlash("Wallet deleted."); + ctx.renderWalletList(); + showView("main"); + } + }); } module.exports = { init, show, renderSiteLists }; From 34cd72be88a5cf5471f390fe61e5cc077a1f8392 Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:44:40 -0800 Subject: [PATCH 07/13] fix: rework wallet deletion per review feedback - Remove all red/danger styling, use standard monochrome colors - Add wallet picker dropdown instead of relying on selectedWallet - Fix encryptedSecret field name (was wallet.encrypted) - Populate dropdown when settings view opens - Confirmation modal uses standard border styling --- src/popup/views/settings.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/popup/views/settings.js b/src/popup/views/settings.js index eb01cf3..a6f9083 100644 --- a/src/popup/views/settings.js +++ b/src/popup/views/settings.js @@ -71,6 +71,17 @@ function show() { $("settings-blockscout").value = state.blockscoutUrl; renderTrackedTokens(); renderSiteLists(); + // Populate wallet deletion dropdown + const sel = $("delete-wallet-select"); + sel.innerHTML = ""; + for (let i = 0; i < state.wallets.length; i++) { + const opt = document.createElement("option"); + opt.value = i; + opt.textContent = state.wallets[i].name || "Wallet " + (i + 1); + sel.appendChild(opt); + } + $("delete-wallet-confirm").classList.add("hidden"); + showView("settings"); } From 655b90c7dfa3341e1fa19727162776a3f8098fca Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 12:46:03 -0800 Subject: [PATCH 08/13] feat: add wallet deletion from settings (closes #13) - Per-wallet [delete] links in settings wallet list - Monochrome styling throughout, no red/danger colors - Password confirmation modal with warning text - Cleans up site permissions for deleted addresses - Switches to first remaining wallet or shows welcome if none left --- src/popup/index.html | 38 +++++----------------- src/popup/views/settings.js | 63 ++++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index 68edf66..4a2b899 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -708,9 +708,7 @@

Wallets

-

- Add a new wallet from a recovery phrase or private key. -

+
-
-

Danger Zone

-

- Permanently delete the currently selected wallet. This - cannot be undone. Make sure you have backed up your - recovery phrase before proceeding. -

- -
- `; }); container.innerHTML = html; @@ -94,6 +94,38 @@ function renderWalletListSettings() { $("delete-wallet-confirm").classList.remove("hidden"); }); }); + + // Inline rename on click + container.querySelectorAll(".settings-wallet-name").forEach((span) => { + span.addEventListener("click", () => { + const idx = parseInt(span.dataset.idx, 10); + const wallet = state.wallets[idx]; + const input = document.createElement("input"); + input.type = "text"; + input.className = + "border border-border p-0 text-xs bg-bg text-fg w-full"; + input.value = wallet.name || "Wallet " + (idx + 1); + span.replaceWith(input); + input.focus(); + input.select(); + const finish = async () => { + const val = input.value.trim(); + if (val && val !== wallet.name) { + wallet.name = val; + await saveState(); + } + renderWalletListSettings(); + }; + input.addEventListener("blur", finish); + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") input.blur(); + if (e.key === "Escape") { + input.value = wallet.name || "Wallet " + (idx + 1); + input.blur(); + } + }); + }); + }); } function show() { From 2b0b889b0118d82f765946f610f3adb28a5a68b5 Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 13:52:08 -0800 Subject: [PATCH 10/13] fix: use wallet.encryptedSecret not wallet.encrypted for password verify --- src/popup/views/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/views/settings.js b/src/popup/views/settings.js index 535d38a..34a0de2 100644 --- a/src/popup/views/settings.js +++ b/src/popup/views/settings.js @@ -283,7 +283,7 @@ function init(ctx) { // Verify password against the wallet's encrypted data try { - await decryptWithPassword(wallet.encrypted, pw); + await decryptWithPassword(wallet.encryptedSecret, pw); } catch (_e) { showFlash("Wrong password."); return; From 2bffa910459fd8b97cbe5e74ffde75bc3f5f1a6c Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 13:54:19 -0800 Subject: [PATCH 11/13] fix: reduce contract info well margins to prevent address wrapping --- src/popup/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/index.html b/src/popup/index.html index e6562c2..ba10b29 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -377,7 +377,7 @@ From 8893f5dce78608d6c7f2f019e52b91c0ace44ace Mon Sep 17 00:00:00 2001 From: clawbot Date: Fri, 27 Feb 2026 13:58:58 -0800 Subject: [PATCH 12/13] refactor: delete-wallet-confirm as standalone full view Replace the inline confirmation div at the bottom of Settings with a proper full-screen view (view-delete-wallet-confirm). This fixes the issue where the confirmation was offscreen on the 360x600 popup. - New view with back button, title, warning text, password input, and red-text Confirm Delete button - Dedicated flash area for password errors - New deleteWallet.js module with init/show pattern - Added delete-wallet-confirm to VIEWS array in helpers.js - Removed old inline confirmation HTML and logic from settings --- src/popup/index.html | 54 ++++++++++---------- src/popup/views/deleteWallet.js | 90 +++++++++++++++++++++++++++++++++ src/popup/views/helpers.js | 1 + src/popup/views/settings.js | 81 ++--------------------------- 4 files changed, 123 insertions(+), 103 deletions(-) create mode 100644 src/popup/views/deleteWallet.js diff --git a/src/popup/index.html b/src/popup/index.html index 4a2b899..0818067 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -841,39 +841,41 @@

+ -