diff --git a/src/app/common/actions/send-request-account-response.spec.ts b/src/app/common/actions/send-request-account-response.spec.ts index c633761eb22..713585446cc 100644 --- a/src/app/common/actions/send-request-account-response.spec.ts +++ b/src/app/common/actions/send-request-account-response.spec.ts @@ -17,8 +17,8 @@ describe(sendRequestAccountResponseToTab.name, () => { } as any, }); expect(sendMessageToTab).toHaveBeenCalledTimes(1); - expect(sendMessageToTab).toHaveBeenCalledWith(2, '1', [ - { dataPublicKey: 'dataKey1', stxPublicKey: 'pubKey1' }, - ]); + expect(sendMessageToTab).toHaveBeenCalledWith(2, '1', { + result: [{ dataPublicKey: 'dataKey1', stxPublicKey: 'pubKey1' }], + }); }); }); diff --git a/src/app/common/actions/send-request-account-response.ts b/src/app/common/actions/send-request-account-response.ts index f10bd2e77de..d0713aef2d1 100644 --- a/src/app/common/actions/send-request-account-response.ts +++ b/src/app/common/actions/send-request-account-response.ts @@ -14,5 +14,9 @@ export function sendRequestAccountResponseToTab(args: SendRequestAccountResponse dataPublicKey: account.dataPublicKey, }; - return sendMessageToTab(parseInt(tabId), id, [safeAccountKeys]); + return sendMessageToTab(parseInt(tabId), id, { result: [safeAccountKeys] }); +} + +export function sendUserDeniesAccountRequest({ tabId, id }: { tabId: string; id: string }) { + return sendMessageToTab(parseInt(tabId), id, { error: { code: 4000, message: 'lskdjflksjdfl' } }); } diff --git a/src/app/pages/choose-account-request/account-request.tsx b/src/app/pages/choose-account-request/account-request.tsx index d2dfd537f5b..b370fcc8a06 100644 --- a/src/app/pages/choose-account-request/account-request.tsx +++ b/src/app/pages/choose-account-request/account-request.tsx @@ -1,13 +1,18 @@ +import { logger } from '@shared/logger'; + import { useRouteHeader } from '@app/common/hooks/use-route-header'; import { useAppDetails } from '@app/common/hooks/auth/use-app-details'; import { Header } from '@app/components/header'; import { AccountPicker } from '@app/features/account-picker/accounts'; import { useAccounts } from '@app/store/accounts/account.hooks'; import { AccountPickerLayout } from '@app/features/account-picker/account-picker.layout'; -import { logger } from '@shared/logger'; -import { sendRequestAccountResponseToTab } from '@app/common/actions/send-request-account-response'; +import { + sendRequestAccountResponseToTab, + sendUserDeniesAccountRequest, +} from '@app/common/actions/send-request-account-response'; import { useAccountRequestSearchParams } from './use-account-request-search-params'; +import { useEffect } from 'react'; export function AccountRequest() { const accounts = useAccounts(); @@ -29,6 +34,19 @@ export function AccountRequest() { window.close(); }; + const handleUnmount = () => { + if (!tabId || !id) { + logger.error('Missing either tabId or uuid. Both values are necessary to respond to app'); + return; + } + sendUserDeniesAccountRequest({ tabId, id }); + }; + + useEffect(() => { + window.addEventListener('beforeunload', handleUnmount); + return () => window.removeEventListener('beforeunload', handleUnmount); + }, []); + return ( ({ + selectId: entity => entity.domain, +}); + +export const appsSlice = createSlice({ + name: 'apps', + initialState: appsAdapter.getInitialState(), + reducers: { + appConnected: appsAdapter.addOne, + }, +}); diff --git a/src/app/store/index.ts b/src/app/store/index.ts index b2eb1e34c41..eb47923f143 100644 --- a/src/app/store/index.ts +++ b/src/app/store/index.ts @@ -20,10 +20,12 @@ import { inMemoryKeySlice } from './in-memory-key/in-memory-key.slice'; import { ExtensionStorage } from './utils/extension-storage'; import { onboardingSlice } from './onboarding/onboarding.slice'; import { analyticsSlice } from './analytics/analytics.slice'; +import { appsSlice } from './apps/apps.slice'; const storage = new ExtensionStorage(chrome.storage.local, chrome.runtime); const rootReducer = combineReducers({ + apps: appsSlice.reducer, keys: keySlice.reducer, chains: combineReducers({ stx: stxChainSlice.reducer, diff --git a/src/background/background.ts b/src/background/background.ts index 631b5044c8d..e752c2988fa 100755 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -9,7 +9,6 @@ import { logger } from '@shared/logger'; import { CONTENT_SCRIPT_PORT, LegacyMessageFromContentScript, - MESSAGE_SOURCE, RpcMethods, SupportedRpcMessages, } from '@shared/message-types'; @@ -44,6 +43,7 @@ chrome.runtime.onInstalled.addListener(details => { chrome.runtime.onConnect.addListener(port => Sentry.wrap(() => { if (port.name !== CONTENT_SCRIPT_PORT) return; + port.onMessage.addListener( (message: LegacyMessageFromContentScript | SupportedRpcMessages, port) => { if (inferLegacyMessage(message)) { @@ -59,16 +59,9 @@ chrome.runtime.onConnect.addListener(port => const params = new URLSearchParams(); params.set('tabId', port.sender.tab.id.toString()); params.set('id', message.id); - console.log(params.toString()); popupCenter({ url: `/popup-center.html#${RouteUrls.AccountRequest}?${params.toString()}`, }); - - // chrome.tabs.sendMessage(port.sender.tab.id, { - // source: MESSAGE_SOURCE, - // id: message.id, - // results: { publicKey: 'sldkfjs' }, - // }); break; } } diff --git a/src/background/legacy-external-message-handler.ts b/src/background/legacy-external-message-handler.ts index dfbcfa1c962..77149b20932 100644 --- a/src/background/legacy-external-message-handler.ts +++ b/src/background/legacy-external-message-handler.ts @@ -17,9 +17,8 @@ async function openRequestInFullPage(path: string, urlParams: URLSearchParams) { export function inferLegacyMessage(message: any): message is LegacyMessageFromContentScript { // Now that we use a RPC communication style, we can infer // legacy message types by presence of an id - // Types incorrectly state this is `undefined` - // @ts-ignore - return !Object.hasOwn(message, 'id'); + const hasIdProp = 'id' in message; + return !hasIdProp; } export async function handleLegacyExternalMethodFormat( diff --git a/src/inpage/inpage.ts b/src/inpage/inpage.ts index 0cd0d25a5eb..0c1275ee992 100644 --- a/src/inpage/inpage.ts +++ b/src/inpage/inpage.ts @@ -10,10 +10,18 @@ import { LegacyMessageToContentScript, MESSAGE_SOURCE, RpcMethodNames, + RpcRequestArgs, + RpcResponseArgs, TransactionResponseMessage, } from '@shared/message-types'; import { logger } from '@shared/logger'; +declare global { + interface Crypto { + randomUUID: () => string; + } +} + type CallableMethods = keyof typeof ExternalMethods; interface ExtensionResponse { @@ -109,19 +117,17 @@ const provider: StacksProvider = { }); }, - async request(method: RpcMethodNames, params?: any[]) { + async request(method: RpcMethodNames, params?: any[]): Promise { return new Promise((resolve, _reject) => { const id = crypto.randomUUID(); - const event = new CustomEvent(DomEventName.rpcRequest, { + const event = new CustomEvent(DomEventName.rpcRequest, { detail: { jsonrpc: '2.0', id, method, params }, }); document.dispatchEvent(event); const handleMessage = (event: MessageEvent) => { - console.log(event); if (event.data.id !== id) return; - window.removeEventListener('message', handleMessage); - resolve(event.data.result); + resolve(event.data); }; window.addEventListener('message', handleMessage); }); @@ -137,28 +143,6 @@ const provider: StacksProvider = { }, }; }, -} as StacksProvider & { request(): Promise }; +} as StacksProvider & { request(): Promise }; window.StacksProvider = provider; - -interface RpcRequestArgs { - method: RpcMethodNames; - params?: any[]; -} - -interface RpcEventArgs extends RpcRequestArgs { - jsonrpc: '2.0'; - id: string; -} - -declare global { - interface Crypto { - randomUUID: () => string; - } -} - -// declare global { -// interface Window { -// StacksProvider?: Provider; -// } -// } diff --git a/src/shared/message-types.ts b/src/shared/message-types.ts index 6aee0dcb29d..a81f65d87ef 100644 --- a/src/shared/message-types.ts +++ b/src/shared/message-types.ts @@ -36,6 +36,28 @@ export interface Message // // RPC Methods, SIP pending +interface RpcBaseArgs { + jsonrpc: '2.0'; + id: string; +} + +export interface RpcRequestArgs extends RpcBaseArgs { + method: RpcMethodNames; + params?: any[]; +} + +interface RpcSuccessResponseArgs extends RpcBaseArgs { + results: any; +} + +interface RpcErrorResponseArgs extends RpcBaseArgs { + error: { + code: number; + message: string; + }; +} + +export type RpcResponseArgs = RpcSuccessResponseArgs | RpcErrorResponseArgs; export enum RpcMethods { stx_requestAccounts, @@ -55,18 +77,6 @@ type TestAction = RpcMessage<'stx_testAnotherMethod'>; export type SupportedRpcMessages = RequestAccounts | TestAction; -// interface SupportedMessagesReturnTypeMap { -// [RpcMethods.stx_requestAccounts]: { xxx: string }; -// [RpcMethods.stx_testAnotherMethod]: { yyy: string }; -// } - -// function xx(): // method: RpcMethods -// SupportedMessagesReturnTypeMap[Method] { - -// } - -// xx('stx_requestAccounts'); - // // Deprecated methods type AuthenticationRequestMessage = Message; diff --git a/src/shared/messages.ts b/src/shared/messages.ts index d659855bdcd..782a35666d1 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -33,5 +33,5 @@ export function sendMessageToBackground(message: BackgroundActions) { } export function sendMessageToTab(tabId: number, id: string, message: object) { - return chrome.tabs.sendMessage(tabId, { source: MESSAGE_SOURCE, id, result: message }); + return chrome.tabs.sendMessage(tabId, { source: MESSAGE_SOURCE, id, ...message }); }