fix: WaitTx timeout no longer overwrites a rendered success screen (closes #155)
All checks were successful
check / check (push) Successful in 41s

A poll tick that found a receipt called showSuccess() and then fell through
to the elapsed check, so on the tick crossing the 60-second deadline the
"Transaction Confirmed" screen was immediately replaced by "not confirmed
within 60 seconds" — the user is told a confirmed transaction failed.

The wait now has an explicit lifecycle. A wait id is bumped by endWait(),
which is called on receipt, on timeout, when a new wait starts and when the
user navigates away; every timer callback and every post-await continuation
checks it, so exactly one outcome can be rendered per wait and no stale
timer or in-flight receipt lookup can touch a view it no longer owns.

A receipt lookup that throws is treated as "no answer this tick" rather than
"no receipt": the poll returns before the deadline check and keeps running,
so one transient RPC failure cannot declare a timeout. This matters most on
a resumed wait, whose first poll is immediate and may already be past the
deadline, where a single error would otherwise be terminal.

The wait is also persisted (state.viewData.pendingWait) and "wait-tx" is now
restorable: reopening the popup resumes the poll with the elapsed counter
and the deadline still measured from the original broadcast, instead of
silently abandoning the wait. restoreWait() validates the whole persisted
payload — hash, txInfo and a finite numeric broadcastTime — and returns
false otherwise, so a malformed payload falls back to the main view instead
of throwing out of restoreView() or rendering an unexitable "NaNs" wait.
Polling stays in the popup rather than moving to the background, which would
depend on setInterval surviving in an MV3 service worker.

The 60-second threshold and the timeout copy are unchanged.
This commit is contained in:
clawbot
2026-08-11 12:39:15 +00:00
parent f455b0ae7f
commit feed6779d2
5 changed files with 467 additions and 20 deletions

View File

@@ -601,10 +601,17 @@ screen, including ExportPrivKey, falls back to Home.
- To: color dot + full address + etherscan link
- Transaction hash: full hash (tap to copy) + etherscan link
- Count-up timer: "Waiting for confirmation... Ns"
- **Behavior**: Polls `getTransactionReceipt` every 10 seconds.
- **Behavior**: Polls `getTransactionReceipt` every 10 seconds. The wait is
persisted: closing and reopening the popup resumes the poll, with the elapsed
counter and the timeout deadline still measured from the original broadcast. A
lookup that fails is retried on the next tick rather than counted as a missing
receipt.
- **Transitions**:
- Receipt found → **SuccessTx**
- 60 seconds without confirmation → **ErrorTx** (timeout message)
- A lookup that answers "no receipt" 60 seconds or more after broadcast →
**ErrorTx** (timeout message)
- Exactly one of the two: a receipt found on the tick that crosses the
deadline wins, and neither outcome can be rendered over the other
#### SuccessTx (`success-tx`)