feat: remove an address from an HD wallet, behind a confirmation (closes #162)
All checks were successful
check / check (push) Successful in 36s

Address rows on Home gain an [x] control, on wallets that derive addresses from
an extended key and hold more than one, opening a DeleteAddress confirmation
screen.

Removal cannot destroy anything: the key material stays. Derivation indices are
not renumbered, so the next "+" derives the next unused index rather than
resurrecting the removed one. The confirmation states the real route back --
delete the whole wallet in Settings, which asks for the password and destroys
the stored recovery phrase, then import it again -- and notes that the scan
which follows only finds addresses with on-chain activity. The copy varies by
wallet type, since an xprv wallet has no recovery phrase.

Removing an address that holds a balance is allowed, with a warning naming no
figure; the funds are at the address on-chain and stay there either way.
Selection and active address move only when the removed address was the one
selected, and site permissions are dropped for it alone.

The state transition shares its address comparison, permission cleanup and
active-changed broadcast with the wallet-level removal.
This commit was merged in pull request #240.
This commit is contained in:
2026-08-12 11:16:29 +02:00
parent 1f41a07df2
commit 937f699fb1
11 changed files with 905 additions and 19 deletions

View File

@@ -25,6 +25,7 @@ const VIEWS = [
"add-token",
"settings",
"delete-wallet-confirm",
"delete-address-confirm",
"settings-addtoken",
"transaction",
"approve-site",
@@ -217,6 +218,20 @@ function balanceLinesForAddress(addr, trackedTokens, showZero) {
return html;
}
// Whether an address holds anything at all: ETH or any ERC-20 the wallet
// knows about. Deliberately unrounded — the rendered lines round to four
// decimals, so a dust balance displays as 0.0000 while still being real
// money at a real address. Callers that warn about holdings must ask this,
// not the rendered figure.
function addressHoldsFunds(addr) {
if (!addr) return false;
if (parseFloat(addr.balance || "0") > 0) return true;
for (const t of addr.tokenBalances || []) {
if (parseFloat(t.balance || "0") > 0) return true;
}
return false;
}
// Truncate the middle of a string, replacing removed characters with "…".
// Safety: refuses to truncate more than 10 characters, which is the maximum
// that still prevents address spoofing attacks (see Display Consistency in
@@ -463,6 +478,7 @@ module.exports = {
flashCopyFeedback,
balanceLine,
balanceLinesForAddress,
addressHoldsFunds,
addressColor,
addressDotHtml,
escapeHtml,