From 6e4dcb2e4f344af62440249daaa7c8fc8bea5b03 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 27 Feb 2026 12:11:46 -0800 Subject: [PATCH] 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 };