fix: closing a transaction or signature approval window leaves the request pending (closes #673)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

The browser can close the approval window when the user clicks away from it,
for example to copy the password from a password manager. Closing it used to
reject the request with 4001. Now the request stays pending and the site gets
no answer. Until it is answered, the toolbar popup opens the oldest such
approval. A worker that starts holds no approvals, so it points the toolbar
popup back at the wallet.

Reject now closes its window only after the background has the rejection. Sent
as the window closed, the rejection could be lost, which the old window-close
rejection hid.

Site-connection and network-switch windows still reject the request when
closed.

Model: opus-5-5
This commit is contained in:
2026-10-26 21:18:24 +00:00
parent bf8aa9f5dd
commit df0de00821
9 changed files with 592 additions and 162 deletions
+3 -3
View File
@@ -281,9 +281,9 @@ async function followStoredSettings() {
// zoom it reports, 170% among them, so once the page has its new width (its
// resize event) it is measured again, and the window widened again while the
// page still falls short, three times at most. A window that cannot grow sends
// no resize event, and the page stops there. The connection prompt can also
// show in the toolbar popup, whose window is the user's browser window; that
// one is left alone.
// no resize event, and the page stops there. An approval can also show in the
// toolbar popup, whose window is the user's browser window; that one is left
// alone.
async function widenApprovalWindow() {
const page = document.documentElement;
if (page.scrollWidth <= page.clientWidth) return;
+11 -7
View File
@@ -55,7 +55,7 @@ const {
} = require("../../shared/approvalVerify");
const txStatus = require("./txStatus");
const uniswap = require("../../shared/uniswap");
const { notify, runtimeApi, sendMessage } = require("../../shared/browserApi");
const { runtimeApi, sendMessage } = require("../../shared/browserApi");
const erc20Iface = new Interface(ERC20_ABI);
@@ -1142,12 +1142,15 @@ function init(_ctx) {
}
});
$("btn-reject-tx").addEventListener("click", () => {
notify({
// The window closes only once the background has the rejection. A message
// sent as the window closes can be lost, and a closed window does not
// reject the request.
$("btn-reject-tx").addEventListener("click", async () => {
await sendMessage({
type: "AUTISTMASK_TX_RESPONSE",
id: approvalId,
approved: false,
});
}).catch(() => {});
window.close();
});
@@ -1270,12 +1273,13 @@ function init(_ctx) {
if (outcome.retryable) setSignButtonBusy(false);
});
$("btn-reject-sign").addEventListener("click", () => {
notify({
// As for the transaction's Reject above.
$("btn-reject-sign").addEventListener("click", async () => {
await sendMessage({
type: "AUTISTMASK_SIGN_RESPONSE",
id: approvalId,
approved: false,
});
}).catch(() => {});
window.close();
});
}