Compare commits
2 Commits
feat/issue
...
a7315efca9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7315efca9 | ||
| 3bf60ff162 |
32
README.md
32
README.md
@@ -435,25 +435,29 @@ transitions.
|
|||||||
#### TransactionDetail
|
#### TransactionDetail
|
||||||
|
|
||||||
- **When**: User tapped a transaction row from AddressDetail or AddressToken.
|
- **When**: User tapped a transaction row from AddressDetail or AddressToken.
|
||||||
- **Elements**:
|
- **Elements** (grouped into logical blocks using light well containers; field
|
||||||
|
labels are self-explanatory so groups have no headings):
|
||||||
- "Transaction" heading, "Back" button
|
- "Transaction" heading, "Back" button
|
||||||
|
- Transaction hash: full hash (tap to copy) + etherscan link
|
||||||
- Type: transaction classification — one of: Native ETH Transfer, ERC-20
|
- Type: transaction classification — one of: Native ETH Transfer, ERC-20
|
||||||
Token Transfer, Swap, Token Approval, Contract Call, Contract Creation
|
Token Transfer, Swap, Token Approval, Contract Call, Contract Creation
|
||||||
|
- Status: "Success" or "Failed"
|
||||||
|
- From: blockie + color dot + full address (tap to copy) + etherscan link;
|
||||||
|
ENS name if available
|
||||||
|
- To: blockie + color dot + full address (tap to copy) + etherscan link; ENS
|
||||||
|
name if available
|
||||||
|
- Time: ISO datetime + relative age in parentheses
|
||||||
|
- Block: block number (tap to copy) + etherscan block link
|
||||||
|
- Amount: value + symbol (bold)
|
||||||
|
- Native quantity: raw integer + unit (shown when available)
|
||||||
- Token contract: shown for ERC-20 transfers — color dot + full contract
|
- Token contract: shown for ERC-20 transfers — color dot + full contract
|
||||||
address (tap to copy) + etherscan token link
|
address (tap to copy) + etherscan token link
|
||||||
- Status: "Success" or "Failed"
|
- Decoded details (shown for contract calls): action name, decoded
|
||||||
- Time: ISO datetime + relative age in parentheses
|
parameters, token details, swap steps
|
||||||
- Amount: value + symbol (bold)
|
- Network details (shown when on-chain data is available): nonce, gas price,
|
||||||
- From: blockie + color dot + full address (tap to copy) + etherscan link
|
gas used, transaction fee (all tap to copy)
|
||||||
- ENS name if available
|
- Raw data (shown when calldata is present): full calldata in monospace
|
||||||
- To: blockie + color dot + full address (tap to copy) + etherscan link
|
dashed border
|
||||||
- ENS name if available
|
|
||||||
- Transaction hash: full hash (tap to copy) + etherscan link
|
|
||||||
- Block: block number (tap to copy) + etherscan block link
|
|
||||||
- Nonce: transaction nonce (tap to copy)
|
|
||||||
- Transaction fee: ETH amount (tap to copy)
|
|
||||||
- Gas price: value in Gwei (tap to copy)
|
|
||||||
- Gas used: integer (tap to copy)
|
|
||||||
- **Transitions**:
|
- **Transitions**:
|
||||||
- "Back" → **AddressToken** (if `selectedToken` set) or **AddressDetail**
|
- "Back" → **AddressToken** (if `selectedToken` set) or **AddressDetail**
|
||||||
|
|
||||||
|
|||||||
@@ -1064,87 +1064,135 @@
|
|||||||
<h2 id="tx-detail-heading" class="font-bold mb-2">
|
<h2 id="tx-detail-heading" class="font-bold mb-2">
|
||||||
Transaction
|
Transaction
|
||||||
</h2>
|
</h2>
|
||||||
<div id="tx-detail-type-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Type</div>
|
<!-- ── Identity ── -->
|
||||||
<div id="tx-detail-type" class="text-xs font-bold"></div>
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
</div>
|
<div class="mb-2">
|
||||||
<div class="mb-4">
|
<div class="text-xs text-muted mb-1">
|
||||||
<div class="text-xs text-muted mb-1">Status</div>
|
Transaction hash
|
||||||
<div id="tx-detail-status" class="text-xs"></div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="text-xs text-muted mb-1">Time</div>
|
|
||||||
<div id="tx-detail-time" class="text-xs"></div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="text-xs text-muted mb-1">Amount</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>
|
|
||||||
<div id="tx-detail-from" class="text-xs break-all"></div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="text-xs text-muted mb-1">To</div>
|
|
||||||
<div id="tx-detail-to" class="text-xs break-all"></div>
|
|
||||||
</div>
|
|
||||||
<div id="tx-detail-token-contract-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Token contract</div>
|
|
||||||
<div
|
|
||||||
id="tx-detail-token-contract"
|
|
||||||
class="text-xs break-all"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<div id="tx-detail-calldata-section" class="mb-4 hidden">
|
|
||||||
<div
|
|
||||||
id="tx-detail-calldata-well"
|
|
||||||
class="mb-3 border border-border border-dashed p-2"
|
|
||||||
>
|
|
||||||
<div class="text-xs text-muted mb-1">Action</div>
|
|
||||||
<div
|
<div
|
||||||
id="tx-detail-calldata-action"
|
id="tx-detail-hash"
|
||||||
class="text-xs font-bold mb-2"
|
class="text-xs break-all"
|
||||||
></div>
|
></div>
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-type-section" class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">Type</div>
|
||||||
<div
|
<div
|
||||||
id="tx-detail-calldata-details"
|
id="tx-detail-type"
|
||||||
class="text-xs"
|
class="text-xs font-bold"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">Status</div>
|
||||||
|
<div id="tx-detail-status" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">From</div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-from"
|
||||||
|
class="text-xs break-all"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">To</div>
|
||||||
|
<div id="tx-detail-to" class="text-xs break-all"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ── Timing ── -->
|
||||||
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
|
<div class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">Time</div>
|
||||||
|
<div id="tx-detail-time" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-block-section" class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">Block</div>
|
||||||
|
<div id="tx-detail-block" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ── Value ── -->
|
||||||
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
|
<div class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">Amount</div>
|
||||||
|
<div id="tx-detail-value" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">
|
||||||
|
Native quantity
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-native" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-token-contract-section"
|
||||||
|
class="mb-2 hidden"
|
||||||
|
>
|
||||||
|
<div class="text-xs text-muted mb-1">
|
||||||
|
Token contract
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-token-contract"
|
||||||
|
class="text-xs break-all"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
|
||||||
<div class="text-xs text-muted mb-1">Transaction hash</div>
|
<!-- ── Decoded details ── -->
|
||||||
<div id="tx-detail-hash" class="text-xs break-all"></div>
|
<div id="tx-detail-calldata-section" class="hidden">
|
||||||
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
|
<div id="tx-detail-calldata-well" class="mb-2">
|
||||||
|
<div class="text-xs text-muted mb-1">Action</div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-calldata-action"
|
||||||
|
class="text-xs font-bold mb-2"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-calldata-details"
|
||||||
|
class="text-xs"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tx-detail-block-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Block</div>
|
<!-- ── Network details ── -->
|
||||||
<div id="tx-detail-block" class="text-xs"></div>
|
<div id="tx-detail-network-section" class="hidden">
|
||||||
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
|
<div id="tx-detail-nonce-section" class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">Nonce</div>
|
||||||
|
<div id="tx-detail-nonce" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="tx-detail-gasprice-section"
|
||||||
|
class="mb-2 hidden"
|
||||||
|
>
|
||||||
|
<div class="text-xs text-muted mb-1">Gas price</div>
|
||||||
|
<div id="tx-detail-gasprice" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-gasused-section" class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">Gas used</div>
|
||||||
|
<div id="tx-detail-gasused" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-fee-section" class="mb-2 hidden">
|
||||||
|
<div class="text-xs text-muted mb-1">
|
||||||
|
Transaction fee
|
||||||
|
</div>
|
||||||
|
<div id="tx-detail-fee" class="text-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tx-detail-nonce-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Nonce</div>
|
<!-- ── Raw data ── -->
|
||||||
<div id="tx-detail-nonce" class="text-xs"></div>
|
<div id="tx-detail-rawdata-section" class="hidden">
|
||||||
</div>
|
<div class="bg-well p-3 mx-1 mb-3">
|
||||||
<div id="tx-detail-fee-section" class="mb-4 hidden">
|
<div class="mb-2">
|
||||||
<div class="text-xs text-muted mb-1">Transaction fee</div>
|
<div class="text-xs text-muted mb-1">Raw data</div>
|
||||||
<div id="tx-detail-fee" class="text-xs"></div>
|
<div
|
||||||
</div>
|
id="tx-detail-rawdata"
|
||||||
<div id="tx-detail-gasprice-section" class="mb-4 hidden">
|
class="text-xs break-all font-mono border border-border border-dashed p-2"
|
||||||
<div class="text-xs text-muted mb-1">Gas price</div>
|
></div>
|
||||||
<div id="tx-detail-gasprice" class="text-xs"></div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tx-detail-gasused-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Gas used</div>
|
|
||||||
<div id="tx-detail-gasused" class="text-xs"></div>
|
|
||||||
</div>
|
|
||||||
<div id="tx-detail-rawdata-section" class="mb-4 hidden">
|
|
||||||
<div class="text-xs text-muted mb-1">Raw data</div>
|
|
||||||
<div
|
|
||||||
id="tx-detail-rawdata"
|
|
||||||
class="text-xs break-all font-mono border border-border border-dashed p-2"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ function etherscanAddressLink(address) {
|
|||||||
return `https://etherscan.io/address/${address}`;
|
return `https://etherscan.io/address/${address}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function etherscanTokenLink(tokenContract, holderAddress) {
|
||||||
|
return `https://etherscan.io/token/${tokenContract}?a=${holderAddress}`;
|
||||||
|
}
|
||||||
|
|
||||||
function isoDate(timestamp) {
|
function isoDate(timestamp) {
|
||||||
const d = new Date(timestamp * 1000);
|
const d = new Date(timestamp * 1000);
|
||||||
const pad = (n) => String(n).padStart(2, "0");
|
const pad = (n) => String(n).padStart(2, "0");
|
||||||
@@ -151,7 +155,10 @@ function show() {
|
|||||||
$("address-token-dot").innerHTML = addressDotHtml(addr.address);
|
$("address-token-dot").innerHTML = addressDotHtml(addr.address);
|
||||||
$("address-token-full").dataset.full = addr.address;
|
$("address-token-full").dataset.full = addr.address;
|
||||||
$("address-token-full").textContent = addr.address;
|
$("address-token-full").textContent = addr.address;
|
||||||
const addrLink = etherscanAddressLink(addr.address);
|
const addrLink =
|
||||||
|
tokenId !== "ETH"
|
||||||
|
? etherscanTokenLink(tokenId, addr.address)
|
||||||
|
: etherscanAddressLink(addr.address);
|
||||||
$("address-token-etherscan-link").innerHTML =
|
$("address-token-etherscan-link").innerHTML =
|
||||||
`<a href="${addrLink}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
`<a href="${addrLink}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ function render() {
|
|||||||
"tx-detail-fee-section",
|
"tx-detail-fee-section",
|
||||||
"tx-detail-gasprice-section",
|
"tx-detail-gasprice-section",
|
||||||
"tx-detail-gasused-section",
|
"tx-detail-gasused-section",
|
||||||
|
"tx-detail-network-section",
|
||||||
]) {
|
]) {
|
||||||
const el = $(id);
|
const el = $(id);
|
||||||
if (el) el.classList.add("hidden");
|
if (el) el.classList.add("hidden");
|
||||||
@@ -285,6 +286,21 @@ function populateOnChainDetails(txData) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show the network details wrapper if any child section is visible
|
||||||
|
const networkWrapper = $("tx-detail-network-section");
|
||||||
|
if (networkWrapper) {
|
||||||
|
const hasVisible = [
|
||||||
|
"tx-detail-nonce-section",
|
||||||
|
"tx-detail-fee-section",
|
||||||
|
"tx-detail-gasprice-section",
|
||||||
|
"tx-detail-gasused-section",
|
||||||
|
].some((id) => {
|
||||||
|
const el = $(id);
|
||||||
|
return el && !el.classList.contains("hidden");
|
||||||
|
});
|
||||||
|
if (hasVisible) networkWrapper.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
// Bind copy handlers for newly added elements
|
// Bind copy handlers for newly added elements
|
||||||
for (const id of [
|
for (const id of [
|
||||||
"tx-detail-block-section",
|
"tx-detail-block-section",
|
||||||
|
|||||||
Reference in New Issue
Block a user