// Transaction detail view — shows full details for a single transaction. // Shared by addressDetail and addressToken via ctx.showTransactionDetail(). const { $, showView, showFlash, addressDotHtml, addressTitle, escapeHtml, isoDate, timeAgo, } = require("./helpers"); const { state } = require("../../shared/state"); const makeBlockie = require("ethereum-blockies-base64"); const EXT_ICON = `` + `` + `` + `` + ``; let ctx; function copyableHtml(text, extraClass) { const cls = "underline decoration-dashed cursor-pointer" + (extraClass ? " " + extraClass : ""); return `${escapeHtml(text)}`; } function blockieHtml(address) { const src = makeBlockie(address); return ``; } function txAddressHtml(address, ensName, title) { const blockie = blockieHtml(address); const dot = addressDotHtml(address); const link = `https://etherscan.io/address/${address}`; const extLink = `${EXT_ICON}`; let html = `
${blockie}
`; if (title) { html += `
${dot}${escapeHtml(title)}
`; } if (ensName) { html += `
${title ? "" : dot}` + copyableHtml(ensName, "") + extLink + `
` + `
` + copyableHtml(address, "break-all") + `
`; } else { html += `
${title ? "" : dot}` + copyableHtml(address, "break-all") + extLink + `
`; } return html; } function txHashHtml(hash) { const link = `https://etherscan.io/tx/${hash}`; const extLink = `${EXT_ICON}`; return copyableHtml(hash, "break-all") + extLink; } function show(tx) { state.viewData = { tx: { hash: tx.hash, 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, fromEns: tx.fromEns || null, toEns: tx.toEns || null, directionLabel: tx.directionLabel || null, }, }; render(); } function render() { const tx = state.viewData.tx; if (!tx) return; $("tx-detail-hash").innerHTML = txHashHtml(tx.hash); 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"; showView("transaction"); document .getElementById("view-transaction") .querySelectorAll("[data-copy]") .forEach((el) => { el.onclick = () => { navigator.clipboard.writeText(el.dataset.copy); showFlash("Copied!"); }; }); } function init(_ctx) { ctx = _ctx; $("btn-tx-back").addEventListener("click", () => { if (state.selectedToken) { ctx.showAddressToken(); } else { ctx.showAddressDetail(); } }); } module.exports = { init, show, render };