Show exact amounts and address titles in transaction detail
All checks were successful
check / check (push) Successful in 5s
All checks were successful
check / check (push) Successful in 5s
- Display full-precision amount (no 4-decimal truncation) in the transaction detail view, with native quantity (wei/base units) below - Both amount and native quantity are click-copyable - Show wallet/address title above from/to when the address is ours - Update README Display Consistency to document the exception
This commit is contained in:
@@ -843,7 +843,11 @@
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="text-xs text-muted mb-1">Amount</div>
|
||||
<div id="tx-detail-value" class="text-xs font-bold"></div>
|
||||
<div id="tx-detail-value" class="text-xs"></div>
|
||||
</div>
|
||||
<div class="mb-4 hidden">
|
||||
<div class="text-xs text-muted mb-1">Native quantity</div>
|
||||
<div id="tx-detail-native" class="text-xs"></div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="text-xs text-muted mb-1">From</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ const {
|
||||
showView,
|
||||
showFlash,
|
||||
addressDotHtml,
|
||||
addressTitle,
|
||||
escapeHtml,
|
||||
} = require("./helpers");
|
||||
const { state } = require("../../shared/state");
|
||||
@@ -67,15 +68,18 @@ function blockieHtml(address) {
|
||||
return `<img src="${src}" width="48" height="48" style="image-rendering:pixelated;border-radius:50%;display:inline-block">`;
|
||||
}
|
||||
|
||||
function txAddressHtml(address, ensName) {
|
||||
function txAddressHtml(address, ensName, title) {
|
||||
const blockie = blockieHtml(address);
|
||||
const dot = addressDotHtml(address);
|
||||
const link = `https://etherscan.io/address/${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">${dot}` +
|
||||
`<div class="flex items-center">${title ? "" : dot}` +
|
||||
copyableHtml(ensName, "") +
|
||||
extLink +
|
||||
`</div>` +
|
||||
@@ -84,7 +88,7 @@ function txAddressHtml(address, ensName) {
|
||||
`</div>`;
|
||||
} else {
|
||||
html +=
|
||||
`<div class="flex items-center">${dot}` +
|
||||
`<div class="flex items-center">${title ? "" : dot}` +
|
||||
copyableHtml(address, "break-all") +
|
||||
extLink +
|
||||
`</div>`;
|
||||
@@ -105,6 +109,9 @@ function show(tx) {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
value: tx.value,
|
||||
exactValue: tx.exactValue || tx.value,
|
||||
rawAmount: tx.rawAmount || "",
|
||||
rawUnit: tx.rawUnit || "",
|
||||
symbol: tx.symbol,
|
||||
timestamp: tx.timestamp,
|
||||
isError: tx.isError,
|
||||
@@ -120,11 +127,33 @@ function render() {
|
||||
const tx = state.viewData.tx;
|
||||
if (!tx) return;
|
||||
$("tx-detail-hash").innerHTML = txHashHtml(tx.hash);
|
||||
$("tx-detail-from").innerHTML = txAddressHtml(tx.from, tx.fromEns);
|
||||
$("tx-detail-to").innerHTML = txAddressHtml(tx.to, tx.toEns);
|
||||
$("tx-detail-value").textContent = tx.value
|
||||
? tx.value + " " + tx.symbol
|
||||
|
||||
const fromTitle = addressTitle(tx.from, state.wallets);
|
||||
const toTitle = addressTitle(tx.to, state.wallets);
|
||||
$("tx-detail-from").innerHTML = txAddressHtml(
|
||||
tx.from,
|
||||
tx.fromEns,
|
||||
fromTitle,
|
||||
);
|
||||
$("tx-detail-to").innerHTML = txAddressHtml(tx.to, tx.toEns, toTitle);
|
||||
|
||||
// Exact amount (full precision, copyable)
|
||||
const exactStr = tx.exactValue
|
||||
? tx.exactValue + " " + tx.symbol
|
||||
: tx.directionLabel + " " + tx.symbol;
|
||||
$("tx-detail-value").innerHTML = copyableHtml(exactStr, "font-bold");
|
||||
|
||||
// Native quantity (raw integer, copyable)
|
||||
const nativeEl = $("tx-detail-native");
|
||||
if (tx.rawAmount && tx.rawUnit) {
|
||||
const nativeStr = tx.rawAmount + " " + tx.rawUnit;
|
||||
nativeEl.innerHTML = copyableHtml(nativeStr, "");
|
||||
nativeEl.parentElement.classList.remove("hidden");
|
||||
} else {
|
||||
nativeEl.innerHTML = "";
|
||||
nativeEl.parentElement.classList.add("hidden");
|
||||
}
|
||||
|
||||
$("tx-detail-time").textContent =
|
||||
isoDate(tx.timestamp) + " (" + timeAgo(tx.timestamp) + ")";
|
||||
$("tx-detail-status").textContent = tx.isError ? "Failed" : "Success";
|
||||
|
||||
@@ -27,6 +27,9 @@ function parseTx(tx, addrLower) {
|
||||
// For contract calls, produce a meaningful label instead of "0.0000 ETH"
|
||||
let symbol = "ETH";
|
||||
let value = formatTxValue(formatEther(rawWei));
|
||||
let exactValue = formatEther(rawWei);
|
||||
let rawAmount = rawWei;
|
||||
let rawUnit = "wei";
|
||||
let direction = from.toLowerCase() === addrLower ? "sent" : "received";
|
||||
let directionLabel = direction === "sent" ? "Sent" : "Received";
|
||||
if (toIsContract && method && method !== "transfer") {
|
||||
@@ -38,6 +41,9 @@ function parseTx(tx, addrLower) {
|
||||
direction = "contract";
|
||||
directionLabel = label;
|
||||
value = "";
|
||||
exactValue = "";
|
||||
rawAmount = "";
|
||||
rawUnit = "";
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -47,6 +53,9 @@ function parseTx(tx, addrLower) {
|
||||
from: from,
|
||||
to: to,
|
||||
value: value,
|
||||
exactValue: exactValue,
|
||||
rawAmount: rawAmount,
|
||||
rawUnit: rawUnit,
|
||||
valueGwei: Math.floor(Number(BigInt(rawWei) / BigInt(1000000000))),
|
||||
symbol: symbol,
|
||||
direction: direction,
|
||||
@@ -63,17 +72,21 @@ function parseTokenTransfer(tt, addrLower) {
|
||||
const from = tt.from?.hash || "";
|
||||
const to = tt.to?.hash || "";
|
||||
const decimals = parseInt(tt.total?.decimals || "18", 10);
|
||||
const rawValue = tt.total?.value || "0";
|
||||
const rawVal = tt.total?.value || "0";
|
||||
const direction = from.toLowerCase() === addrLower ? "sent" : "received";
|
||||
const sym = tt.token?.symbol || "?";
|
||||
return {
|
||||
hash: tt.transaction_hash,
|
||||
blockNumber: tt.block_number,
|
||||
timestamp: Math.floor(new Date(tt.timestamp).getTime() / 1000),
|
||||
from: from,
|
||||
to: to,
|
||||
value: formatTxValue(formatUnits(rawValue, decimals)),
|
||||
value: formatTxValue(formatUnits(rawVal, decimals)),
|
||||
exactValue: formatUnits(rawVal, decimals),
|
||||
rawAmount: rawVal,
|
||||
rawUnit: sym + " base units (10^-" + decimals + ")",
|
||||
valueGwei: null,
|
||||
symbol: tt.token?.symbol || "?",
|
||||
symbol: sym,
|
||||
direction: direction,
|
||||
directionLabel: direction === "sent" ? "Sent" : "Received",
|
||||
isError: false,
|
||||
|
||||
Reference in New Issue
Block a user