From 727fa27ebd88dfed8cccf5a80e2b4524573db962 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Thu, 22 Oct 2026 19:14:57 +0300 Subject: [PATCH] WizardConnect "Open in wallet" links that open a new window reach Aegis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Potidaea's "Open in wallet" is , a shape many dapps use. A new-window wiz:// link goes through the window-open handler, which credits a pairing to the page only through the request's referrer, so it can tell the page's own link from one in a frame. noreferrer strips the referrer, so the link was dropped and the wallet never heard of it. The inject preload, which runs in a tab's top document only, now hands a trusted click on a wiz:// link straight to main, and main accepts it only from the tab's main frame before routing it like any pairing link. Links inside iframes still go the old way and are still refused without a referrer. --- addon-inject-preload.js | 20 ++++++++++++++++++++ main.js | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/addon-inject-preload.js b/addon-inject-preload.js index c049eb22..4f19b346 100644 --- a/addon-inject-preload.js +++ b/addon-inject-preload.js @@ -43,3 +43,23 @@ for (const inj of injections) { console.warn(`[theseus] add-on "${id}" page-inject failed:`, e?.message || e); } } + +// wiz:// links (WizardConnect pairing, "Open in wallet"). A same-tab click is +// caught by main on will-navigate; one that opens a new window +// (target="_blank") reaches main's window-open handler, which can tell the +// page's own link from a frame's only by the referrer, and rel="noreferrer", +// common on dapps, strips it. So those clicks were dropped and the wallet +// never saw them. A click the user really made on such a link in this, the +// top document, goes straight to main instead; main checks it came from the +// tab's main frame and routes it like any other pairing link. +document.addEventListener("click", (e) => { + if (!e.isTrusted || e.button !== 0) return; + // composedPath reaches into shadow roots, where web-component buttons live. + const a = (typeof e.composedPath === "function" ? e.composedPath() : [e.target]) + .find((n) => n && n.tagName === "A" && n.hasAttribute && n.hasAttribute("href")); + if (!a) return; + const href = String(a.getAttribute("href") || "").trim(); + if (!/^wiz:/i.test(href) || href.length > 4096) return; + e.preventDefault(); + ipcRenderer.send("wiz-link", href); +}, true); diff --git a/main.js b/main.js index 411777b9..95fcad4e 100644 --- a/main.js +++ b/main.js @@ -7368,6 +7368,16 @@ function routeWizUri(uri, pageUrl, tabId) { send(); return true; } +// A wiz:// link the user clicked in a page's top document, reported by +// addon-inject-preload.js. It covers links that open a new window with +// rel="noreferrer", which the window-open handler cannot credit to the page. +// Only a tab's main frame may report one: the preload runs nowhere else, and +// a frame's report would otherwise be credited to the tab's top origin. +ipcMain.on("wiz-link", (e, uri) => { + const tab = tabForSender(e.sender); + if (!tab || tab.settings || tab.addonId || e.senderFrame !== e.sender.mainFrame) return; + routeWizUri(String(uri || "").slice(0, 4096), e.sender.getURL(), tab.id); +}); ipcMain.handle("addon-page-msg", async (e, addonId, msg, payload) => { const tab = tabForSender(e.sender);