Skip to content

Commit

Permalink
Merge branch 'develop' into rekmarks/reorder-permission-middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
legobeat committed May 31, 2024
2 parents 03017e7 + 6168b3a commit 7506f83
Show file tree
Hide file tree
Showing 19 changed files with 361 additions and 151 deletions.
319 changes: 241 additions & 78 deletions .circleci/config.yml

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ Before running e2e tests, ensure you've run `yarn install` to download dependenc
- `yarn build:test` for main build
- `yarn build:test:flask` for flask build
- `yarn build:test:mmi` for mmi build
- `yarn build:test:mv3` for mv3 build
- `yarn build:test:mv2` for mv2 build
3. Start a test build with live changes: `yarn start:test` is particularly useful for development. It starts a test build that automatically recompiles application code upon changes. This option is ideal for iterative testing and development. This command also allows you to generate test builds for various types, including:
- `yarn start:test` for main build
- `yarn start:test:flask` for flask build
- `yarn start:test:mv3` for mv3 build
- `yarn start:test:mv2` for mv2 build

Note: The `yarn start:test` command (which initiates the testDev build type) has LavaMoat disabled for both the build system and the application, offering a streamlined testing experience during development. On the other hand, `yarn build:test` enables LavaMoat for enhanced security in both the build system and application, mirroring production environments more closely.

Expand Down Expand Up @@ -183,7 +183,7 @@ Different build types have different e2e tests sets. In order to run them look i
```console
"test:e2e:chrome:mmi": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js --mmi",
"test:e2e:chrome:snaps": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js --snaps",
"test:e2e:chrome:mv3": "ENABLE_MV3=true SELENIUM_BROWSER=chrome node test/e2e/run-all.js",
"test:e2e:firefox": "ENABLE_MV3=false SELENIUM_BROWSER=firefox node test/e2e/run-all.js",
```

#### Note: Running MMI e2e tests
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/lib/WeakRefObjectMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class WeakRefObjectMap<RecordType extends Record<string, object>>
set(key: string, value: RecordType): this {
const weakRefValue: Partial<WeakRefObject<RecordType>> = {};
for (const keyValue in value) {
if (!Object.hasOwn(value, keyValue)) {
if (!Object.prototype.hasOwnProperty.call(value, keyValue)) {
continue;
}
const item: RecordType[typeof keyValue] = value[keyValue];
Expand Down Expand Up @@ -74,7 +74,7 @@ export class WeakRefObjectMap<RecordType extends Record<string, object>>

const deRefValue: Partial<RecordType> = {};
for (const keyValue in weakRefValue) {
if (!Object.hasOwn(weakRefValue, keyValue)) {
if (!Object.prototype.hasOwnProperty.call(weakRefValue, keyValue)) {
continue;
}
const deref = weakRefValue[keyValue].deref();
Expand Down
22 changes: 18 additions & 4 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3987,11 +3987,16 @@ export default class MetamaskController extends EventEmitter {
await this.keyringController.addNewAccount(count));
}

const { completedOnboarding } =
this.onboardingController.store.getState();

// This must be set as soon as possible to communicate to the
// keyring's iframe and have the setting initialized properly
// Optimistically called to not block MetaMask login due to
// Ledger Keyring GitHub downtime
this.setLedgerTransportPreference();
if (completedOnboarding) {
this.setLedgerTransportPreference();
}

return vault;
} finally {
Expand Down Expand Up @@ -4060,6 +4065,7 @@ export default class MetamaskController extends EventEmitter {
* @param {string} password - The user's password
*/
async submitPassword(password) {
const { completedOnboarding } = this.onboardingController.store.getState();
await this.keyringController.submitPassword(password);

///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
Expand All @@ -4078,7 +4084,9 @@ export default class MetamaskController extends EventEmitter {
// keyring's iframe and have the setting initialized properly
// Optimistically called to not block MetaMask login due to
// Ledger Keyring GitHub downtime
this.setLedgerTransportPreference();
if (completedOnboarding) {
this.setLedgerTransportPreference();
}
}

async _loginUser(password) {
Expand Down Expand Up @@ -4238,6 +4246,10 @@ export default class MetamaskController extends EventEmitter {
async connectHardware(deviceName, page, hdPath) {
const keyring = await this.getKeyringForDevice(deviceName, hdPath);

if (deviceName === HardwareDeviceNames.ledger) {
await this.setLedgerTransportPreference(keyring);
}

let accounts = [];
switch (page) {
case -1:
Expand Down Expand Up @@ -5896,14 +5908,16 @@ export default class MetamaskController extends EventEmitter {
/**
* Sets the Ledger Live preference to use for Ledger hardware wallet support
*
* @param _keyring
* @deprecated This method is deprecated and will be removed in the future.
* Only webhid connections are supported in chrome and u2f in firefox.
*/
async setLedgerTransportPreference() {
async setLedgerTransportPreference(_keyring) {
const transportType = window.navigator.hid
? LedgerTransportTypes.webhid
: LedgerTransportTypes.u2f;
const keyring = await this.getKeyringForDevice(HardwareDeviceNames.ledger);
const keyring =
_keyring || (await this.getKeyringForDevice(HardwareDeviceNames.ledger));
if (keyring?.updateTransportMethod) {
return keyring.updateTransportMethod(transportType).catch((e) => {
throw e;
Expand Down
5 changes: 2 additions & 3 deletions builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ env:
- SUPPORT_REQUEST_LINK: https://metamask.zendesk.com/hc/en-us
- SKIP_BACKGROUND_INITIALIZATION: false

# TODO(ritave): Move ManifestV3 into a feature?
- ENABLE_MV3: false
- ENABLE_MV3: true
# These are exclusively used for MV3
- USE_SNOW
- APPLY_LAVAMOAT
Expand Down Expand Up @@ -318,4 +317,4 @@ env:
# Account Abstraction (EIP-4337)
###

- EIP_4337_ENTRYPOINT: null
- EIP_4337_ENTRYPOINT: null
9 changes: 6 additions & 3 deletions development/build/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ const path = require('path');
const childProcess = require('child_process');
const { mergeWith, cloneDeep } = require('lodash');

const baseManifest = process.env.ENABLE_MV3
const IS_MV3_ENABLED =
process.env.ENABLE_MV3 === 'true' || process.env.ENABLE_MV3 === undefined;

const baseManifest = IS_MV3_ENABLED
? require('../../app/manifest/v3/_base.json')
: require('../../app/manifest/v2/_base.json');
const { loadBuildTypesConfig } = require('../lib/build-type');
Expand Down Expand Up @@ -32,7 +35,7 @@ function createManifestTasks({
'..',
'..',
'app',
process.env.ENABLE_MV3 ? 'manifest/v3' : 'manifest/v2',
IS_MV3_ENABLED ? 'manifest/v3' : 'manifest/v2',
`${platform}.json`,
),
);
Expand Down Expand Up @@ -136,7 +139,7 @@ function createManifestTasks({
buildType,
applyLavaMoat,
shouldIncludeSnow,
shouldIncludeMV3: process.env.ENABLE_MV3,
shouldIncludeMV3: IS_MV3_ENABLED,
});

manifest.description = `${environment} build from git id: ${gitRevisionStr}`;
Expand Down
14 changes: 9 additions & 5 deletions development/build/scripts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// TODO(ritave): Remove switches on hardcoded build types

const { callbackify } = require('util');
const path = require('path');
const { writeFileSync, readFileSync, unlinkSync } = require('fs');
Expand Down Expand Up @@ -53,6 +52,9 @@ const {
createRemoveFencedCodeTransform,
} = require('./transforms/remove-fenced-code');

const isEnableMV3 =
process.env.ENABLE_MV3 === 'true' || process.env.ENABLE_MV3 === undefined;

// map dist files to bag of needed native APIs against LM scuttling
const scuttlingConfigBase = {
'scripts/sentry-install.js': {
Expand Down Expand Up @@ -189,7 +191,7 @@ function createScriptTasks({

// In MV3 we will need to build our offscreen entry point bundle and any
// entry points for iframes that we want to lockdown with LavaMoat.
if (process.env.ENABLE_MV3 === 'true') {
if (isEnableMV3) {
standardEntryPoints.push('offscreen');
}

Expand Down Expand Up @@ -350,7 +352,7 @@ function createScriptTasks({
() => {
// MV3 injects inpage into the tab's main world, but in MV2 we need
// to do it manually:
if (process.env.ENABLE_MV3) {
if (isEnableMV3) {
return;
}
// stringify scripts/inpage.js into itself, and then make it inject itself into the page
Expand Down Expand Up @@ -714,7 +716,7 @@ function createFactoredBuild({
applyLavaMoat,
destinationFileName: 'load-background.js',
});
if (process.env.ENABLE_MV3) {
if (isEnableMV3) {
const jsBundles = [
...commonSet.values(),
...groupSet.values(),
Expand Down Expand Up @@ -1027,7 +1029,9 @@ function setupMinification(buildConfiguration) {

function setupScuttlingWrapping(buildConfiguration, applyLavaMoat, envVars) {
const scuttlingConfig =
envVars.ENABLE_MV3 === 'true'
envVars.ENABLE_MV3 === 'true' ||
envVars.ENABLE_MV3 === undefined ||
envVars.ENABLE_MV3 === true
? mv3ScuttlingConfig
: standardScuttlingConfig;
const { events } = buildConfiguration;
Expand Down
6 changes: 5 additions & 1 deletion development/build/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,11 @@ function getCopyTargets(
allCopyTargets.push({
src: getPathInsideNodeModules('@blockaid/ppom_release', '/'),
pattern: '*.wasm',
dest: process.env.ENABLE_MV3 ? 'scripts/' : '',
dest:
process.env.ENABLE_MV3 === 'true' ||
process.env.ENABLE_MV3 === undefined
? 'scripts/'
: '',
});
}

Expand Down
30 changes: 21 additions & 9 deletions development/metamaskbot-build-announce.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,20 @@ async function start() {
const platforms = ['chrome', 'firefox'];
const buildLinks = platforms
.map((platform) => {
const url = `${BUILD_LINK_BASE}/builds/metamask-${platform}-${VERSION}.zip`;
const url =
platform === 'firefox'
? `${BUILD_LINK_BASE}/builds-mv2/metamask-${platform}-${VERSION}.zip`
: `${BUILD_LINK_BASE}/builds/metamask-${platform}-${VERSION}.zip`;
return `<a href="${url}">${platform}</a>`;
})
.join(', ');
const betaBuildLinks = `<a href="${BUILD_LINK_BASE}/builds-beta/metamask-beta-chrome-${VERSION}.zip">chrome</a>`;
const flaskBuildLinks = platforms
.map((platform) => {
const url = `${BUILD_LINK_BASE}/builds-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`;
const url =
platform === 'firefox'
? `${BUILD_LINK_BASE}/builds-flask-mv2/metamask-flask-${platform}-${VERSION}-flask.0.zip`
: `${BUILD_LINK_BASE}/builds-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`;
return `<a href="${url}">${platform}</a>`;
})
.join(', ');
Expand All @@ -87,13 +93,19 @@ async function start() {
.join(', ');
const testBuildLinks = platforms
.map((platform) => {
const url = `${BUILD_LINK_BASE}/builds-test/metamask-${platform}-${VERSION}.zip`;
const url =
platform === 'firefox'
? `${BUILD_LINK_BASE}/builds-test-mv2/metamask-${platform}-${VERSION}.zip`
: `${BUILD_LINK_BASE}/builds-test/metamask-${platform}-${VERSION}.zip`;
return `<a href="${url}">${platform}</a>`;
})
.join(', ');
const testFlaskBuildLinks = platforms
.map((platform) => {
const url = `${BUILD_LINK_BASE}/builds-test-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`;
const url =
platform === 'firefox'
? `${BUILD_LINK_BASE}/builds-test-flask-mv2/metamask-flask-${platform}-${VERSION}-flask.0.zip`
: `${BUILD_LINK_BASE}/builds-test-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`;
return `<a href="${url}">${platform}</a>`;
})
.join(', ');
Expand Down Expand Up @@ -144,13 +156,13 @@ async function start() {
// links to bundle browser builds
const depVizUrl = `${BUILD_LINK_BASE}/build-artifacts/build-viz/index.html`;
const depVizLink = `<a href="${depVizUrl}">Build System</a>`;
const moduleInitStatsBackgroundUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/initialisation/background/index.html`;
const moduleInitStatsBackgroundUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/initialisation/background/index.html`;
const moduleInitStatsBackgroundLink = `<a href="${moduleInitStatsBackgroundUrl}">Background Module Init Stats</a>`;
const moduleInitStatsUIUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/initialisation/ui/index.html`;
const moduleInitStatsUIUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/initialisation/ui/index.html`;
const moduleInitStatsUILink = `<a href="${moduleInitStatsUIUrl}">UI Init Stats</a>`;
const moduleLoadStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/load_time/index.html`;
const moduleLoadStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/load_time/index.html`;
const moduleLoadStatsLink = `<a href="${moduleLoadStatsUrl}">Module Load Stats</a>`;
const bundleSizeStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/bundle_size.json`;
const bundleSizeStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/bundle_size.json`;
const bundleSizeStatsLink = `<a href="${bundleSizeStatsUrl}">Bundle Size Stats</a>`;
const userActionsStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/benchmark/user_actions.json`;
const userActionsStatsLink = `<a href="${userActionsStatsUrl}">E2e Actions Stats</a>`;
Expand Down Expand Up @@ -297,7 +309,7 @@ async function start() {
path.resolve(
__dirname,
'..',
path.join('test-artifacts', 'chrome', 'mv3', 'bundle_size.json'),
path.join('test-artifacts', 'chrome', 'bundle_size.json'),
),
'utf-8',
),
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,30 @@
"scripts": {
"start": "yarn build:dev dev --apply-lavamoat=false --snow=false",
"start:skip-onboarding": "SKIP_ONBOARDING=true yarn start",
"start:mv3": "ENABLE_MV3=true yarn build:dev dev --apply-lavamoat=false --snow=false",
"start:mv2": "ENABLE_MV3=false yarn build:dev dev --apply-lavamoat=false --snow=false",
"start:flask": "yarn start --build-type flask",
"start:mmi": "yarn start --build-type mmi",
"start:lavamoat": "yarn build:dev dev --apply-lavamoat=true",
"dist": "yarn build dist",
"dist:mv3": "ENABLE_MV3=true yarn build dist",
"dist:mv2": "ENABLE_MV3=false yarn build dist",
"dist:mmi": "yarn dist --build-type mmi",
"dist:mmi:debug": "yarn dist --build-type mmi --apply-lavamoat=false --snow=false",
"build": "yarn lavamoat:build",
"build:dev": "node development/build/index.js",
"start:test": "BLOCKAID_FILE_CDN=static.cx.metamask.io/api/v1/confirmations/ppom SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --apply-lavamoat=false --snow=false",
"start:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev",
"start:test:flask": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --build-type flask --apply-lavamoat=false --snow=false",
"start:test:mv3": "ENABLE_MV3=true SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev",
"start:test:mv2:flask": "ENABLE_MV3=false SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --build-type flask --apply-lavamoat=false --snow=false",
"start:test:mv2": "ENABLE_MV3=false BLOCKAID_FILE_CDN=static.cx.metamask.io/api/v1/confirmations/ppom SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --apply-lavamoat=false --snow=false",
"benchmark:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/benchmark.js",
"mv3:stats:chrome": "SELENIUM_BROWSER=chrome ENABLE_MV3=true ts-node test/e2e/mv3-perf-stats/index.js",
"mv3:stats:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/mv3-perf-stats/index.js",
"user-actions-benchmark:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/user-actions-benchmark.js",
"benchmark:firefox": "SELENIUM_BROWSER=firefox ts-node test/e2e/benchmark.js",
"build:test": "BLOCKAID_FILE_CDN=static.cx.metamask.io/api/v1/confirmations/ppom SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build test",
"build:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build test",
"build:test:dev": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --apply-lavamoat=false",
"build:test:flask": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build test --build-type flask",
"build:test:flask:mv2": "ENABLE_MV3=false SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build test --build-type flask",
"build:test:mmi": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build test --build-type mmi",
"build:test:mv3": "ENABLE_MV3=true SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build test",
"build:test:dev:mv3": "ENABLE_MV3=true SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build:dev testDev --apply-lavamoat=false",
"build:test:mv2": "ENABLE_MV3=false BLOCKAID_FILE_CDN=static.cx.metamask.io/api/v1/confirmations/ppom SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 yarn build test",
"test": "yarn lint && yarn test:unit && yarn test:unit:jest",
"dapp": "node development/static-server.js node_modules/@metamask/test-dapp/dist --port 8080",
"dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'",
Expand All @@ -50,7 +52,6 @@
"test:e2e:mmi:visual": "./test/e2e/mmi/scripts/run-visual-test.sh check",
"test:e2e:mmi:visual:update": "./test/e2e/mmi/scripts/run-visual-test.sh update",
"test:e2e:pw:report": "yarn playwright show-report public/playwright/playwright-reports/html",
"test:e2e:chrome:mv3": "ENABLE_MV3=true SELENIUM_BROWSER=chrome node test/e2e/run-all.js",
"test:e2e:chrome:rpc": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js --rpc",
"test:e2e:chrome:multi-provider": "MULTIPROVIDER=true SELENIUM_BROWSER=chrome node test/e2e/run-all.js --multi-provider",
"test:e2e:firefox": "SELENIUM_BROWSER=firefox node test/e2e/run-all.js",
Expand Down
6 changes: 5 additions & 1 deletion test/e2e/json-rpc/switchEthereumChain.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,11 @@ describe('Switch Ethereum Chain for two dapps', function () {
// if this is an MV3 build(3 or 4 total)
await driver.wait(async () => {
const windowHandles = await driver.getAllWindowHandles();
const numberOfWindowHandlesToExpect = process.env.ENABLE_MV3 ? 4 : 3;
const numberOfWindowHandlesToExpect =
process.env.ENABLE_MV3 === 'true' ||
process.env.ENABLE_MV3 === undefined
? 4
: 3;
return windowHandles.length === numberOfWindowHandlesToExpect;
});
},
Expand Down
6 changes: 5 additions & 1 deletion test/e2e/tests/account/import-flow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ describe('Import flow @no-mmi', function () {

// accepts the account password after lock
await unlockWallet(driver, {
navigate: false,
waitLoginSuccess: false,
});

Expand Down Expand Up @@ -378,7 +379,10 @@ describe('Import flow @no-mmi', function () {
});

it('Connects to a Hardware wallet for lattice', async function () {
if (process.env.ENABLE_MV3) {
if (
process.env.ENABLE_MV3 === 'true' ||
process.env.ENABLE_MV3 === undefined
) {
// Hardware wallets not supported in MV3 build yet
this.skip();
}
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/request-queuing/ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async function selectDappClickSendGetNetwork(driver, dappUrl) {
// because the offscreen document returned by getAllWindowHandles provides
// an extra window handle
const newWindowHandles = await driver.waitUntilXWindowHandles(
process.env.ENABLE_MV3
process.env.ENABLE_MV3 === 'true' || process.env.ENABLE_MV3 === undefined
? currentWindowHandles.length
: currentWindowHandles.length + 1,
);
Expand Down
Loading

0 comments on commit 7506f83

Please sign in to comment.