Add dedicated wait/success/error screens for transaction status
After broadcast, the user is taken to a full-screen wait view showing the amount, recipient, tx hash (copyable + etherscan link), and a count-up timer. The view polls every 10 seconds for confirmation. On confirmation: navigates to success screen showing block number, tx hash, and a Done button that returns to the address view. On 60-second timeout or error: navigates to error screen with the failure message, tx hash (if available), and Done button. Replaces the previous inline confirm-status div that was crammed onto the confirmation page.
This commit is contained in:
@@ -27,6 +27,7 @@ const { isScamAddress } = require("../../shared/scamlist");
|
||||
const { ERC20_ABI } = require("../../shared/constants");
|
||||
const { log } = require("../../shared/log");
|
||||
const makeBlockie = require("ethereum-blockies-base64");
|
||||
const txStatus = require("./txStatus");
|
||||
|
||||
const EXT_ICON =
|
||||
`<span style="display:inline-block;width:10px;height:10px;margin-left:4px;vertical-align:middle">` +
|
||||
@@ -36,7 +37,6 @@ const EXT_ICON =
|
||||
`</svg></span>`;
|
||||
|
||||
let pendingTx = null;
|
||||
let elapsedTimer = null;
|
||||
|
||||
function etherscanTokenLink(address) {
|
||||
return `https://etherscan.io/token/${address}`;
|
||||
@@ -217,7 +217,6 @@ function show(txInfo) {
|
||||
// Gas estimate — show placeholder then fetch async
|
||||
$("confirm-fee").classList.remove("hidden");
|
||||
$("confirm-fee-amount").textContent = "Estimating...";
|
||||
$("confirm-status").classList.add("hidden");
|
||||
showView("confirm-tx");
|
||||
|
||||
estimateGas(txInfo);
|
||||
@@ -309,10 +308,7 @@ function init(ctx) {
|
||||
|
||||
hidePasswordModal();
|
||||
|
||||
const statusEl = $("confirm-status");
|
||||
statusEl.textContent = "Sending...";
|
||||
statusEl.classList.remove("hidden");
|
||||
|
||||
let tx;
|
||||
try {
|
||||
const signer = getSignerForAddress(
|
||||
wallet,
|
||||
@@ -322,7 +318,6 @@ function init(ctx) {
|
||||
const provider = getProvider(state.rpcUrl);
|
||||
const connectedSigner = signer.connect(provider);
|
||||
|
||||
let tx;
|
||||
if (pendingTx.token === "ETH") {
|
||||
tx = await connectedSigner.sendTransaction({
|
||||
to: pendingTx.to,
|
||||
@@ -339,62 +334,10 @@ function init(ctx) {
|
||||
tx = await contract.transfer(pendingTx.to, amount);
|
||||
}
|
||||
|
||||
// Disable send button immediately after broadcast
|
||||
const sendBtn = $("btn-confirm-send");
|
||||
sendBtn.disabled = true;
|
||||
sendBtn.classList.add("text-muted");
|
||||
|
||||
// Show etherscan link and elapsed timer
|
||||
const broadcastTime = Date.now();
|
||||
statusEl.innerHTML = "";
|
||||
statusEl.appendChild(
|
||||
document.createTextNode(
|
||||
"Broadcast. Waiting for confirmation... ",
|
||||
),
|
||||
);
|
||||
const timerSpan = document.createElement("span");
|
||||
timerSpan.textContent = "(0s)";
|
||||
statusEl.appendChild(timerSpan);
|
||||
statusEl.appendChild(document.createElement("br"));
|
||||
const txLink = document.createElement("a");
|
||||
txLink.href = "https://etherscan.io/tx/" + tx.hash;
|
||||
txLink.target = "_blank";
|
||||
txLink.rel = "noopener";
|
||||
txLink.className = "underline decoration-dashed break-all";
|
||||
txLink.textContent = tx.hash;
|
||||
statusEl.appendChild(document.createTextNode("Tx: "));
|
||||
statusEl.appendChild(txLink);
|
||||
|
||||
if (elapsedTimer) clearInterval(elapsedTimer);
|
||||
elapsedTimer = setInterval(() => {
|
||||
const elapsed = Math.floor((Date.now() - broadcastTime) / 1000);
|
||||
timerSpan.textContent = "(" + elapsed + "s)";
|
||||
}, 1000);
|
||||
|
||||
const receipt = await tx.wait();
|
||||
clearInterval(elapsedTimer);
|
||||
elapsedTimer = null;
|
||||
|
||||
statusEl.innerHTML = "";
|
||||
statusEl.appendChild(
|
||||
document.createTextNode(
|
||||
"Confirmed in block " + receipt.blockNumber + ". Tx: ",
|
||||
),
|
||||
);
|
||||
const link = document.createElement("a");
|
||||
link.href = "https://etherscan.io/tx/" + receipt.hash;
|
||||
link.target = "_blank";
|
||||
link.rel = "noopener";
|
||||
link.className = "underline decoration-dashed break-all";
|
||||
link.textContent = receipt.hash;
|
||||
statusEl.appendChild(link);
|
||||
ctx.doRefreshAndRender();
|
||||
txStatus.showWait(pendingTx, tx.hash);
|
||||
} catch (e) {
|
||||
if (elapsedTimer) {
|
||||
clearInterval(elapsedTimer);
|
||||
elapsedTimer = null;
|
||||
}
|
||||
statusEl.textContent = "Failed: " + (e.shortMessage || e.message);
|
||||
const hash = tx ? tx.hash : null;
|
||||
txStatus.showError(pendingTx, hash, e.shortMessage || e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user