fix: closing a transaction or signature approval window leaves the request pending (closes #673)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

Closing a transaction or signature approval window no longer rejects the request; only Cancel does. The browser can close that window when the user clicks away, for example to copy the password from a password manager. The request stays pending and the site gets no answer. Pressing the toolbar button opens the oldest such request, unless an approved attempt still holds it. A Reject the background refuses keeps the window open with the background's message. The worker points the toolbar back at the wallet when it starts.

While such a request waits, the transaction slot stays held, so another site's eth_sendTransaction gets -32002. An address switch still rejects pending approvals with 4001.

Model: opus-5-5
This commit was merged in pull request #676.
This commit is contained in:
2026-10-27 00:56:36 +01:00
parent b58ecec1f9
commit 33ab99b7be
9 changed files with 747 additions and 165 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;
+22 -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,21 @@ 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. After Confirm, the background refuses a rejection
// while the transaction is being sent. The window then stays open and
// shows the background's message.
$("btn-reject-tx").addEventListener("click", async () => {
const response = await sendMessage({
type: "AUTISTMASK_TX_RESPONSE",
id: approvalId,
approved: false,
});
}).catch(() => null);
if (response && response.error) {
showError("approve-tx-error", response.error);
return;
}
window.close();
});
@@ -1270,12 +1279,18 @@ function init(_ctx) {
if (outcome.retryable) setSignButtonBusy(false);
});
$("btn-reject-sign").addEventListener("click", () => {
notify({
// As for the transaction's Reject above. After Sign, the background
// refuses a rejection while the signature is being checked.
$("btn-reject-sign").addEventListener("click", async () => {
const response = await sendMessage({
type: "AUTISTMASK_SIGN_RESPONSE",
id: approvalId,
approved: false,
});
}).catch(() => null);
if (response && response.error) {
showError("approve-sign-error", response.error);
return;
}
window.close();
});
}