From f9f3e7b85ab158c10205171032692ed5f921f35f Mon Sep 17 00:00:00 2001 From: user Date: Sat, 28 Feb 2026 13:44:14 -0800 Subject: [PATCH 1/5] feat: show red warning when sending to address with zero tx history On the confirm-tx view, asynchronously check the recipient address transaction count via getTransactionCount(). If zero, display a prominent red warning advising the user to double-check the address. Closes #82 --- src/popup/views/confirmTx.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/popup/views/confirmTx.js b/src/popup/views/confirmTx.js index 522e9e5..82c14dd 100644 --- a/src/popup/views/confirmTx.js +++ b/src/popup/views/confirmTx.js @@ -244,6 +244,7 @@ function show(txInfo) { showView("confirm-tx"); estimateGas(txInfo); + checkRecipientHistory(txInfo); } async function estimateGas(txInfo) { @@ -286,6 +287,28 @@ async function estimateGas(txInfo) { } } +async function checkRecipientHistory(txInfo) { + try { + const provider = getProvider(state.rpcUrl); + const txCount = await provider.getTransactionCount(txInfo.to); + if (txCount === 0) { + const warningsEl = $("confirm-warnings"); + const warning = + `
` + + `WARNING: The recipient address has ZERO transaction history. ` + + `This may indicate a fresh or unused address. Double-check the address before sending.
`; + if (warningsEl.classList.contains("hidden")) { + warningsEl.innerHTML = warning; + warningsEl.classList.remove("hidden"); + } else { + warningsEl.innerHTML += warning; + } + } + } catch (e) { + log.errorf("recipient history check failed:", e.message); + } +} + function init(ctx) { $("btn-confirm-send").addEventListener("click", async () => { const password = $("confirm-tx-password").value; From a3c2b8227aebdbf136a1ef3285f1577d32f65276 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 28 Feb 2026 14:18:28 -0800 Subject: [PATCH 2/5] fix: zero-tx warning layout shift and contract address false positive - Reserve space for the warning upfront using visibility:hidden instead of display:none, preventing layout shift per README policy - Move warning HTML to index.html as a static element rather than injecting dynamically - Skip warning for contract addresses (check getCode first) since getTransactionCount only returns outgoing tx nonce - Collapse reserved space when warning is not needed (address has history, is a contract, or on RPC error) --- src/popup/index.html | 13 +++++++++++++ src/popup/views/confirmTx.js | 34 +++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index 5c9d444..c77bd37 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -577,6 +577,19 @@
+ `; - if (warningsEl.classList.contains("hidden")) { - warningsEl.innerHTML = warning; - warningsEl.classList.remove("hidden"); - } else { - warningsEl.innerHTML += warning; - } + el.style.visibility = "visible"; + } else { + // Address has history — collapse the reserved space + el.style.display = "none"; } } catch (e) { log.errorf("recipient history check failed:", e.message); + // On error, collapse the reserved space rather than showing a + // false warning or leaving an empty gap + el.style.display = "none"; } } From 8c071ae508df39db131b7a09a8b234dbe717a900 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 28 Feb 2026 15:26:49 -0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20never=20collapse=20warning=20contain?= =?UTF-8?q?er=20=E2=80=94=20always=20reserve=20space=20to=20prevent=20layo?= =?UTF-8?q?ut=20shift?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace display:none with persistent visibility:hidden so the warning area occupies the same vertical space regardless of API result. This eliminates the layout shift that occurred when the container was collapsed after the recipient history check returned. --- src/popup/views/confirmTx.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/popup/views/confirmTx.js b/src/popup/views/confirmTx.js index e2977ba..f9b4f34 100644 --- a/src/popup/views/confirmTx.js +++ b/src/popup/views/confirmTx.js @@ -246,7 +246,6 @@ function show(txInfo) { // Reset recipient warning: reserve space (visibility:hidden) while // the async check runs, preventing layout shift per README policy. const recipientWarning = $("confirm-recipient-warning"); - recipientWarning.style.display = ""; recipientWarning.style.visibility = "hidden"; estimateGas(txInfo); @@ -302,22 +301,18 @@ async function checkRecipientHistory(txInfo) { // the nonce, i.e. sent-tx count only). const code = await provider.getCode(txInfo.to); if (code && code !== "0x") { - // Contract address — hide the reserved space entirely - el.style.display = "none"; + // Contract address — no warning needed, keep space reserved + // but invisible to prevent layout shift return; } const txCount = await provider.getTransactionCount(txInfo.to); if (txCount === 0) { el.style.visibility = "visible"; - } else { - // Address has history — collapse the reserved space - el.style.display = "none"; } + // If txCount > 0, leave visibility:hidden — space stays reserved } catch (e) { log.errorf("recipient history check failed:", e.message); - // On error, collapse the reserved space rather than showing a - // false warning or leaving an empty gap - el.style.display = "none"; + // On error, leave visibility:hidden — no layout shift, no false warning } } From 576fe3ab15c3faa921eb68e42ebf5d007910a0a2 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 28 Feb 2026 15:37:27 -0800 Subject: [PATCH 4/5] fix: replace visibility:hidden with smooth collapse for zero-tx warning Instead of permanently reserving space with visibility:hidden, the warning container now uses max-height + opacity transitions. Space is reserved during the async check, then smoothly collapses to 0 if the warning isn't needed. This reclaims ~40px of popup viewport in the common case. --- src/popup/index.html | 9 ++++++++- src/popup/views/confirmTx.js | 24 ++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/popup/index.html b/src/popup/index.html index c77bd37..7083141 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -580,7 +580,14 @@