diff --git a/app/lib/ppom/ppom-util.test.ts b/app/lib/ppom/ppom-util.test.ts index 95241217c88..27340f43e23 100644 --- a/app/lib/ppom/ppom-util.test.ts +++ b/app/lib/ppom/ppom-util.test.ts @@ -13,6 +13,12 @@ import { RpcEndpointType, } from '@metamask/network-controller'; import { NETWORKS_CHAIN_ID } from '../../constants/network'; +import { + Reason, + ResultType, + SecurityAlertSource, +} from '../../components/Views/confirmations/components/BlockaidBanner/BlockaidBanner.types'; +import Logger from '../../util/Logger'; const CHAIN_ID_MOCK = '0x1'; @@ -176,8 +182,8 @@ describe('PPOM Utils', () => { MockEngine.context.PreferencesController.state.securityAlertsEnabled = false; await PPOMUtil.validateRequest(mockRequest, CHAIN_ID_MOCK); - expect(MockEngine.context.PPOMController?.usePPOM).toBeCalledTimes(0); - expect(spyTransactionAction).toBeCalledTimes(0); + expect(MockEngine.context.PPOMController?.usePPOM).toHaveBeenCalledTimes(0); + expect(spyTransactionAction).toHaveBeenCalledTimes(0); }); it('should not validate if request is send to users own account ', async () => { @@ -307,6 +313,22 @@ describe('PPOM Utils', () => { }); }); + it('logs error if normalization fails', async () => { + const error = new Error('Test Error'); + normalizeTransactionParamsMock.mockImplementation(() => { + throw error; + }); + + const spyLogger = jest.spyOn(Logger, 'log'); + + await PPOMUtil.validateRequest(mockRequest, CHAIN_ID_MOCK); + + expect(spyLogger).toHaveBeenCalledTimes(1); + expect(spyLogger).toHaveBeenCalledWith( + `Error validating JSON RPC using PPOM: ${error}`, + ); + }); + it('normalizes transaction request origin before validation', async () => { const validateMock = jest.fn(); @@ -385,5 +407,34 @@ describe('PPOM Utils', () => { await PPOMUtil.validateRequest(mockRequest, CHAIN_ID_MOCK); expect(spy).toHaveBeenCalledTimes(2); }); + + it('sets security alerts response to failed when security alerts API and controller PPOM throws', async () => { + const spy = jest.spyOn( + TransactionActions, + 'setTransactionSecurityAlertResponse', + ); + + const validateMock = new Error('Test Error'); + + const ppomMock = { + validateJsonRpc: validateMock, + }; + + MockEngine.context.PPOMController?.usePPOM.mockImplementation( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (callback: any) => callback(ppomMock), + ); + + await PPOMUtil.validateRequest(mockRequest, CHAIN_ID_MOCK); + expect(spy).toHaveBeenCalledTimes(2); + expect(spy).toHaveBeenCalledWith(CHAIN_ID_MOCK, { + chainId: CHAIN_ID_MOCK, + req: mockRequest, + result_type: ResultType.Failed, + reason: Reason.failed, + description: 'Validating the confirmation failed by throwing error.', + source: SecurityAlertSource.Local, + }); + }); }); -}); +}); \ No newline at end of file diff --git a/app/lib/ppom/ppom-util.ts b/app/lib/ppom/ppom-util.ts index 86f291b3543..3a7716eb87f 100644 --- a/app/lib/ppom/ppom-util.ts +++ b/app/lib/ppom/ppom-util.ts @@ -155,14 +155,19 @@ async function validateWithController( ppomController: PPOMController, request: PPOMRequest, ): Promise { - const response = (await ppomController.usePPOM((ppom) => - ppom.validateJsonRpc(request as unknown as Record), - )) as SecurityAlertResponse; + try{ + const response = (await ppomController.usePPOM((ppom) => + ppom.validateJsonRpc(request as unknown as Record), + )) as SecurityAlertResponse; - return { - ...response, - source: SecurityAlertSource.Local, - }; + return { + ...response, + source: SecurityAlertSource.Local, + }; + } catch (e) { + Logger.log(`Error validating request with PPOM: ${e}`); + return {...SECURITY_ALERT_RESPONSE_FAILED, source: SecurityAlertSource.Local,}; + } } async function validateWithAPI(