From 47e690f466207f2d7566bd84e664dd9da9538fde Mon Sep 17 00:00:00 2001 From: sneak Date: Thu, 26 Feb 2026 15:37:39 +0700 Subject: [PATCH] Show tracked tokens with zero balance on main and address pages Add showZeroBalanceTokens setting (default: on). When enabled, balanceLinesForAddress merges state.trackedTokens with the address's tokenBalances, showing 0.0000 lines for tracked tokens that have no balance on that address. This gives users visibility into all tokens they're watching across all addresses. --- src/popup/index.html | 13 +++++++++++++ src/popup/views/addressDetail.js | 6 +++++- src/popup/views/helpers.js | 12 ++++++++++-- src/popup/views/home.js | 6 +++++- src/popup/views/settings.js | 6 ++++++ src/shared/state.js | 6 ++++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index dd83eb2..ef0f5d8 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -502,6 +502,19 @@ +
+

Display

+ +
+

Ethereum RPC

diff --git a/src/popup/views/addressDetail.js b/src/popup/views/addressDetail.js index 09d272b..83589ff 100644 --- a/src/popup/views/addressDetail.js +++ b/src/popup/views/addressDetail.js @@ -38,7 +38,11 @@ function show() { } else { ensEl.classList.add("hidden"); } - $("address-balances").innerHTML = balanceLinesForAddress(addr); + $("address-balances").innerHTML = balanceLinesForAddress( + addr, + state.trackedTokens, + state.showZeroBalanceTokens, + ); renderSendTokenSelect(addr); $("tx-list").innerHTML = '

Loading...
'; diff --git a/src/popup/views/helpers.js b/src/popup/views/helpers.js index dda007a..47011ac 100644 --- a/src/popup/views/helpers.js +++ b/src/popup/views/helpers.js @@ -85,16 +85,24 @@ function balanceLine(symbol, amount, price) { ); } -function balanceLinesForAddress(addr) { +function balanceLinesForAddress(addr, trackedTokens, showZero) { let html = balanceLine( "ETH", parseFloat(addr.balance || "0"), getPrice("ETH"), ); + const seen = new Set(); for (const t of addr.tokenBalances || []) { const bal = parseFloat(t.balance || "0"); - if (bal === 0) continue; + if (bal === 0 && !showZero) continue; html += balanceLine(t.symbol, bal, getPrice(t.symbol)); + seen.add(t.address.toLowerCase()); + } + if (showZero && trackedTokens) { + for (const t of trackedTokens) { + if (seen.has(t.address.toLowerCase())) continue; + html += balanceLine(t.symbol, 0, getPrice(t.symbol)); + } } return html; } diff --git a/src/popup/views/home.js b/src/popup/views/home.js index cccc48d..abd052a 100644 --- a/src/popup/views/home.js +++ b/src/popup/views/home.js @@ -57,7 +57,11 @@ function render(ctx) { html += `${addr.ensName ? "" : dot}${truncateMiddle(addr.address, 40)}`; html += `${addrUsd}`; html += `
`; - html += balanceLinesForAddress(addr); + html += balanceLinesForAddress( + addr, + state.trackedTokens, + state.showZeroBalanceTokens, + ); html += ``; }); diff --git a/src/popup/views/settings.js b/src/popup/views/settings.js index ae44dd5..f892967 100644 --- a/src/popup/views/settings.js +++ b/src/popup/views/settings.js @@ -113,6 +113,12 @@ function init(ctx) { showFlash("Saved."); }); + $("settings-show-zero-balances").checked = state.showZeroBalanceTokens; + $("settings-show-zero-balances").addEventListener("change", async () => { + state.showZeroBalanceTokens = $("settings-show-zero-balances").checked; + await saveState(); + }); + $("settings-hide-low-holders").checked = state.hideLowHolderTokens; $("settings-hide-low-holders").addEventListener("change", async () => { state.hideLowHolderTokens = $("settings-hide-low-holders").checked; diff --git a/src/shared/state.js b/src/shared/state.js index 5bac05c..955a181 100644 --- a/src/shared/state.js +++ b/src/shared/state.js @@ -18,6 +18,7 @@ const DEFAULT_STATE = { allowedSites: {}, deniedSites: {}, rememberSiteChoice: true, + showZeroBalanceTokens: true, hideLowHolderTokens: true, hideFraudContracts: true, hideDustTransactions: true, @@ -44,6 +45,7 @@ async function saveState() { allowedSites: state.allowedSites, deniedSites: state.deniedSites, rememberSiteChoice: state.rememberSiteChoice, + showZeroBalanceTokens: state.showZeroBalanceTokens, hideLowHolderTokens: state.hideLowHolderTokens, hideFraudContracts: state.hideFraudContracts, hideDustTransactions: state.hideDustTransactions, @@ -78,6 +80,10 @@ async function loadState() { saved.rememberSiteChoice !== undefined ? saved.rememberSiteChoice : true; + state.showZeroBalanceTokens = + saved.showZeroBalanceTokens !== undefined + ? saved.showZeroBalanceTokens + : true; state.hideLowHolderTokens = saved.hideLowHolderTokens !== undefined ? saved.hideLowHolderTokens