diff --git a/src/popup/views/transactionDetail.js b/src/popup/views/transactionDetail.js
index a3c2056..0ec1dc3 100644
--- a/src/popup/views/transactionDetail.js
+++ b/src/popup/views/transactionDetail.js
@@ -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 `
`;
}
-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 = `
${dot}` +
+ `
${title ? "" : dot}` +
copyableHtml(address, "break-all") +
extLink +
`
`;
@@ -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";
diff --git a/src/shared/transactions.js b/src/shared/transactions.js
index b9f5805..f926784 100644
--- a/src/shared/transactions.js
+++ b/src/shared/transactions.js
@@ -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,