Skip to content

Commit

Permalink
Merge branch 'develop' into fix_simulation_display
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuri authored Jun 12, 2024
2 parents f4a6e8f + 696cf1d commit 3f0e61f
Show file tree
Hide file tree
Showing 64 changed files with 2,147 additions and 251 deletions.
50 changes: 50 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions app/scripts/controllers/metametrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export default class MetaMetricsController {
this.store = new ObservableStore({
participateInMetaMetrics: null,
metaMetricsId: null,
dataCollectionForMarketing: null,
eventsBeforeMetricsOptIn: [],
traits: {},
previousUserTraits: {},
Expand Down Expand Up @@ -475,6 +476,12 @@ export default class MetaMetricsController {
return metaMetricsId;
}

setDataCollectionForMarketing(dataCollectionForMarketing) {
const { metaMetricsId } = this.state;
this.store.updateState({ dataCollectionForMarketing });
return metaMetricsId;
}

get state() {
return this.store.getState();
}
Expand Down Expand Up @@ -824,6 +831,10 @@ export default class MetaMetricsController {
metamaskState.securityAlertsEnabled ? ['blockaid'] : [],
[MetaMetricsUserTrait.PetnameAddressCount]:
this._getPetnameAddressCount(metamaskState),
[MetaMetricsUserTrait.IsMetricsOptedIn]:
metamaskState.participateInMetaMetrics,
[MetaMetricsUserTrait.HasMarketingConsent]:
metamaskState.dataCollectionForMarketing,
};

if (!previousUserTraits) {
Expand Down
14 changes: 13 additions & 1 deletion app/scripts/lib/createRPCMethodTrackingMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
MetaMetricsEventName,
MetaMetricsEventUiCustomization,
} from '../../../shared/constants/metametrics';
import { parseTypedDataMessage } from '../../../shared/modules/transaction.utils';

import {
BlockaidResultType,
Expand All @@ -16,7 +17,10 @@ import {
} from '../../../shared/constants/security-provider';

///: BEGIN:ONLY_INCLUDE_IF(blockaid)
import { SIGNING_METHODS } from '../../../shared/constants/transaction';
import {
EIP712_PRIMARY_TYPE_PERMIT,
SIGNING_METHODS,
} from '../../../shared/constants/transaction';
import { getBlockaidMetricsProps } from '../../../ui/helpers/utils/metrics';
///: END:ONLY_INCLUDE_IF
import { REDESIGN_APPROVAL_TYPES } from '../../../ui/pages/confirmations/utils/confirm';
Expand Down Expand Up @@ -303,6 +307,14 @@ export default function createRPCMethodTrackingMiddleware({
MetaMetricsEventUiCustomization.Siwe,
];
}
} else if (method === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4) {
const { primaryType } = parseTypedDataMessage(data);
if (primaryType === EIP712_PRIMARY_TYPE_PERMIT) {
eventProperties.ui_customizations = [
...(eventProperties.ui_customizations || []),
MetaMetricsEventUiCustomization.Permit,
];
}
}
} catch (e) {
console.warn(`createRPCMethodTrackingMiddleware: Errored - ${e}`);
Expand Down
30 changes: 30 additions & 0 deletions app/scripts/lib/createRPCMethodTrackingMiddleware.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { errorCodes } from 'eth-rpc-errors';
import { detectSIWE } from '@metamask/controller-utils';

import { MESSAGE_TYPE } from '../../../shared/constants/app';
import {
MetaMetricsEventCategory,
Expand All @@ -11,6 +12,7 @@ import {
BlockaidReason,
BlockaidResultType,
} from '../../../shared/constants/security-provider';
import { permitSignatureMsg } from '../../../test/data/confirmations/typed_sign';
import createRPCMethodTrackingMiddleware from './createRPCMethodTrackingMiddleware';

const trackEvent = jest.fn();
Expand Down Expand Up @@ -506,6 +508,34 @@ describe('createRPCMethodTrackingMiddleware', () => {
});
});

it('should track typed-sign permit message if detected', async () => {
const req = {
method: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4,
origin: 'some.dapp',
params: [undefined, permitSignatureMsg.msgParams.data],
};
const res = {
error: null,
};
const { next, executeMiddlewareStack } = getNext();
const handler = createHandler();

await handler(req, res, next);
await executeMiddlewareStack();

expect(trackEvent).toHaveBeenCalledTimes(2);

expect(trackEvent.mock.calls[1][0]).toMatchObject({
category: MetaMetricsEventCategory.InpageProvider,
event: MetaMetricsEventName.SignatureApproved,
properties: {
signature_type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4,
ui_customizations: [MetaMetricsEventUiCustomization.Permit],
},
referrer: { url: 'some.dapp' },
});
});

describe(`when '${MESSAGE_TYPE.ETH_SIGN}' is disabled in advanced settings`, () => {
it(`should track ${MetaMetricsEventName.SignatureFailed} and include error property`, async () => {
const mockError = { code: errorCodes.rpc.methodNotFound };
Expand Down
1 change: 1 addition & 0 deletions app/scripts/lib/setupSentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export const SENTRY_BACKGROUND_STATE = {
previousUserTraits: false,
segmentApiCalls: false,
traits: false,
dataCollectionForMarketing: false,
},
NameController: {
names: false,
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3050,6 +3050,10 @@ export default class MetamaskController extends EventEmitter {
metaMetricsController.setParticipateInMetaMetrics.bind(
metaMetricsController,
),
setDataCollectionForMarketing:
metaMetricsController.setDataCollectionForMarketing.bind(
metaMetricsController,
),
setCurrentLocale: preferencesController.setCurrentLocale.bind(
preferencesController,
),
Expand Down
2 changes: 2 additions & 0 deletions builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ buildTypes:
- REQUIRE_SNAPS_ALLOWLIST: true
- IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.3.0/index.html
- ACCOUNT_SNAPS_DIRECTORY_URL: https://snaps.metamask.io/account-management
- BTC_BETA_SUPPORT: false
# Main build uses the default browser manifest
manifestOverrides: false
# Build name used in multiple user-readable places
Expand Down Expand Up @@ -70,6 +71,7 @@ buildTypes:
- SEGMENT_WRITE_KEY_REF: SEGMENT_FLASK_WRITE_KEY
- ACCOUNT_SNAPS_DIRECTORY_URL: https://metamask.github.io/snaps-directory-staging/main/account-management
- EIP_4337_ENTRYPOINT: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'
- BTC_BETA_SUPPORT: false
isPrerelease: true
manifestOverrides: ./app/build-types/flask/manifest/
buildNameOverride: MetaMask Flask
Expand Down
10 changes: 10 additions & 0 deletions shared/constants/metametrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,14 @@ export type MetaMetricsUserTraits = {
};

export enum MetaMetricsUserTrait {
/**
* Identifies if the user has opted in for MetaMetrics
*/
IsMetricsOptedIn = 'is_metrics_opted_in',
/**
* Identifies is the user has given marketing consent
*/
HasMarketingConsent = 'has_marketing_consent',
/**
* Identified when the user adds or modifies addresses in the address book.
*/
Expand Down Expand Up @@ -497,6 +505,7 @@ export enum MetaMetricsEventName {
AccountRenamed = 'Account Renamed',
ActivityDetailsOpened = 'Activity Details Opened',
ActivityDetailsClosed = 'Activity Details Closed',
AnalyticsPreferenceSelected = 'Analytics Preference Selected',
AppInstalled = 'App Installed',
AppUnlocked = 'App Unlocked',
AppUnlockedFailed = 'App Unlocked Failed',
Expand Down Expand Up @@ -828,6 +837,7 @@ export enum MetaMetricsEventUiCustomization {
RedesignedConfirmation = 'redesigned_confirmation',
SecurityAlertError = 'security_alert_error',
Siwe = 'sign_in_with_ethereum',
Permit = 'permit',
}

/**
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,5 @@ export enum TokenStandard {
/** Not a token, but rather the base asset of the selected chain. */
none = 'NONE',
}

export const EIP712_PRIMARY_TYPE_PERMIT = 'Permit';
14 changes: 14 additions & 0 deletions shared/modules/transaction.utils.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import EthQuery from '@metamask/ethjs-query';
import { TransactionType } from '@metamask/transaction-controller';

import { createTestProviderTools } from '../../test/stub/provider';
import {
determineTransactionType,
isEIP1559Transaction,
isLegacyTransaction,
parseStandardTokenTransactionData,
parseTypedDataMessage,
} from './transaction.utils';

describe('Transaction.utils', function () {
Expand Down Expand Up @@ -387,5 +389,17 @@ describe('Transaction.utils', function () {
getCodeResponse: '0x0a',
});
});

describe('parseTypedDataMessage', () => {
it('parses data passed correctly', () => {
const result = parseTypedDataMessage('{"test": "dummy"}');
expect(result.test).toBe('dummy');
});
it('throw error for invalid typedDataMessage', () => {
expect(() => {
parseTypedDataMessage('');
}).toThrow(new Error('Unexpected end of JSON input'));
});
});
});
});
3 changes: 3 additions & 0 deletions shared/modules/transaction.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,6 @@ export async function determineTransactionAssetType(
}
return { assetType: AssetType.native, tokenStandard: TokenStandard.none };
}

export const parseTypedDataMessage = (dataToParse: string) =>
JSON.parse(dataToParse);
1 change: 1 addition & 0 deletions test/e2e/default-fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) {
fragments: {},
metaMetricsId: null,
participateInMetaMetrics: false,
dataCollectionForMarketing: false,
traits: {},
},
NetworkController: {
Expand Down
39 changes: 34 additions & 5 deletions test/e2e/mock-e2e.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const fs = require('fs');

const { GAS_API_BASE_URL } = require('../../shared/constants/swaps');
const {
GAS_API_BASE_URL,
SWAPS_API_V2_BASE_URL,
TOKEN_API_BASE_URL,
} = require('../../shared/constants/swaps');

const CDN_CONFIG_PATH = 'test/e2e/mock-cdn/cdn-config.txt';
const CDN_STALE_DIFF_PATH = 'test/e2e/mock-cdn/cdn-stale-diff.txt';
Expand All @@ -15,6 +19,10 @@ const CDN_STALE_DIFF_RES_HEADERS_PATH =
const CDN_STALE_RES_HEADERS_PATH =
'test/e2e/mock-cdn/cdn-stale-res-headers.json';

const AGGREGATOR_METADATA_PATH =
'test/e2e/mock-response-data/aggregator-metadata.json';
const TOKEN_BLOCKLIST_PATH = 'test/e2e/mock-response-data/token-blocklist.json';

const blacklistedHosts = [
'arbitrum-mainnet.infura.io',
'goerli.infura.io',
Expand Down Expand Up @@ -239,7 +247,7 @@ async function setupMocking(
.thenCallback(suggestedGasFeesCallbackMock);

await server
.forGet('https://swap.api.cx.metamask.io/networks/1/token')
.forGet(`${SWAPS_API_V2_BASE_URL}/networks/1/token`)
.withQuery({ address: '0x72c9Fb7ED19D3ce51cea5C56B3e023cd918baaDf' })
.thenCallback(() => {
return {
Expand All @@ -256,7 +264,7 @@ async function setupMocking(
});

await server
.forGet('https://swap.api.cx.metamask.io/featureFlags')
.forGet(`${SWAPS_API_V2_BASE_URL}/featureFlags`)
.thenCallback(() => {
return {
statusCode: 200,
Expand Down Expand Up @@ -354,8 +362,29 @@ async function setupMocking(
};
});

const TOKEN_BLOCKLIST = fs.readFileSync(TOKEN_BLOCKLIST_PATH);
await server
.forGet(`${TOKEN_API_BASE_URL}/blocklist`)
.withQuery({ chainId: '1', region: 'global' })
.thenCallback(() => {
return {
statusCode: 200,
json: JSON.parse(TOKEN_BLOCKLIST),
};
});

const AGGREGATOR_METADATA = fs.readFileSync(AGGREGATOR_METADATA_PATH);
await server
.forGet(`${SWAPS_API_V2_BASE_URL}/networks/1/aggregatorMetadata`)
.thenCallback(() => {
return {
statusCode: 200,
json: JSON.parse(AGGREGATOR_METADATA),
};
});

await server
.forGet('https://swap.api.cx.metamask.io/networks/1/tokens')
.forGet(`${SWAPS_API_V2_BASE_URL}/networks/1/tokens`)
.thenCallback(() => {
return {
statusCode: 200,
Expand Down Expand Up @@ -439,7 +468,7 @@ async function setupMocking(
});

await server
.forGet('https://swap.api.cx.metamask.io/networks/1/topAssets')
.forGet(`${SWAPS_API_V2_BASE_URL}/networks/1/topAssets`)
.thenCallback(() => {
return {
statusCode: 200,
Expand Down
Loading

0 comments on commit 3f0e61f

Please sign in to comment.