diff --git a/apps/extension/src/hooks/popup-ready.ts b/apps/extension/src/hooks/popup-ready.ts index ebcca4c4..3123da63 100644 --- a/apps/extension/src/hooks/popup-ready.ts +++ b/apps/extension/src/hooks/popup-ready.ts @@ -1,24 +1,19 @@ import { useEffect, useRef } from 'react'; -import { PopupResponse, PopupType, Ready } from '../message/popup'; +import { useSearchParams } from 'react-router-dom'; type IsReady = boolean | undefined; // signals that react is ready (mounted) to service worker export const usePopupReady = (isReady: IsReady = undefined) => { const sentMessagesRef = useRef(new Set()); - const searchParams = new URLSearchParams(window.location.search); + const [searchParams] = useSearchParams(); const popupId = searchParams.get('popupId'); useEffect(() => { if (popupId && (isReady === undefined || isReady) && !sentMessagesRef.current.has(popupId)) { sentMessagesRef.current.add(popupId); - void chrome.runtime.sendMessage({ - type: PopupType.Ready, - data: { - popupId, - }, - } as PopupResponse); + void chrome.runtime.sendMessage(popupId); } }, [popupId, isReady]); }; diff --git a/apps/extension/src/message/popup.ts b/apps/extension/src/message/popup.ts index 092cc61f..29290e34 100644 --- a/apps/extension/src/message/popup.ts +++ b/apps/extension/src/message/popup.ts @@ -11,10 +11,9 @@ import { OriginRecord } from '../storage/types'; export enum PopupType { TxApproval = 'TxApproval', OriginApproval = 'OriginApproval', - Ready = 'PopupReady', } -export type PopupMessage = TxApproval | OriginApproval | Ready; +export type PopupMessage = TxApproval | OriginApproval; export type PopupRequest = InternalRequest; export type PopupResponse = InternalResponse; @@ -35,14 +34,6 @@ export type TxApproval = InternalMessage< } >; -export type Ready = InternalMessage< - PopupType.Ready, - null, - { - popupId: string; - } ->; - export const isPopupRequest = (req: unknown): req is PopupRequest => req != null && typeof req === 'object' && @@ -51,19 +42,8 @@ export const isPopupRequest = (req: unknown): req is PopupRequest => typeof req.type === 'string' && req.type in PopupType; -export const isPopupResponse = (res: unknown): res is PopupResponse => - res != null && - typeof res === 'object' && - ('data' in res || 'error' in res) && - 'type' in res && - typeof res.type === 'string' && - res.type in PopupType; - export const isOriginApprovalRequest = (req: unknown): req is InternalRequest => - isPopupRequest(req) && req.type === PopupType.OriginApproval; + isPopupRequest(req) && req.type === PopupType.OriginApproval && 'origin' in req.request; export const isTxApprovalRequest = (req: unknown): req is InternalRequest => - isPopupRequest(req) && req.type === PopupType.TxApproval; - -export const isPopupReadyResponse = (res: unknown): res is InternalResponse => - isPopupResponse(res) && res.type === PopupType.Ready; + isPopupRequest(req) && req.type === PopupType.TxApproval && 'authorizeRequest' in req.request; diff --git a/apps/extension/src/popup.ts b/apps/extension/src/popup.ts index 8f540d90..c42dd93b 100644 --- a/apps/extension/src/popup.ts +++ b/apps/extension/src/popup.ts @@ -1,11 +1,5 @@ import { sessionExtStorage } from './storage/session'; -import { - isPopupReadyResponse, - PopupMessage, - PopupRequest, - PopupResponse, - PopupType, -} from './message/popup'; +import { PopupMessage, PopupRequest, PopupType } from './message/popup'; import { PopupPath } from './routes/popup/paths'; import type { InternalRequest, InternalResponse } from '@penumbra-zone/types/internal-msg/shared'; import { Code, ConnectError } from '@connectrpc/connect'; @@ -82,16 +76,16 @@ const throwIfNeedsLogin = async () => { }; const spawnPopup = async (pop: PopupType, popupId: string) => { - const popUrl = new URL(chrome.runtime.getURL(`popup.html?popupId=${popupId}`)); + const popUrl = new URL(chrome.runtime.getURL('popup.html')); await throwIfNeedsLogin(); switch (pop) { case PopupType.OriginApproval: - popUrl.hash = PopupPath.ORIGIN_APPROVAL; + popUrl.hash = `${PopupPath.ORIGIN_APPROVAL}?popupId=${popupId}`; return spawnDetachedPopup(popUrl.href); case PopupType.TxApproval: - popUrl.hash = PopupPath.TRANSACTION_APPROVAL; + popUrl.hash = `${PopupPath.TRANSACTION_APPROVAL}?popupId=${popupId}`; return spawnDetachedPopup(popUrl.href); default: throw Error('Unknown popup type'); @@ -100,23 +94,17 @@ const spawnPopup = async (pop: PopupType, popupId: string) => { const POPUP_READY_TIMEOUT = 60 * 1000; -const popupReady = async (popupId: string): Promise => { - return new Promise((resolve, reject): void => { - setTimeout(() => { - reject(new Error('Popup ready timed out')); - }, POPUP_READY_TIMEOUT); +const popupReady = (popupId: string): Promise => + new Promise((resolve, reject) => { + AbortSignal.timeout(POPUP_READY_TIMEOUT).onabort = reject; - const handlePopupReady = (res: PopupResponse): void => { - if (!isPopupReadyResponse(res)) { - return; - } - - if ('data' in res && res.data.popupId === popupId) { - chrome.runtime.onMessage.removeListener(handlePopupReady); + const idListen = (msg: unknown, _: chrome.runtime.MessageSender, respond: () => void) => { + if (msg === popupId) { resolve(); + chrome.runtime.onMessage.removeListener(idListen); + respond(); } }; - chrome.runtime.onMessage.addListener(handlePopupReady); + chrome.runtime.onMessage.addListener(idListen); }); -};