fix: WaitTx and TransactionDetail use the network the transaction was sent on (closes #584)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

WaitTx asked the active network's node for the receipt, so after a network
switch a transaction sent on the other network was never found and was
reported as timed out. It now asks the node of the network its chain id
names, through reviewedNetworkProvider(), moved from ConfirmTx into the
shared view helpers so both screens use one function. WaitTx and
TransactionDetail build their explorer links for that network too. A stored
wait or transaction whose chain id names no network is refused on restore,
as a stored ConfirmTx transaction already is.

Model: opus-5-5
This commit was merged in pull request #621.
This commit is contained in:
2026-10-19 23:38:10 +02:00
parent 96446f4661
commit e46d894527
11 changed files with 220 additions and 66 deletions
+24 -14
View File
@@ -48,16 +48,16 @@ function getTransactionType(tx) {
return "Native " + nativeCurrencyByChainId(tx.chainId) + " Transfer";
}
function txAddressHtml(address, ensName, title) {
function txAddressHtml(address, ensName, title, chainId) {
const blockie = blockieHtml(address);
return (
`<div class="mb-1">${blockie}</div>` +
renderAddressHtml(address, { title, ensName })
renderAddressHtml(address, { title, ensName, chainId })
);
}
function txHashHtml(hash) {
const link = explorerUrl("tx", hash);
function txHashHtml(hash, chainId) {
const link = explorerUrl("tx", hash, chainId);
const extLink = etherscanLinkHtml(link);
return copyableHtml(hash, "break-all") + extLink;
}
@@ -83,10 +83,10 @@ function show(tx) {
method: tx.method || null,
contractAddress: tx.contractAddress || null,
// The network the history entry was read from. The type line and
// the fee are in its native currency, not the active network's:
// the active network can change, in Settings or when the user
// approves a site's request, before a later popup shows this
// screen again.
// the fee are in its native currency, not the active network's,
// and the links open its explorer: the active network can change,
// in Settings or when the user approves a site's request, before
// a later popup shows this screen again.
chainId: tx.chainId,
},
};
@@ -96,18 +96,24 @@ function show(tx) {
function render() {
const tx = state.viewData.tx;
if (!tx) return;
$("tx-detail-hash").innerHTML = txHashHtml(tx.hash);
$("tx-detail-hash").innerHTML = txHashHtml(tx.hash, tx.chainId);
const fromTitle = addressTitle(tx.from, state.wallets);
$("tx-detail-from").innerHTML = txAddressHtml(
tx.from,
tx.fromEns,
fromTitle,
tx.chainId,
);
// A contract creation has no recipient: transactions.js gives it `to: ""`.
if (tx.to) {
const toTitle = addressTitle(tx.to, state.wallets);
$("tx-detail-to").innerHTML = txAddressHtml(tx.to, tx.toEns, toTitle);
$("tx-detail-to").innerHTML = txAddressHtml(
tx.to,
tx.toEns,
toTitle,
tx.chainId,
);
} else {
$("tx-detail-to").innerHTML = escapeHtml(CONTRACT_CREATION_TEXT);
}
@@ -146,7 +152,7 @@ function render() {
if (tokenContractSection && tokenContractEl) {
if (tx.contractAddress) {
const dot = addressDotHtml(tx.contractAddress);
const link = explorerUrl("token", tx.contractAddress);
const link = explorerUrl("token", tx.contractAddress, tx.chainId);
// Hand-rolled rather than renderAddressHtml() because the
// link goes to the explorer's /token/ page, not /address/.
// Same two-row shape though: dot and link on the strip, the
@@ -204,7 +210,11 @@ function showDetailField(sectionId, contentId, value) {
function populateOnChainDetails(txData, chainId) {
// Block number
if (txData.block_number != null) {
const blockLink = explorerUrl("block", String(txData.block_number));
const blockLink = explorerUrl(
"block",
String(txData.block_number),
chainId,
);
const blockSection = $("tx-detail-block-section");
const blockEl = $("tx-detail-block");
if (blockSection && blockEl) {
@@ -340,9 +350,9 @@ async function loadFullTxDetails(txHash, chainId) {
if (tokenSymbol) {
detailsHtml += `<div class="font-bold">${escapeHtml(displaySymbol(tokenSymbol))}</div>`;
}
detailsHtml += renderAddressHtml(d.address);
detailsHtml += renderAddressHtml(d.address, { chainId });
} else if (d.address) {
detailsHtml += renderAddressHtml(d.address);
detailsHtml += renderAddressHtml(d.address, { chainId });
} else {
detailsHtml += `<div class="font-bold">${escapeHtml(d.value)}</div>`;
}