From 0351309227181e9ab4382d7a66910bbcebfabd6b Mon Sep 17 00:00:00 2001 From: Filip Sekulic Date: Thu, 23 Mar 2023 18:01:51 +0100 Subject: [PATCH] OpenSea security provider metrics (#17688) * Added metrics for the OpenSea security provider * Fixed tests * Fixed a test * Fixed metrics * Code refactor * Lint fixed * Removed unnecessary code * Fix build * Fix e2e * Cleanup * Fix e2e * Code refactor * Removed unnecessary code * rpc middleware: catch securityProviderCheck errors to not block dapp rpc requests * Fixed an issue * Added aditional test * Applied some changes * Fixed a test * Fixed a test * Code refactor * Covered more code with tests * Updated a test * Fixed an issue --------- Co-authored-by: Jyoti Puri Co-authored-by: digiwand <20778143+digiwand@users.noreply.github.com> Co-authored-by: Brad Decker --- app/scripts/controllers/metametrics.js | 3 + app/scripts/controllers/metametrics.test.js | 2 + app/scripts/controllers/transactions/index.js | 12 ++ .../controllers/transactions/index.test.js | 170 ++++++++++++++++++ .../lib/createRPCMethodTrackingMiddleware.js | 132 +++++++++++--- .../createRPCMethodTrackingMiddleware.test.js | 122 ++++++++++++- app/scripts/lib/security-provider-helpers.js | 12 +- app/scripts/metamask-controller.js | 9 +- shared/constants/metametrics.js | 4 + test/e2e/tests/eth-sign.spec.js | 2 +- 10 files changed, 426 insertions(+), 42 deletions(-) diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index f9266a540..a949f3cc7 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -721,6 +721,9 @@ export default class MetaMetricsController { ///: BEGIN:ONLY_INCLUDE_IN(flask) [TRAITS.DESKTOP_ENABLED]: metamaskState.desktopEnabled || false, ///: END:ONLY_INCLUDE_IN + [TRAITS.SECURITY_PROVIDERS]: metamaskState.transactionSecurityCheckEnabled + ? ['opensea'] + : [], }; if (!previousUserTraits) { diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index 494d4f763..f3969a7b3 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -952,6 +952,7 @@ describe('MetaMetricsController', function () { theme: 'default', useTokenDetection: true, desktopEnabled: false, + security_providers: [], }); assert.deepEqual(traits, { @@ -970,6 +971,7 @@ describe('MetaMetricsController', function () { [TRAITS.THEME]: 'default', [TRAITS.TOKEN_DETECTION_ENABLED]: true, [TRAITS.DESKTOP_ENABLED]: false, + [TRAITS.SECURITY_PROVIDERS]: [], }); }); diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 32f405617..112071ffd 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -2147,6 +2147,7 @@ export default class TransactionController extends EventEmitter { originalApprovalAmount, finalApprovalAmount, contractMethodName, + securityProviderResponse, } = txMeta; const source = referrer === ORIGIN_METAMASK ? 'user' : 'dapp'; @@ -2298,6 +2299,16 @@ export default class TransactionController extends EventEmitter { } } + let uiCustomizations; + + if (securityProviderResponse?.flagAsDangerous === 1) { + uiCustomizations = ['flagged_as_malicious']; + } else if (securityProviderResponse?.flagAsDangerous === 2) { + uiCustomizations = ['flagged_as_safety_unknown']; + } else { + uiCustomizations = null; + } + let properties = { chain_id: chainId, referrer, @@ -2312,6 +2323,7 @@ export default class TransactionController extends EventEmitter { token_standard: tokenStandard, transaction_type: transactionType, transaction_speed_up: type === TransactionType.retry, + ui_customizations: uiCustomizations, }; if (transactionContractMethod === contractMethodNames.APPROVE) { diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 7cf1f5a01..096783fae 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -1740,6 +1740,9 @@ describe('Transaction Controller', function () { gas: '0x7b0d', gasPrice: '0x77359400', }, + securityProviderResponse: { + flagAsDangerous: 0, + }, }; }); @@ -1766,6 +1769,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { default_gas: '0.000031501', @@ -1852,6 +1856,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { default_gas: '0.000031501', @@ -1921,6 +1926,9 @@ describe('Transaction Controller', function () { gas: '0x7b0d', gasPrice: '0x77359400', }, + securityProviderResponse: { + flagAsDangerous: 0, + }, }; }); @@ -1947,6 +1955,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { default_gas: '0.000031501', @@ -2035,6 +2044,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { default_gas: '0.000031501', @@ -2099,6 +2109,9 @@ describe('Transaction Controller', function () { chainId: currentChainId, time: 1624408066355, metamaskNetworkId: currentNetworkId, + securityProviderResponse: { + flagAsDangerous: 0, + }, }; const expectedPayload = { @@ -2122,6 +2135,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { gas_price: '2', @@ -2167,6 +2181,9 @@ describe('Transaction Controller', function () { chainId: currentChainId, time: 1624408066355, metamaskNetworkId: currentNetworkId, + securityProviderResponse: { + flagAsDangerous: 0, + }, }; const expectedPayload = { actionId, @@ -2190,6 +2207,155 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, + }, + sensitiveProperties: { + baz: 3.0, + foo: 'bar', + gas_price: '2', + gas_limit: '0x7b0d', + transaction_contract_method: undefined, + transaction_replaced: undefined, + first_seen: 1624408066355, + transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY, + status: 'unapproved', + }, + }; + + await txController._trackTransactionMetricsEvent( + txMeta, + TransactionMetaMetricsEvent.added, + actionId, + { + baz: 3.0, + foo: 'bar', + }, + ); + assert.equal(createEventFragmentSpy.callCount, 1); + assert.equal(finalizeEventFragmentSpy.callCount, 0); + assert.deepEqual( + createEventFragmentSpy.getCall(0).args[0], + expectedPayload, + ); + }); + + it('should call _trackMetaMetricsEvent with the correct payload (extra params) when flagAsDangerous is malicious', async function () { + const txMeta = { + id: 1, + status: TransactionStatus.unapproved, + txParams: { + from: fromAccount.address, + to: '0x1678a085c290ebd122dc42cba69373b5953b831d', + gasPrice: '0x77359400', + gas: '0x7b0d', + nonce: '0x4b', + }, + type: TransactionType.simpleSend, + origin: 'other', + chainId: currentChainId, + time: 1624408066355, + metamaskNetworkId: currentNetworkId, + securityProviderResponse: { + flagAsDangerous: 1, + }, + }; + const expectedPayload = { + actionId, + initialEvent: 'Transaction Added', + successEvent: 'Transaction Approved', + failureEvent: 'Transaction Rejected', + uniqueIdentifier: 'transaction-added-1', + persist: true, + category: EVENT.CATEGORIES.TRANSACTIONS, + properties: { + network: '5', + referrer: 'other', + source: EVENT.SOURCE.TRANSACTION.DAPP, + transaction_type: TransactionType.simpleSend, + chain_id: '0x5', + eip_1559_version: '0', + gas_edit_attempted: 'none', + gas_edit_type: 'none', + account_type: 'MetaMask', + asset_type: AssetType.native, + token_standard: TokenStandard.none, + device_model: 'N/A', + transaction_speed_up: false, + ui_customizations: ['flagged_as_malicious'], + }, + sensitiveProperties: { + baz: 3.0, + foo: 'bar', + gas_price: '2', + gas_limit: '0x7b0d', + transaction_contract_method: undefined, + transaction_replaced: undefined, + first_seen: 1624408066355, + transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY, + status: 'unapproved', + }, + }; + + await txController._trackTransactionMetricsEvent( + txMeta, + TransactionMetaMetricsEvent.added, + actionId, + { + baz: 3.0, + foo: 'bar', + }, + ); + assert.equal(createEventFragmentSpy.callCount, 1); + assert.equal(finalizeEventFragmentSpy.callCount, 0); + assert.deepEqual( + createEventFragmentSpy.getCall(0).args[0], + expectedPayload, + ); + }); + + it('should call _trackMetaMetricsEvent with the correct payload (extra params) when flagAsDangerous is unknown', async function () { + const txMeta = { + id: 1, + status: TransactionStatus.unapproved, + txParams: { + from: fromAccount.address, + to: '0x1678a085c290ebd122dc42cba69373b5953b831d', + gasPrice: '0x77359400', + gas: '0x7b0d', + nonce: '0x4b', + }, + type: TransactionType.simpleSend, + origin: 'other', + chainId: currentChainId, + time: 1624408066355, + metamaskNetworkId: currentNetworkId, + securityProviderResponse: { + flagAsDangerous: 2, + }, + }; + const expectedPayload = { + actionId, + initialEvent: 'Transaction Added', + successEvent: 'Transaction Approved', + failureEvent: 'Transaction Rejected', + uniqueIdentifier: 'transaction-added-1', + persist: true, + category: EVENT.CATEGORIES.TRANSACTIONS, + properties: { + network: '5', + referrer: 'other', + source: EVENT.SOURCE.TRANSACTION.DAPP, + transaction_type: TransactionType.simpleSend, + chain_id: '0x5', + eip_1559_version: '0', + gas_edit_attempted: 'none', + gas_edit_type: 'none', + account_type: 'MetaMask', + asset_type: AssetType.native, + token_standard: TokenStandard.none, + device_model: 'N/A', + transaction_speed_up: false, + ui_customizations: ['flagged_as_safety_unknown'], }, sensitiveProperties: { baz: 3.0, @@ -2245,6 +2411,9 @@ describe('Transaction Controller', function () { maxFeePerGas: '0x77359400', maxPriorityFeePerGas: '0x77359400', }, + securityProviderResponse: { + flagAsDangerous: 0, + }, }; const expectedPayload = { actionId, @@ -2268,6 +2437,7 @@ describe('Transaction Controller', function () { token_standard: TokenStandard.none, device_model: 'N/A', transaction_speed_up: false, + ui_customizations: null, }, sensitiveProperties: { baz: 3.0, diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.js index e1376ae1e..8a5186d42 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.js @@ -107,14 +107,16 @@ const rateLimitTimeouts = {}; * MetaMetricsController * @param {number} [opts.rateLimitSeconds] - number of seconds to wait before * allowing another set of events to be tracked. + * @param opts.securityProviderRequest * @returns {Function} */ export default function createRPCMethodTrackingMiddleware({ trackEvent, getMetricsState, rateLimitSeconds = 60 * 5, + securityProviderRequest, }) { - return function rpcMethodTrackingMiddleware( + return async function rpcMethodTrackingMiddleware( /** @type {any} */ req, /** @type {any} */ res, /** @type {Function} */ next, @@ -162,22 +164,65 @@ export default function createRPCMethodTrackingMiddleware({ const properties = {}; + let msgParams; + if (event === EVENT_NAMES.SIGNATURE_REQUESTED) { properties.signature_type = method; + + const data = req?.params?.[0]; + const from = req?.params?.[1]; + const paramsExamplePassword = req?.params?.[2]; + + msgParams = { + ...paramsExamplePassword, + from, + data, + origin, + }; + + const msgData = { + msgParams, + status: 'unapproved', + type: req.method, + }; + + try { + const securityProviderResponse = await securityProviderRequest( + msgData, + req.method, + ); + + if (securityProviderResponse?.flagAsDangerous === 1) { + properties.ui_customizations = ['flagged_as_malicious']; + } else if (securityProviderResponse?.flagAsDangerous === 2) { + properties.ui_customizations = ['flagged_as_safety_unknown']; + } else { + properties.ui_customizations = null; + } + + if (method === MESSAGE_TYPE.PERSONAL_SIGN) { + const { isSIWEMessage } = detectSIWE({ data }); + if (isSIWEMessage) { + properties.ui_customizations === null + ? (properties.ui_customizations = [ + METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS] + .SIWE, + ]) + : properties.ui_customizations.push( + METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS] + .SIWE, + ); + } + } + } catch (e) { + console.warn( + `createRPCMethodTrackingMiddleware: Error calling securityProviderRequest - ${e}`, + ); + } } else { properties.method = method; } - if (method === MESSAGE_TYPE.PERSONAL_SIGN) { - const data = req?.params?.[0]; - const { isSIWEMessage } = detectSIWE({ data }); - if (isSIWEMessage) { - properties.ui_customizations = [ - METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS].SIWE, - ]; - } - } - trackEvent({ event, category: EVENT.CATEGORIES.INPAGE_PROVIDER, @@ -192,7 +237,7 @@ export default function createRPCMethodTrackingMiddleware({ }, SECOND * rateLimitSeconds); } - next((callback) => { + next(async (callback) => { if (shouldTrackEvent === false || typeof eventType === 'undefined') { return callback(); } @@ -216,22 +261,65 @@ export default function createRPCMethodTrackingMiddleware({ event = eventType.APPROVED; } + let msgParams; + if (eventType.REQUESTED === EVENT_NAMES.SIGNATURE_REQUESTED) { properties.signature_type = method; + + const data = req?.params?.[0]; + const from = req?.params?.[1]; + const paramsExamplePassword = req?.params?.[2]; + + msgParams = { + ...paramsExamplePassword, + from, + data, + origin, + }; + + const msgData = { + msgParams, + status: 'unapproved', + type: req.method, + }; + + try { + const securityProviderResponse = await securityProviderRequest( + msgData, + req.method, + ); + + if (securityProviderResponse?.flagAsDangerous === 1) { + properties.ui_customizations = ['flagged_as_malicious']; + } else if (securityProviderResponse?.flagAsDangerous === 2) { + properties.ui_customizations = ['flagged_as_safety_unknown']; + } else { + properties.ui_customizations = null; + } + + if (method === MESSAGE_TYPE.PERSONAL_SIGN) { + const { isSIWEMessage } = detectSIWE({ data }); + if (isSIWEMessage) { + properties.ui_customizations === null + ? (properties.ui_customizations = [ + METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS] + .SIWE, + ]) + : properties.ui_customizations.push( + METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS] + .SIWE, + ); + } + } + } catch (e) { + console.warn( + `createRPCMethodTrackingMiddleware: Error calling securityProviderRequest - ${e}`, + ); + } } else { properties.method = method; } - if (method === MESSAGE_TYPE.PERSONAL_SIGN) { - const data = req?.params?.[0]; - const { isSIWEMessage } = detectSIWE({ data }); - if (isSIWEMessage) { - properties.ui_customizations = [ - METAMETRIC_KEY_OPTIONS[METAMETRIC_KEY.UI_CUSTOMIZATIONS].SIWE, - ]; - } - } - trackEvent({ event, category: EVENT.CATEGORIES.INPAGE_PROVIDER, diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js index 9a9f72157..af910279e 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js @@ -8,10 +8,19 @@ const trackEvent = jest.fn(); const metricsState = { participateInMetaMetrics: null }; const getMetricsState = () => metricsState; +let flagAsDangerous = 0; + +const securityProviderRequest = () => { + return { + flagAsDangerous, + }; +}; + const handler = createRPCMethodTrackingMiddleware({ trackEvent, getMetricsState, rateLimitSeconds: 1, + securityProviderRequest, }); function getNext(timeout = 500) { @@ -92,7 +101,7 @@ describe('createRPCMethodTrackingMiddleware', () => { metricsState.participateInMetaMetrics = true; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, () => { + it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -102,12 +111,14 @@ describe('createRPCMethodTrackingMiddleware', () => { error: null, }; const { next } = getNext(); - handler(req, res, next); + await handler(req, res, next); expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', event: EVENT_NAMES.SIGNATURE_REQUESTED, - properties: { signature_type: MESSAGE_TYPE.ETH_SIGN }, + properties: { + signature_type: MESSAGE_TYPE.ETH_SIGN, + }, referrer: { url: 'some.dapp' }, }); }); @@ -122,13 +133,15 @@ describe('createRPCMethodTrackingMiddleware', () => { error: null, }; const { next, executeMiddlewareStack } = getNext(); - handler(req, res, next); + await handler(req, res, next); await executeMiddlewareStack(); expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', event: EVENT_NAMES.SIGNATURE_APPROVED, - properties: { signature_type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4 }, + properties: { + signature_type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4, + }, referrer: { url: 'some.dapp' }, }); }); @@ -143,13 +156,15 @@ describe('createRPCMethodTrackingMiddleware', () => { error: { code: 4001 }, }; const { next, executeMiddlewareStack } = getNext(); - handler(req, res, next); + await handler(req, res, next); await executeMiddlewareStack(); expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', event: EVENT_NAMES.SIGNATURE_REJECTED, - properties: { signature_type: MESSAGE_TYPE.PERSONAL_SIGN }, + properties: { + signature_type: MESSAGE_TYPE.PERSONAL_SIGN, + }, referrer: { url: 'some.dapp' }, }); }); @@ -162,7 +177,7 @@ describe('createRPCMethodTrackingMiddleware', () => { const res = {}; const { next, executeMiddlewareStack } = getNext(); - handler(req, res, next); + await handler(req, res, next); await executeMiddlewareStack(); expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ @@ -227,7 +242,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }; const { next, executeMiddlewareStack } = getNext(); - handler(req, res, next); + await handler(req, res, next); await executeMiddlewareStack(); expect(trackEvent).toHaveBeenCalledTimes(2); @@ -244,4 +259,93 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); }); + + describe('participateInMetaMetrics is set to true with a request flagged as safe', () => { + beforeEach(() => { + metricsState.participateInMetaMetrics = true; + }); + + it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as safe`, async () => { + const req = { + method: MESSAGE_TYPE.ETH_SIGN, + origin: 'some.dapp', + }; + + const res = { + error: null, + }; + const { next } = getNext(); + await handler(req, res, next); + expect(trackEvent).toHaveBeenCalledTimes(1); + expect(trackEvent.mock.calls[0][0]).toMatchObject({ + category: 'inpage_provider', + event: EVENT_NAMES.SIGNATURE_REQUESTED, + properties: { + signature_type: MESSAGE_TYPE.ETH_SIGN, + ui_customizations: null, + }, + referrer: { url: 'some.dapp' }, + }); + }); + }); + + describe('participateInMetaMetrics is set to true with a request flagged as malicious', () => { + beforeEach(() => { + metricsState.participateInMetaMetrics = true; + flagAsDangerous = 1; + }); + + it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as malicious`, async () => { + const req = { + method: MESSAGE_TYPE.ETH_SIGN, + origin: 'some.dapp', + }; + + const res = { + error: null, + }; + const { next } = getNext(); + await handler(req, res, next); + expect(trackEvent).toHaveBeenCalledTimes(1); + expect(trackEvent.mock.calls[0][0]).toMatchObject({ + category: 'inpage_provider', + event: EVENT_NAMES.SIGNATURE_REQUESTED, + properties: { + signature_type: MESSAGE_TYPE.ETH_SIGN, + ui_customizations: ['flagged_as_malicious'], + }, + referrer: { url: 'some.dapp' }, + }); + }); + }); + + describe('participateInMetaMetrics is set to true with a request flagged as safety unknown', () => { + beforeEach(() => { + metricsState.participateInMetaMetrics = true; + flagAsDangerous = 2; + }); + + it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as safety unknown`, async () => { + const req = { + method: MESSAGE_TYPE.ETH_SIGN, + origin: 'some.dapp', + }; + + const res = { + error: null, + }; + const { next } = getNext(); + await handler(req, res, next); + expect(trackEvent).toHaveBeenCalledTimes(1); + expect(trackEvent.mock.calls[0][0]).toMatchObject({ + category: 'inpage_provider', + event: EVENT_NAMES.SIGNATURE_REQUESTED, + properties: { + signature_type: MESSAGE_TYPE.ETH_SIGN, + ui_customizations: ['flagged_as_safety_unknown'], + }, + referrer: { url: 'some.dapp' }, + }); + }); + }); }); diff --git a/app/scripts/lib/security-provider-helpers.js b/app/scripts/lib/security-provider-helpers.js index db66c462d..b05c9a40b 100644 --- a/app/scripts/lib/security-provider-helpers.js +++ b/app/scripts/lib/security-provider-helpers.js @@ -39,12 +39,12 @@ export async function securityProviderCheck( rpc_method_name: methodName, chain_id: chainId, data: { - from_address: requestData.txParams.from, - to_address: requestData.txParams.to, - gas: requestData.txParams.gas, - gasPrice: requestData.txParams.gasPrice, - value: requestData.txParams.value, - data: requestData.txParams.data, + from_address: requestData?.txParams?.from, + to_address: requestData?.txParams?.to, + gas: requestData?.txParams?.gas, + gasPrice: requestData?.txParams?.gasPrice, + value: requestData?.txParams?.value, + data: requestData?.txParams?.data, }, currentLocale, }; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 1e9698e78..b4c2ef4ba 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -3729,6 +3729,7 @@ export default class MetamaskController extends EventEmitter { getMetricsState: this.metaMetricsController.store.getState.bind( this.metaMetricsController.store, ), + securityProviderRequest: this.securityProviderRequest.bind(this), }), ); @@ -4383,11 +4384,11 @@ export default class MetamaskController extends EventEmitter { const { currentLocale, transactionSecurityCheckEnabled } = this.preferencesController.store.getState(); - const chainId = Number( - hexToDecimal(this.networkController.store.getState().provider.chainId), - ); - if (transactionSecurityCheckEnabled) { + const chainId = Number( + hexToDecimal(this.networkController.store.getState().provider.chainId), + ); + try { const securityProviderResponse = await securityProviderCheck( requestData, diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index 853807ce5..a9691d5a2 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -187,6 +187,8 @@ * identify the token_detection_enabled trait * @property {'install_date_ext'} INSTALL_DATE_EXT - when the user installed the extension * @property {'desktop_enabled'} [DESKTOP_ENABLED] - optional / does the user have desktop enabled? + * @property {'security_providers'} SECURITY_PROVIDERS - when security provider feature is toggled we + * identify the security_providers trait */ /** @@ -210,6 +212,7 @@ export const TRAITS = { THREE_BOX_ENABLED: 'three_box_enabled', TOKEN_DETECTION_ENABLED: 'token_detection_enabled', DESKTOP_ENABLED: 'desktop_enabled', + SECURITY_PROVIDERS: 'security_providers', }; /** @@ -240,6 +243,7 @@ export const TRAITS = { * @property {string} [theme] - which theme the user has selected * @property {boolean} [token_detection_enabled] - does the user have token detection is enabled? * @property {boolean} [desktop_enabled] - optional / does the user have desktop enabled? + * @property {Array} [security_providers] - whether security provider feature toggle is on or off */ // Mixpanel converts the zero address value to a truly anonymous event, which diff --git a/test/e2e/tests/eth-sign.spec.js b/test/e2e/tests/eth-sign.spec.js index 51ef2168c..5b0feb3b3 100644 --- a/test/e2e/tests/eth-sign.spec.js +++ b/test/e2e/tests/eth-sign.spec.js @@ -31,10 +31,10 @@ describe('Eth sign', function () { await driver.openNewPage('http://127.0.0.1:8080/'); await driver.clickElement('#ethSign'); + await driver.delay(1000); const ethSignButton = await driver.findElement('#ethSign'); const exceptionString = 'ERROR: ETH_SIGN HAS BEEN DISABLED. YOU MUST ENABLE IT IN THE ADVANCED SETTINGS'; - assert.equal(await ethSignButton.getText(), exceptionString); }, );