Show blockies on confirm page, put USD values inline in parentheses
All checks were successful
check / check (push) Successful in 17s

From and To addresses now render with 48px blockie identicons,
color dots, and etherscan links — matching the transaction detail
view pattern. USD estimates for amount, balance, and network fee
are shown in parentheses after the value on the same line, not on
a separate line below.
This commit is contained in:
2026-02-27 11:58:04 +07:00
parent b85eac1e75
commit a43e8f20ea
2 changed files with 61 additions and 53 deletions

View File

@@ -472,25 +472,16 @@
<div class="mb-3">
<div class="text-xs text-muted mb-1">Amount</div>
<div id="confirm-amount" class="font-bold"></div>
<div
id="confirm-amount-usd"
class="text-xs text-muted"
></div>
</div>
<div class="mb-3">
<div class="text-xs text-muted mb-1">Your balance</div>
<div id="confirm-balance" class="text-xs"></div>
<div
id="confirm-balance-usd"
class="text-xs text-muted"
></div>
</div>
<div id="confirm-fee" class="mb-3 hidden">
<div class="text-xs text-muted mb-1">
Estimated network fee
</div>
<div id="confirm-fee-amount" class="text-xs"></div>
<div id="confirm-fee-usd" class="text-xs text-muted"></div>
</div>
<div id="confirm-warnings" class="mb-2 hidden"></div>
<div

View File

@@ -15,7 +15,7 @@ const {
hideError,
showView,
addressTitle,
formatAddressHtml,
addressDotHtml,
escapeHtml,
} = require("./helpers");
const { state } = require("../../shared/state");
@@ -26,6 +26,7 @@ const { getProvider } = require("../../shared/balances");
const { isScamAddress } = require("../../shared/scamlist");
const { ERC20_ABI } = require("../../shared/constants");
const { log } = require("../../shared/log");
const makeBlockie = require("ethereum-blockies-base64");
const EXT_ICON =
`<span style="display:inline-block;width:10px;height:10px;margin-left:4px;vertical-align:middle">` +
@@ -41,6 +42,42 @@ function etherscanTokenLink(address) {
return `https://etherscan.io/token/${address}`;
}
function etherscanAddressLink(address) {
return `https://etherscan.io/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">`;
}
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;
}
function valueWithUsd(text, usdAmount) {
if (usdAmount !== null && usdAmount !== undefined && !isNaN(usdAmount)) {
return text + " (" + formatUsd(usdAmount) + ")";
}
return text;
}
function show(txInfo) {
pendingTx = txInfo;
@@ -67,59 +104,46 @@ function show(txInfo) {
tokenSection.classList.add("hidden");
}
// From
// From (with blockie)
const fromTitle = addressTitle(txInfo.from, state.wallets);
$("confirm-from").innerHTML = formatAddressHtml(
$("confirm-from").innerHTML = confirmAddressHtml(
txInfo.from,
null,
null,
fromTitle,
);
// To
// To (with blockie)
const toTitle = addressTitle(txInfo.to, state.wallets);
$("confirm-to").innerHTML = formatAddressHtml(
$("confirm-to").innerHTML = confirmAddressHtml(
txInfo.to,
txInfo.ensName,
null,
toTitle,
);
$("confirm-to-ens").classList.add("hidden");
// Amount
$("confirm-amount").textContent = txInfo.amount + " " + symbol;
// Amount (with inline USD)
const ethPrice = getPrice("ETH");
const tokenPrice = getPrice(symbol);
if (isErc20 && tokenPrice) {
const usd = parseFloat(txInfo.amount) * tokenPrice;
$("confirm-amount-usd").textContent = formatUsd(usd);
} else if (!isErc20 && ethPrice) {
const usd = parseFloat(txInfo.amount) * ethPrice;
$("confirm-amount-usd").textContent = formatUsd(usd);
} else {
$("confirm-amount-usd").textContent = "";
}
const amountNum = parseFloat(txInfo.amount);
const price = isErc20 ? tokenPrice : ethPrice;
const amountUsd = price ? amountNum * price : null;
$("confirm-amount").textContent = valueWithUsd(
txInfo.amount + " " + symbol,
amountUsd,
);
// Balance
// Balance (with inline USD)
if (isErc20) {
const bal = txInfo.tokenBalance || "0";
$("confirm-balance").textContent = bal + " " + symbol;
if (tokenPrice) {
$("confirm-balance-usd").textContent = formatUsd(
parseFloat(bal) * tokenPrice,
);
} else {
$("confirm-balance-usd").textContent = "";
}
const balUsd = tokenPrice ? parseFloat(bal) * tokenPrice : null;
$("confirm-balance").textContent = valueWithUsd(
bal + " " + symbol,
balUsd,
);
} else {
$("confirm-balance").textContent = (txInfo.balance || "0") + " ETH";
if (ethPrice) {
$("confirm-balance-usd").textContent = formatUsd(
parseFloat(txInfo.balance || "0") * ethPrice,
);
} else {
$("confirm-balance-usd").textContent = "";
}
const bal = txInfo.balance || "0";
const balUsd = ethPrice ? parseFloat(bal) * ethPrice : null;
$("confirm-balance").textContent = valueWithUsd(bal + " ETH", balUsd);
}
// Check for warnings
@@ -193,7 +217,6 @@ function show(txInfo) {
// Gas estimate — show placeholder then fetch async
$("confirm-fee").classList.remove("hidden");
$("confirm-fee-amount").textContent = "Estimating...";
$("confirm-fee-usd").textContent = "";
$("confirm-status").classList.add("hidden");
showView("confirm-tx");
@@ -231,18 +254,12 @@ async function estimateGas(txInfo) {
? parts[1].slice(0, 6).replace(/0+$/, "") || "0"
: "0";
const feeStr = parts[0] + "." + dec + " ETH";
$("confirm-fee-amount").textContent = feeStr;
const ethPrice = getPrice("ETH");
if (ethPrice) {
$("confirm-fee-usd").textContent = formatUsd(
parseFloat(gasCostEth) * ethPrice,
);
}
const feeUsd = ethPrice ? parseFloat(gasCostEth) * ethPrice : null;
$("confirm-fee-amount").textContent = valueWithUsd(feeStr, feeUsd);
} catch (e) {
log.errorf("gas estimation failed:", e.message);
$("confirm-fee-amount").textContent = "Unable to estimate";
$("confirm-fee-usd").textContent = "";
}
}