diff --git a/.metamaskrc.dist b/.metamaskrc.dist index 429addc860be..b28f0160f9fb 100644 --- a/.metamaskrc.dist +++ b/.metamaskrc.dist @@ -27,5 +27,10 @@ BLOCKAID_PUBLIC_KEY= ENABLE_CONFIRMATION_REDESIGN= +; URL of security alerts API used to validate dApp requests +; SECURITY_ALERTS_API_URL='http://localhost:3000' +; Temporary mechanism to enable security alerts API prior to release +; SECURITY_ALERTS_API_ENABLED='true' + ; Enables the Settings Page - Developer Options ; ENABLE_SETTINGS_PAGE_DEV_OPTIONS=true diff --git a/app/scripts/lib/ppom/ppom-middleware.ts b/app/scripts/lib/ppom/ppom-middleware.ts index bc442bad932e..1aae47ffa314 100644 --- a/app/scripts/lib/ppom/ppom-middleware.ts +++ b/app/scripts/lib/ppom/ppom-middleware.ts @@ -88,6 +88,7 @@ export function createPPOMMiddleware< ppomController, request: req, securityAlertId, + chainId, }).then((securityAlertResponse) => { updateSecurityAlertResponse( req.method, diff --git a/app/scripts/lib/ppom/ppom-util.test.ts b/app/scripts/lib/ppom/ppom-util.test.ts index ac16022cee8a..cb7eb5425c74 100644 --- a/app/scripts/lib/ppom/ppom-util.test.ts +++ b/app/scripts/lib/ppom/ppom-util.test.ts @@ -11,6 +11,7 @@ import { Message } from '@metamask/message-manager'; import { BlockaidReason, BlockaidResultType, + SecurityAlertSource, } from '../../../../shared/constants/security-provider'; import { AppStateController } from '../../controllers/app-state'; import { @@ -19,6 +20,7 @@ import { validateRequestWithPPOM, } from './ppom-util'; import { SecurityAlertResponse } from './types'; +import * as securityAlertAPI from './security-alerts-api'; jest.mock('@metamask/transaction-controller', () => ({ ...jest.requireActual('@metamask/transaction-controller'), @@ -27,6 +29,7 @@ jest.mock('@metamask/transaction-controller', () => ({ const SECURITY_ALERT_ID_MOCK = '1234-5678'; const TRANSACTION_ID_MOCK = '123'; +const CHAIN_ID_MOCK = '0x1'; const REQUEST_MOCK = { method: 'eth_signTypedData_v4', @@ -36,6 +39,7 @@ const REQUEST_MOCK = { const SECURITY_ALERT_RESPONSE_MOCK: SecurityAlertResponse = { result_type: 'success', reason: 'success', + source: SecurityAlertSource.Local, }; const TRANSACTION_PARAMS_MOCK_1: TransactionParams = { @@ -95,10 +99,14 @@ describe('PPOM Utils', () => { const normalizeTransactionParamsMock = jest.mocked( normalizeTransactionParams, ); + let isSecurityAlertsEnabledMock: jest.SpyInstance; beforeEach(() => { jest.resetAllMocks(); jest.spyOn(console, 'error').mockImplementation(() => undefined); + isSecurityAlertsEnabledMock = jest + .spyOn(securityAlertAPI, 'isSecurityAlertsAPIEnabled') + .mockReturnValue(false); }); describe('validateRequestWithPPOM', () => { @@ -109,15 +117,14 @@ describe('PPOM Utils', () => { ppom.validateJsonRpc.mockResolvedValue(SECURITY_ALERT_RESPONSE_MOCK); ppomController.usePPOM.mockImplementation( - (callback) => - // eslint-disable-next-line @typescript-eslint/no-explicit-any - callback(ppom as any) as any, + (callback) => callback(ppom as any) as any, ); const response = await validateRequestWithPPOM({ ppomController, request: REQUEST_MOCK, securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ @@ -145,6 +152,7 @@ describe('PPOM Utils', () => { ppomController, request: REQUEST_MOCK, securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ @@ -163,6 +171,7 @@ describe('PPOM Utils', () => { ppomController, request: REQUEST_MOCK, securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ @@ -194,6 +203,7 @@ describe('PPOM Utils', () => { ppomController, request, securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, }); expect(ppom.validateJsonRpc).toHaveBeenCalledTimes(1); @@ -238,8 +248,7 @@ describe('PPOM Utils', () => { securityAlertId: SECURITY_ALERT_ID_MOCK, securityAlertResponse: SECURITY_ALERT_RESPONSE_MOCK, signatureController, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - transactionController: {} as any, + transactionController: {} as unknown as TransactionController, }); expect( @@ -261,7 +270,7 @@ describe('PPOM Utils', () => { }, }, ], - } as any); + } as unknown as TransactionController['state']); await updateSecurityAlertResponse({ appStateController: {} as any, @@ -281,4 +290,65 @@ describe('PPOM Utils', () => { ).toHaveBeenCalledWith(TRANSACTION_ID_MOCK, SECURITY_ALERT_RESPONSE_MOCK); }); }); + + describe('validateWithAPI', () => { + const request = { + ...REQUEST_MOCK, + method: 'eth_sendTransaction', + params: [TRANSACTION_PARAMS_MOCK_1], + }; + + it('uses security alerts API if enabled', async () => { + isSecurityAlertsEnabledMock.mockReturnValue(true); + normalizeTransactionParamsMock.mockReturnValue(TRANSACTION_PARAMS_MOCK_1); + const validateWithSecurityAlertsAPIMock = jest + .spyOn(securityAlertAPI, 'validateWithSecurityAlertsAPI') + .mockResolvedValue(SECURITY_ALERT_RESPONSE_MOCK); + + const ppom = createPPOMMock(); + const ppomController = createPPOMControllerMock(); + + await validateRequestWithPPOM({ + ppomController, + request, + securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, + }); + + expect(ppomController.usePPOM).not.toHaveBeenCalled(); + expect(ppom.validateJsonRpc).not.toHaveBeenCalled(); + + expect(validateWithSecurityAlertsAPIMock).toHaveBeenCalledTimes(1); + expect(validateWithSecurityAlertsAPIMock).toHaveBeenCalledWith( + CHAIN_ID_MOCK, + request, + ); + }); + + it('uses controller if security alerts API throws', async () => { + isSecurityAlertsEnabledMock.mockReturnValue(true); + normalizeTransactionParamsMock.mockReturnValue(TRANSACTION_PARAMS_MOCK_1); + + const ppomController = createPPOMControllerMock(); + + const validateWithSecurityAlertsAPIMock = jest + .spyOn(securityAlertAPI, 'validateWithSecurityAlertsAPI') + .mockRejectedValue(new Error('Test Error')); + + await validateRequestWithPPOM({ + ppomController, + request, + securityAlertId: SECURITY_ALERT_ID_MOCK, + chainId: CHAIN_ID_MOCK, + }); + + expect(ppomController.usePPOM).toHaveBeenCalledTimes(1); + + expect(validateWithSecurityAlertsAPIMock).toHaveBeenCalledTimes(1); + expect(validateWithSecurityAlertsAPIMock).toHaveBeenCalledWith( + CHAIN_ID_MOCK, + request, + ); + }); + }); }); diff --git a/app/scripts/lib/ppom/ppom-util.ts b/app/scripts/lib/ppom/ppom-util.ts index 8d64aacd3a91..a890d1c0f6be 100644 --- a/app/scripts/lib/ppom/ppom-util.ts +++ b/app/scripts/lib/ppom/ppom-util.ts @@ -4,17 +4,22 @@ import { TransactionParams, normalizeTransactionParams, } from '@metamask/transaction-controller'; -import { JsonRpcRequest } from '@metamask/utils'; +import { Hex, JsonRpcRequest } from '@metamask/utils'; import { v4 as uuid } from 'uuid'; import { PPOM } from '@blockaid/ppom_release'; import { SignatureController } from '@metamask/signature-controller'; import { BlockaidReason, BlockaidResultType, + SecurityAlertSource, } from '../../../../shared/constants/security-provider'; import { SIGNING_METHODS } from '../../../../shared/constants/transaction'; import { AppStateController } from '../../controllers/app-state'; import { SecurityAlertResponse } from './types'; +import { + isSecurityAlertsAPIEnabled, + validateWithSecurityAlertsAPI, +} from './security-alerts-api'; const { sentry } = global; @@ -29,17 +34,26 @@ export async function validateRequestWithPPOM({ ppomController, request, securityAlertId, + chainId, }: { ppomController: PPOMController; request: JsonRpcRequest; securityAlertId: string; + chainId: Hex; }): Promise { try { - return await ppomController.usePPOM(async (ppom: PPOM) => { - return await usePPOM(request, securityAlertId, ppom); - }); - } catch (error) { - return handlePPOMError(error, 'Error validateRequestWithPPOM#usePPOM: '); + const normalizedRequest = normalizePPOMRequest(request); + + const ppomResponse = isSecurityAlertsAPIEnabled() + ? await validateWithAPI(ppomController, chainId, normalizedRequest) + : await validateWithController(ppomController, normalizedRequest); + + return { + ...ppomResponse, + securityAlertId, + }; + } catch (error: unknown) { + return handlePPOMError(error, 'Error validating JSON RPC using PPOM: '); } } @@ -97,24 +111,6 @@ export function handlePPOMError( }; } -async function usePPOM( - request: JsonRpcRequest, - securityAlertId: string, - ppom: PPOM, -): Promise { - try { - const normalizedRequest = normalizePPOMRequest(request); - const ppomResponse = await ppom.validateJsonRpc(normalizedRequest); - - return { - ...ppomResponse, - securityAlertId, - }; - } catch (error: unknown) { - return handlePPOMError(error, 'Error validating JSON RPC using PPOM: '); - } -} - function normalizePPOMRequest(request: JsonRpcRequest): JsonRpcRequest { if (request.method !== METHOD_SEND_TRANSACTION) { return request; @@ -178,3 +174,35 @@ async function findConfirmationBySecurityAlertId( await new Promise((resolve) => setTimeout(resolve, 100)); } } + +async function validateWithController( + ppomController: PPOMController, + request: JsonRpcRequest, +): Promise { + const response = (await ppomController.usePPOM((ppom: PPOM) => + ppom.validateJsonRpc(request), + )) as SecurityAlertResponse; + + return { + ...response, + source: SecurityAlertSource.Local, + }; +} + +async function validateWithAPI( + ppomController: PPOMController, + chainId: string, + request: JsonRpcRequest, +): Promise { + try { + const response = await validateWithSecurityAlertsAPI(chainId, request); + + return { + ...response, + source: SecurityAlertSource.API, + }; + } catch (error: unknown) { + handlePPOMError(error, `Error validating request with security alerts API`); + return await validateWithController(ppomController, request); + } +} diff --git a/app/scripts/lib/ppom/security-alerts-api.test.ts b/app/scripts/lib/ppom/security-alerts-api.test.ts new file mode 100644 index 000000000000..08915633a01a --- /dev/null +++ b/app/scripts/lib/ppom/security-alerts-api.test.ts @@ -0,0 +1,89 @@ +import { + BlockaidReason, + BlockaidResultType, +} from '../../../../shared/constants/security-provider'; +import { + isSecurityAlertsAPIEnabled, + validateWithSecurityAlertsAPI, +} from './security-alerts-api'; + +const CHAIN_ID_MOCK = '0x1'; + +const REQUEST_MOCK = { + method: 'eth_sendTransaction', + params: [ + { + from: '0x123', + to: '0x456', + value: '0x123', + }, + ], +}; + +const RESPONSE_MOCK = { + result_type: BlockaidResultType.Errored, + reason: BlockaidReason.maliciousDomain, + description: 'Test Description', +}; + +describe('Security Alerts API', () => { + const fetchMock = jest.fn(); + + beforeEach(() => { + jest.resetAllMocks(); + + global.fetch = fetchMock; + + fetchMock.mockResolvedValue({ + ok: true, + json: async () => RESPONSE_MOCK, + }); + + process.env.SECURITY_ALERTS_API_URL = 'https://example.com'; + }); + + describe('validateWithSecurityAlertsAPI', () => { + it('sends POST request', async () => { + const response = await validateWithSecurityAlertsAPI( + CHAIN_ID_MOCK, + REQUEST_MOCK, + ); + + expect(response).toEqual(RESPONSE_MOCK); + + expect(fetchMock).toHaveBeenCalledTimes(1); + expect(fetchMock).toHaveBeenCalledWith( + `https://example.com/validate/${CHAIN_ID_MOCK}`, + expect.any(Object), + ); + }); + + it('throws an error if response is not ok', async () => { + fetchMock.mockResolvedValue({ ok: false, status: 567 }); + + const responsePromise = validateWithSecurityAlertsAPI( + CHAIN_ID_MOCK, + REQUEST_MOCK, + ); + + await expect(responsePromise).rejects.toThrow( + 'Security alerts API request failed with status: 567', + ); + }); + + it('throws an error if SECURITY_ALERTS_API_URL is not set', async () => { + delete process.env.SECURITY_ALERTS_API_URL; + + await expect( + validateWithSecurityAlertsAPI(CHAIN_ID_MOCK, REQUEST_MOCK), + ).rejects.toThrow('Security alerts API URL is not set'); + }); + + it('throws an error if SECURITY_ALERTS_API_ENABLED is false', () => { + process.env.SECURITY_ALERTS_API_ENABLED = 'false'; + + const isEnabled = isSecurityAlertsAPIEnabled(); + expect(isEnabled).toBe(false); + }); + }); +}); diff --git a/app/scripts/lib/ppom/security-alerts-api.ts b/app/scripts/lib/ppom/security-alerts-api.ts new file mode 100644 index 000000000000..eb706975c19c --- /dev/null +++ b/app/scripts/lib/ppom/security-alerts-api.ts @@ -0,0 +1,51 @@ +import { SecurityAlertResponse } from './types'; + +const ENDPOINT_VALIDATE = 'validate'; + +export type SecurityAlertsAPIRequest = { + method: string; + params: unknown[]; +}; + +export function isSecurityAlertsAPIEnabled() { + const isEnabled = process.env.SECURITY_ALERTS_API_ENABLED; + return isEnabled?.toString() === 'true'; +} + +export async function validateWithSecurityAlertsAPI( + chainId: string, + request: SecurityAlertsAPIRequest, +): Promise { + const endpoint = `${ENDPOINT_VALIDATE}/${chainId}`; + return postRequest(endpoint, request); +} + +async function postRequest(endpoint: string, body: unknown) { + const url = getUrl(endpoint); + + const response = await fetch(url, { + method: 'POST', + body: JSON.stringify(body), + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error( + `Security alerts API request failed with status: ${response.status}`, + ); + } + + return response.json(); +} + +function getUrl(endpoint: string) { + const host = process.env.SECURITY_ALERTS_API_URL; + + if (!host) { + throw new Error('Security alerts API URL is not set'); + } + + return `${host}/${endpoint}`; +} diff --git a/app/scripts/lib/ppom/types.ts b/app/scripts/lib/ppom/types.ts index 8dc272edbf24..6532b7693236 100644 --- a/app/scripts/lib/ppom/types.ts +++ b/app/scripts/lib/ppom/types.ts @@ -1,3 +1,5 @@ +import { SecurityAlertSource } from '../../../../shared/constants/security-provider'; + export type SecurityAlertResponse = { description?: string; features?: string[]; @@ -5,4 +7,5 @@ export type SecurityAlertResponse = { reason: string; result_type: string; securityAlertId?: string; + source?: SecurityAlertSource; }; diff --git a/app/scripts/lib/transaction/util.ts b/app/scripts/lib/transaction/util.ts index d62ea2af02f3..d7755cff6fc2 100644 --- a/app/scripts/lib/transaction/util.ts +++ b/app/scripts/lib/transaction/util.ts @@ -264,6 +264,7 @@ function validateSecurity(request: AddTransactionRequest) { ppomController, request: ppomRequest, securityAlertId, + chainId, }).then((securityAlertResponse) => { updateSecurityAlertResponse( ppomRequest.method, diff --git a/builds.yml b/builds.yml index 0e83d86303b0..0e5a69dd86d0 100644 --- a/builds.yml +++ b/builds.yml @@ -263,6 +263,10 @@ env: - TEST_GAS_FEE_FLOWS: false # Determines if feature flagged network ui new design - ENABLE_NETWORK_UI_REDESIGN: '' + # Temporary mechanism to enable security alerts API prior to release + - SECURITY_ALERTS_API_ENABLED: '' + # URL of security alerts API used to validate dApp requests + - SECURITY_ALERTS_API_URL: 'http://localhost:3000' # Enables the notifications feature within the build: - NOTIFICATIONS: '' diff --git a/shared/constants/security-provider.ts b/shared/constants/security-provider.ts index a53dd7caba78..e6fff53ee28a 100644 --- a/shared/constants/security-provider.ts +++ b/shared/constants/security-provider.ts @@ -14,7 +14,7 @@ type SecurityProviderConfig = Record< { /** translation key for security provider name */ readonly tKeyName: string; - /** URL to securty provider website */ + /** URL to security provider website */ readonly url: string; } >; @@ -116,3 +116,11 @@ export const LOADING_SECURITY_ALERT_RESPONSE: SecurityAlertResponse = { result_type: BlockaidResultType.Loading, reason: BlockaidReason.inProgress, }; + +export enum SecurityAlertSource { + /** Validation performed remotely using the Security Alerts API. */ + API = 'api', + + /** Validation performed locally using the PPOM. */ + Local = 'local', +} diff --git a/ui/helpers/utils/metrics.js b/ui/helpers/utils/metrics.js index a890d8f06f73..7e66f88d6857 100644 --- a/ui/helpers/utils/metrics.js +++ b/ui/helpers/utils/metrics.js @@ -58,6 +58,7 @@ export const getBlockaidMetricsProps = ({ securityAlertResponse }) => { reason, result_type: resultType, description, + source, } = securityAlertResponse; const uiCustomization = getBlockaidMetricUiCustomization(resultType); @@ -76,6 +77,8 @@ export const getBlockaidMetricsProps = ({ securityAlertResponse }) => { params.security_alert_response = resultType ?? BlockaidResultType.NotApplicable; + params.security_alert_source = source; + // add counts of each RPC call if (providerRequestsCount) { Object.keys(providerRequestsCount).forEach((key) => { diff --git a/ui/helpers/utils/metrics.test.js b/ui/helpers/utils/metrics.test.js index d1a2f1a5d72e..db5bec5143b8 100644 --- a/ui/helpers/utils/metrics.test.js +++ b/ui/helpers/utils/metrics.test.js @@ -1,6 +1,8 @@ +import { MetaMetricsEventUiCustomization } from '../../../shared/constants/metametrics'; import { BlockaidReason, BlockaidResultType, + SecurityAlertSource, } from '../../../shared/constants/security-provider'; import { getBlockaidMetricsProps, getMethodName } from './metrics'; @@ -20,6 +22,14 @@ const securityAlertResponse = { result_type: BlockaidResultType.Malicious, reason: BlockaidReason.setApprovalForAll, features: [], + source: SecurityAlertSource.Local, +}; + +const expectedMetricsPropsBase = { + security_alert_reason: BlockaidReason.setApprovalForAll, + security_alert_response: BlockaidResultType.Malicious, + security_alert_source: SecurityAlertSource.Local, + ui_customizations: [MetaMetricsEventUiCustomization.FlaggedAsMalicious], }; describe('getBlockaidMetricsProps', () => { @@ -32,11 +42,7 @@ describe('getBlockaidMetricsProps', () => { const result = getBlockaidMetricsProps({ securityAlertResponse, }); - expect(result).toStrictEqual({ - security_alert_reason: BlockaidReason.setApprovalForAll, - security_alert_response: BlockaidResultType.Malicious, - ui_customizations: ['flagged_as_malicious'], - }); + expect(result).toStrictEqual(expectedMetricsPropsBase); }); it('includes not applicable reason or result type when they are not provided', () => { @@ -63,9 +69,9 @@ describe('getBlockaidMetricsProps', () => { }); expect(result).toStrictEqual({ - security_alert_reason: BlockaidReason.setApprovalForAll, + ...expectedMetricsPropsBase, security_alert_response: BlockaidResultType.Errored, - ui_customizations: ['security_alert_error'], + ui_customizations: [MetaMetricsEventUiCustomization.SecurityAlertError], }); }); @@ -77,11 +83,7 @@ describe('getBlockaidMetricsProps', () => { }, }); - expect(result).toStrictEqual({ - security_alert_reason: BlockaidReason.setApprovalForAll, - security_alert_response: BlockaidResultType.Malicious, - ui_customizations: ['flagged_as_malicious'], - }); + expect(result).toStrictEqual(expectedMetricsPropsBase); }); it('includes "flagged_as_warning" ui_customization when type is a warning', () => { @@ -92,11 +94,7 @@ describe('getBlockaidMetricsProps', () => { }, }); - expect(result).toStrictEqual({ - security_alert_reason: BlockaidReason.setApprovalForAll, - security_alert_response: BlockaidResultType.Malicious, - ui_customizations: ['flagged_as_malicious'], - }); + expect(result).toStrictEqual(expectedMetricsPropsBase); }); it('excludes reason when type is benign', () => { @@ -109,6 +107,7 @@ describe('getBlockaidMetricsProps', () => { expect(result).toStrictEqual({ security_alert_response: BlockaidResultType.Benign, + security_alert_source: SecurityAlertSource.Local, }); }); @@ -124,11 +123,9 @@ describe('getBlockaidMetricsProps', () => { }); expect(result).toStrictEqual({ + ...expectedMetricsPropsBase, ppom_eth_call_count: 5, ppom_eth_getCode_count: 3, - ui_customizations: ['flagged_as_malicious'], - security_alert_response: BlockaidResultType.Malicious, - security_alert_reason: BlockaidReason.setApprovalForAll, }); }); @@ -141,9 +138,10 @@ describe('getBlockaidMetricsProps', () => { }, }); expect(result).toStrictEqual({ - ui_customizations: ['security_alert_error'], + ui_customizations: [MetaMetricsEventUiCustomization.SecurityAlertError], security_alert_response: BlockaidResultType.Errored, security_alert_reason: 'error: error message', + security_alert_source: SecurityAlertSource.Local, }); }); @@ -155,11 +153,7 @@ describe('getBlockaidMetricsProps', () => { }, }); - expect(result).toStrictEqual({ - ui_customizations: ['flagged_as_malicious'], - security_alert_response: BlockaidResultType.Malicious, - security_alert_reason: BlockaidReason.setApprovalForAll, - }); + expect(result).toStrictEqual(expectedMetricsPropsBase); }); it('excludes eth call counts if providerRequestsCount is undefined', () => { @@ -170,10 +164,20 @@ describe('getBlockaidMetricsProps', () => { }, }); + expect(result).toStrictEqual(expectedMetricsPropsBase); + }); + + it('includes the API source when the security alert originates from the API', () => { + const result = getBlockaidMetricsProps({ + securityAlertResponse: { + ...securityAlertResponse, + source: SecurityAlertSource.API, + }, + }); + expect(result).toStrictEqual({ - ui_customizations: ['flagged_as_malicious'], - security_alert_response: BlockaidResultType.Malicious, - security_alert_reason: BlockaidReason.setApprovalForAll, + ...expectedMetricsPropsBase, + security_alert_source: SecurityAlertSource.API, }); }); }); diff --git a/ui/pages/confirmations/components/confirm/blockaid-loading-indicator/blockaid-loading-indicator.test.tsx b/ui/pages/confirmations/components/confirm/blockaid-loading-indicator/blockaid-loading-indicator.test.tsx index 5be896e98827..d370b263427c 100644 --- a/ui/pages/confirmations/components/confirm/blockaid-loading-indicator/blockaid-loading-indicator.test.tsx +++ b/ui/pages/confirmations/components/confirm/blockaid-loading-indicator/blockaid-loading-indicator.test.tsx @@ -8,8 +8,8 @@ import { import mockState from '../../../../../../test/data/mock-state.json'; import { BlockaidResultType } from '../../../../../../shared/constants/security-provider'; import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; -import { SecurityAlertResponse } from '../../../types/confirm'; +import { SecurityAlertResponse } from '../../../types/confirm'; import BlockaidLoadingIndicator from './blockaid-loading-indicator'; const mockSecurityAlertResponse: SecurityAlertResponse = { diff --git a/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.test.ts b/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.test.ts index 73833278fa7d..b5877cba103d 100644 --- a/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.test.ts +++ b/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.test.ts @@ -1,5 +1,4 @@ import { ApprovalType } from '@metamask/controller-utils'; -import { SecurityAlertResponse } from '../../types/confirm'; import { BlockaidResultType, SecurityProvider, @@ -7,6 +6,7 @@ import { import { Severity } from '../../../../helpers/constants/design-system'; import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; import mockState from '../../../../../test/data/mock-state.json'; +import { SecurityAlertResponse } from '../../types/confirm'; import useBlockaidAlert from './useBlockaidAlerts'; const mockSecurityAlertResponse: SecurityAlertResponse = { diff --git a/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.ts b/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.ts index ae87e60d64f6..98b93bd1021a 100644 --- a/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.ts +++ b/ui/pages/confirmations/hooks/alerts/useBlockaidAlerts.ts @@ -8,7 +8,6 @@ import { import { BlockaidResultType } from '../../../../../shared/constants/security-provider'; import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts'; import { useI18nContext } from '../../../../hooks/useI18nContext'; -import { SecurityAlertResponse } from '../../types/confirm'; import { REDESIGN_TRANSACTION_TYPES, SIGNATURE_TRANSACTION_TYPES, @@ -17,6 +16,7 @@ import { currentConfirmationSelector, currentSignatureRequestSecurityResponseSelector, } from '../../selectors'; +import { SecurityAlertResponse } from '../../types/confirm'; import { normalizeProviderAlert } from './utils'; const SUPPORTED_TRANSACTION_TYPES = [ diff --git a/ui/pages/confirmations/hooks/alerts/utils.test.ts b/ui/pages/confirmations/hooks/alerts/utils.test.ts index 292adc5ed142..6f14f04800c6 100644 --- a/ui/pages/confirmations/hooks/alerts/utils.test.ts +++ b/ui/pages/confirmations/hooks/alerts/utils.test.ts @@ -1,6 +1,6 @@ -import { SecurityAlertResponse } from '../../types/confirm'; import { BlockaidResultType } from '../../../../../shared/constants/security-provider'; import { Severity } from '../../../../helpers/constants/design-system'; +import { SecurityAlertResponse } from '../../types/confirm'; import { getProviderAlertSeverity, normalizeProviderAlert } from './utils'; describe('Utils', () => { diff --git a/ui/pages/confirmations/hooks/alerts/utils.ts b/ui/pages/confirmations/hooks/alerts/utils.ts index 6c88008a2a7c..a3a9922ab90e 100644 --- a/ui/pages/confirmations/hooks/alerts/utils.ts +++ b/ui/pages/confirmations/hooks/alerts/utils.ts @@ -1,4 +1,3 @@ -import { SecurityAlertResponse } from '../../types/confirm'; import { BlockaidResultType, SecurityProvider, @@ -13,6 +12,7 @@ import { REASON_TO_DESCRIPTION_TKEY, REASON_TO_TITLE_TKEY, } from '../../components/security-provider-banner-alert/blockaid-banner-alert/blockaid-banner-alert'; +import { SecurityAlertResponse } from '../../types/confirm'; /** * Returns the corresponding AlertSeverity based on the provided BlockaidResultType. diff --git a/ui/pages/confirmations/types/confirm.ts b/ui/pages/confirmations/types/confirm.ts index 36a1b6a31397..b3a99aa09362 100644 --- a/ui/pages/confirmations/types/confirm.ts +++ b/ui/pages/confirmations/types/confirm.ts @@ -5,6 +5,7 @@ import { TransactionMeta, TransactionType, } from '@metamask/transaction-controller'; +import { SecurityAlertSource } from '../../../../shared/constants/security-provider'; export type TypedSignDataV1Type = { name: string; @@ -18,6 +19,7 @@ export type SecurityAlertResponse = { result_type: string; providerRequestsCount?: Record; securityAlertId?: string; + source?: SecurityAlertSource; }; export type SignatureRequestType = {