From 415108969732302f1f57f6b231e35cd62a6ef747 Mon Sep 17 00:00:00 2001 From: Christopher Ferreira <104831203+christopherferreira9@users.noreply.github.com> Date: Thu, 9 Jan 2025 10:28:19 +0000 Subject: [PATCH] chore: call getPermissions on accountsChanged when using extension (#1185) * chore: call getPermissions on accountsChanged when using extension * chore: fixes linting * chore: uses await instead of .then and adds coverage --- .../setupExtensionPreferences.test.ts | 34 +++++++++++++++++++ .../setupExtensionPreferences.ts | 33 +++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.test.ts b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.test.ts index 8941b891b..3b13e4f2c 100644 --- a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.test.ts +++ b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.test.ts @@ -1,6 +1,8 @@ import { TrackingEvents } from '@metamask/sdk-communication-layer'; import { MetaMaskSDK } from '../../../sdk'; +import { SDKProvider } from '../../../provider/SDKProvider'; import { getBrowserExtension } from '../../../utils/get-browser-extension'; +import { EXTENSION_EVENTS, RPC_METHODS } from '../../../config'; import { setupExtensionPreferences } from './setupExtensionPreferences'; jest.mock('../../../utils/get-browser-extension'); @@ -81,4 +83,36 @@ describe('setupExtensionPreferences', () => { event: TrackingEvents.SDK_USE_EXTENSION, }); }); + + it('should terminate instance if permissions are revoked', async () => { + const mockTerminate = jest.fn().mockResolvedValue(undefined); + const mockRequest = jest.fn().mockResolvedValue([]); + + instance.getProvider = jest.fn().mockReturnValue({ + request: mockRequest, + }) as unknown as () => SDKProvider; + + instance.terminate = mockTerminate; + instance.extensionActive = true; // Ensure extension is active + + const mockBrowserExtension = { + on: jest.fn((event: string, callback: (accounts: string[]) => void) => { + if (event === EXTENSION_EVENTS.ACCOUNTS_CHANGED) { + // Directly call the callback to simulate the event + callback([]); + } + }), + }; + + (getBrowserExtension as jest.Mock).mockReturnValue(mockBrowserExtension); + + await setupExtensionPreferences(instance); + + expect(mockRequest).toHaveBeenCalledWith({ + method: RPC_METHODS.WALLET_GETPERMISSIONS, + params: [], + }); + + expect(mockTerminate).toHaveBeenCalled(); + }); }); diff --git a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.ts b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.ts index 616c25966..4cfb46499 100644 --- a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.ts +++ b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupExtensionPreferences.ts @@ -1,7 +1,11 @@ import { TrackingEvents } from '@metamask/sdk-communication-layer'; import { logger } from '../../../utils/logger'; import { SDKProvider } from '../../../provider/SDKProvider'; -import { EXTENSION_EVENTS, STORAGE_PROVIDER_TYPE } from '../../../config'; +import { + EXTENSION_EVENTS, + RPC_METHODS, + STORAGE_PROVIDER_TYPE, +} from '../../../config'; import { MetaMaskSDK } from '../../../sdk'; import { getBrowserExtension } from '../../../utils/get-browser-extension'; import { Ethereum } from '../../Ethereum'; @@ -64,7 +68,7 @@ export async function setupExtensionPreferences(instance: MetaMaskSDK) { metamaskBrowserExtension.on( EXTENSION_EVENTS.ACCOUNTS_CHANGED, - (accounts) => { + async (accounts) => { logger( `[MetaMaskSDK: setupExtensionPreferences()] PROPAGATE accountsChanged accounts=${accounts}`, ); @@ -80,9 +84,28 @@ export async function setupExtensionPreferences(instance: MetaMaskSDK) { } if (isExtensionActive && (accounts as string[])?.length === 0) { - logger( - `[MetaMaskSDK: setupExtensionPreferences()] permissions were revoked on extension or extension was locked`, - ); + const getPermissionsResponse = await instance + .getProvider() + ?.request({ + method: RPC_METHODS.WALLET_GETPERMISSIONS, + params: [], + }); + + const permissions = getPermissionsResponse as { + caveats: { type: string; value: string[] }[]; + parentCapability: string; + }[]; + + if (permissions.length === 0) { + try { + await instance.terminate(); + } catch (error) { + logger( + `[MetaMaskSDK: setupExtensionPreferences()] error terminating on permissions revoked`, + error, + ); + } + } } }, );