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.
+
+
+
+
+
+
+ Confirm Deletion
+
+
+ Deleting is
+ permanent. Any funds on this wallet will be
+ unrecoverable if you have not backed up your recovery
+ phrase.
+
+
Enter your password to confirm:
+
+
+
+
+
+
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 };