Compare commits
1 Commits
fix/issue-
...
fix/70-con
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc4e78c466 |
@@ -463,12 +463,12 @@
|
||||
</div>
|
||||
|
||||
<!-- ERC-20 token contract (hidden for ETH) -->
|
||||
<div id="confirm-token-section" class="mb-3 hidden">
|
||||
<div class="text-xs text-muted mb-1">Token contract</div>
|
||||
<div
|
||||
id="confirm-token-contract"
|
||||
class="text-xs break-all"
|
||||
></div>
|
||||
<div
|
||||
id="confirm-token-section"
|
||||
class="bg-hover rounded-md mx-1 p-3 mb-3 text-xs hidden"
|
||||
>
|
||||
<div class="font-bold mb-2">Token Contract</div>
|
||||
<div id="confirm-token-contract" class="break-all"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
|
||||
@@ -95,10 +95,22 @@ function show(txInfo) {
|
||||
// Token contract section (ERC-20 only)
|
||||
const tokenSection = $("confirm-token-section");
|
||||
if (isErc20) {
|
||||
const dot = addressDotHtml(txInfo.token);
|
||||
const link = etherscanTokenLink(txInfo.token);
|
||||
$("confirm-token-contract").innerHTML =
|
||||
escapeHtml(txInfo.token) +
|
||||
` <a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
||||
`<div class="flex items-center">` +
|
||||
dot +
|
||||
`<span class="break-all underline decoration-dashed cursor-pointer" id="confirm-token-contract-copy" data-copy="${escapeHtml(txInfo.token)}">${escapeHtml(txInfo.token)}</span>` +
|
||||
`<a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>` +
|
||||
`</div>`;
|
||||
if (txInfo.tokenName) {
|
||||
$("confirm-token-contract").innerHTML +=
|
||||
`<div class="mt-1"><span class="text-muted">Name:</span> ${escapeHtml(txInfo.tokenName)}</div>`;
|
||||
}
|
||||
if (txInfo.tokenSymbol) {
|
||||
$("confirm-token-contract").innerHTML +=
|
||||
`<div class="mt-1"><span class="text-muted">Symbol:</span> ${escapeHtml(txInfo.tokenSymbol)}</div>`;
|
||||
}
|
||||
tokenSection.classList.remove("hidden");
|
||||
} else {
|
||||
tokenSection.classList.add("hidden");
|
||||
@@ -273,6 +285,13 @@ function hidePasswordModal() {
|
||||
}
|
||||
|
||||
function init(ctx) {
|
||||
$("confirm-token-section").addEventListener("click", (e) => {
|
||||
const copyEl = e.target.closest("[data-copy]");
|
||||
if (copyEl) {
|
||||
navigator.clipboard.writeText(copyEl.dataset.copy);
|
||||
}
|
||||
});
|
||||
|
||||
$("btn-confirm-send").addEventListener("click", () => {
|
||||
showPasswordModal();
|
||||
});
|
||||
|
||||
@@ -10,7 +10,11 @@ const {
|
||||
const { state, currentAddress } = require("../../shared/state");
|
||||
let ctx;
|
||||
const { getProvider } = require("../../shared/balances");
|
||||
const { KNOWN_SYMBOLS, resolveSymbol } = require("../../shared/tokenList");
|
||||
const {
|
||||
KNOWN_SYMBOLS,
|
||||
TOKEN_BY_ADDRESS,
|
||||
resolveSymbol,
|
||||
} = require("../../shared/tokenList");
|
||||
|
||||
const EXT_ICON =
|
||||
`<span style="display:inline-block;width:10px;height:10px;margin-left:4px;vertical-align:middle">` +
|
||||
@@ -124,6 +128,7 @@ function init(_ctx) {
|
||||
|
||||
let tokenSymbol = null;
|
||||
let tokenBalance = null;
|
||||
let tokenName = null;
|
||||
if (token !== "ETH") {
|
||||
const tb = (addr.tokenBalances || []).find(
|
||||
(t) => t.address.toLowerCase() === token.toLowerCase(),
|
||||
@@ -134,6 +139,17 @@ function init(_ctx) {
|
||||
state.trackedTokens,
|
||||
);
|
||||
tokenBalance = tb ? tb.balance || "0" : "0";
|
||||
// Resolve token name from balances, tracked tokens, or known list
|
||||
const lower = token.toLowerCase();
|
||||
tokenName =
|
||||
(tb && tb.name) ||
|
||||
(
|
||||
(state.trackedTokens || []).find(
|
||||
(t) => t.address.toLowerCase() === lower,
|
||||
) || {}
|
||||
).name ||
|
||||
(TOKEN_BY_ADDRESS.get(lower) || {}).name ||
|
||||
null;
|
||||
}
|
||||
|
||||
ctx.showConfirmTx({
|
||||
@@ -145,6 +161,7 @@ function init(_ctx) {
|
||||
balance: addr.balance,
|
||||
tokenSymbol: tokenSymbol,
|
||||
tokenBalance: tokenBalance,
|
||||
tokenName: tokenName,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -153,14 +153,9 @@ async function fetchRecentTransactions(address, blockscoutUrl, count = 25) {
|
||||
|
||||
// When a token transfer shares a hash with a normal tx, the normal tx
|
||||
// is the contract call (0 ETH) and the token transfer has the real
|
||||
// amount and symbol. Preserve contract call metadata (direction, label,
|
||||
// method) so swaps and other contract interactions display correctly.
|
||||
//
|
||||
// A single tx hash can produce multiple token transfers (e.g. a swap
|
||||
// sends token A and receives token B). Use a composite key
|
||||
// (hash:contractAddress) so every transfer is preserved. The original
|
||||
// normal-tx entry (keyed by bare hash) is removed when at least one
|
||||
// token transfer replaces it.
|
||||
// amount and symbol. Replace the normal tx with the token transfer,
|
||||
// but preserve contract call metadata (direction, label, method) so
|
||||
// swaps and other contract interactions display correctly.
|
||||
for (const tt of ttJson.items || []) {
|
||||
const parsed = parseTokenTransfer(tt, addrLower);
|
||||
const existing = txsByHash.get(parsed.hash);
|
||||
@@ -169,12 +164,8 @@ async function fetchRecentTransactions(address, blockscoutUrl, count = 25) {
|
||||
parsed.directionLabel = existing.directionLabel;
|
||||
parsed.isContractCall = true;
|
||||
parsed.method = existing.method;
|
||||
// Remove the bare-hash normal tx so it isn't duplicated
|
||||
txsByHash.delete(parsed.hash);
|
||||
}
|
||||
// Use composite key so multiple token transfers per tx are kept
|
||||
const compositeKey = parsed.hash + ":" + (parsed.contractAddress || "");
|
||||
txsByHash.set(compositeKey, parsed);
|
||||
txsByHash.set(parsed.hash, parsed);
|
||||
}
|
||||
|
||||
const txs = [...txsByHash.values()];
|
||||
|
||||
Reference in New Issue
Block a user