fix: unify address display with shared renderAddressHtml utility
All checks were successful
check / check (push) Successful in 26s

All address rendering now uses a single renderAddressHtml() function in
helpers.js that produces consistent output everywhere:
- Color dot (deterministic from address)
- Full address with dashed-underline click-to-copy affordance
- Etherscan external link icon

Refactored all callsites across 9 view files:
- approval.js: approvalAddressHtml now delegates to renderAddressHtml,
  added attachCopyHandlers for click-to-copy on approve-tx/sign/site views
- confirmTx.js: confirmAddressHtml uses renderAddressHtml, token contract
  address uses renderAddressHtml with attachCopyHandlers
- txStatus.js: toAddressHtml delegates to renderAddressHtml
- transactionDetail.js: txAddressHtml delegates to renderAddressHtml,
  decoded calldata addresses use renderAddressHtml
- home.js: active address display uses renderAddressHtml
- send.js: from-address display uses renderAddressHtml
- receive.js: address block uses formatAddressHtml (which delegates to
  renderAddressHtml), removed separate etherscan link element
- addressDetail.js: address line uses renderAddressHtml, export-privkey
  address uses renderAddressHtml
- addressToken.js: address line and contract info use renderAddressHtml

Also consolidated:
- EXT_ICON SVG constant moved to helpers.js (removed 6 duplicates)
- copyableHtml() moved to helpers.js (removed duplicate in transactionDetail)
- etherscanLinkHtml() moved to helpers.js (removed duplicates)
- attachCopyHandlers() moved to helpers.js (removed duplicate in txStatus)
- Removed unused local functions (etherscanTokenLink, etherscanAddressLink)
- Cleaned up unused imports across all files

closes #97
This commit is contained in:
user
2026-03-01 05:59:17 -08:00
parent a138a36710
commit 5395fc6ede
10 changed files with 179 additions and 395 deletions

View File

@@ -17,8 +17,9 @@ const {
showFlash,
flashCopyFeedback,
addressTitle,
addressDotHtml,
escapeHtml,
renderAddressHtml,
attachCopyHandlers,
} = require("./helpers");
const { state, currentNetwork } = require("../../shared/state");
const { getSignerForAddress } = require("../../shared/wallet");
@@ -34,13 +35,6 @@ const { log } = require("../../shared/log");
const makeBlockie = require("ethereum-blockies-base64");
const txStatus = require("./txStatus");
const EXT_ICON =
`<span style="display:inline-block;width:10px;height:10px;margin-left:4px;vertical-align:middle">` +
`<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5">` +
`<path d="M4.5 1.5H2a.5.5 0 00-.5.5v8a.5.5 0 00.5.5h8a.5.5 0 00.5-.5V7.5"/>` +
`<path d="M7 1.5h3.5V5M7 5.5L10.5 1.5"/>` +
`</svg></span>`;
let pendingTx = null;
function restore() {
@@ -50,14 +44,6 @@ function restore() {
}
}
function etherscanTokenLink(address) {
return `${currentNetwork().explorerUrl}/token/${address}`;
}
function etherscanAddressLink(address) {
return `${currentNetwork().explorerUrl}/address/${address}`;
}
function blockieHtml(address) {
const src = makeBlockie(address);
return `<img src="${src}" width="48" height="48" style="image-rendering:pixelated;border-radius:50%;display:inline-block">`;
@@ -65,22 +51,10 @@ function blockieHtml(address) {
function confirmAddressHtml(address, ensName, title) {
const blockie = blockieHtml(address);
const dot = addressDotHtml(address);
const link = etherscanAddressLink(address);
const extLink = `<a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
let html = `<div class="mb-1">${blockie}</div>`;
if (title) {
html += `<div class="flex items-center font-bold">${dot}${escapeHtml(title)}</div>`;
}
if (ensName) {
html += `<div class="flex items-center font-bold">${title ? "" : dot}${escapeHtml(ensName)}</div>`;
}
html +=
`<div class="flex items-center">${title || ensName ? "" : dot}` +
`<span class="break-all">${escapeHtml(address)}</span>` +
extLink +
`</div>`;
return html;
return (
`<div class="mb-1">${blockie}</div>` +
renderAddressHtml(address, { title, ensName })
);
}
function valueWithUsd(text, usdAmount) {
@@ -107,23 +81,12 @@ function show(txInfo) {
// Token contract section (ERC-20 only)
const tokenSection = $("confirm-token-section");
if (isErc20) {
const dot = addressDotHtml(txInfo.token);
const link = etherscanTokenLink(txInfo.token);
$("confirm-token-contract").innerHTML =
`<div class="flex items-center">${dot}` +
`<span class="break-all underline decoration-dashed cursor-pointer" data-copy="${escapeHtml(txInfo.token)}">${escapeHtml(txInfo.token)}</span>` +
`<a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>` +
`</div>`;
$("confirm-token-contract").innerHTML = renderAddressHtml(
txInfo.token,
{},
);
tokenSection.classList.remove("hidden");
// Attach click-to-copy on the contract address
const copyEl = tokenSection.querySelector("[data-copy]");
if (copyEl) {
copyEl.onclick = () => {
navigator.clipboard.writeText(copyEl.dataset.copy);
showFlash("Copied!");
flashCopyFeedback(copyEl);
};
}
attachCopyHandlers(tokenSection);
} else {
tokenSection.classList.add("hidden");
}
@@ -243,6 +206,7 @@ function show(txInfo) {
$("confirm-fee-amount").textContent = "Estimating...";
state.viewData = { pendingTx: txInfo };
showView("confirm-tx");
attachCopyHandlers("view-confirm-tx");
// Reset async warnings to hidden (space always reserved, no layout shift)
$("confirm-recipient-warning").style.visibility = "hidden";