From bb391c2e5d1e3aa31edf030b76ce7a3eb31fa796 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 7 Mar 2025 10:10:26 +0100 Subject: [PATCH 01/17] chore: fix trezor audit (#30850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** We temporarily ignore the `'@trezor/connect-web` audit failure to unblock ci, as upgrading to the new version breaks the webpack build. ``` └─ @trezor/connect-web ├─ ID: @trezor/connect-web (deprecation) ├─ Issue: This version is no longer supported ├─ Severity: moderate ├─ Vulnerable Versions: 9.4.7 │ ├─ Tree Versions │ └─ 9.4.7 │ └─ Dependents └─ metamask-crx@workspace:. ``` [This issue](https://github.com/MetaMask/metamask-extension/issues/30851) is created in order to upgrade to the latest version and remove the entry from the ignore list. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30850?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Check yarn audit gh action ## **Screenshots/Recordings** ### Before ![Screenshot from 2025-03-07 09-35-05](https://github.com/user-attachments/assets/04fe6b00-93c9-40e3-8b0b-aeb758015ba7) ### After ![Screenshot from 2025-03-07 09-40-00](https://github.com/user-attachments/assets/a895ccfa-8203-4c92-b0dd-61c567cd9f5a) ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: Frederik Bolding --- .yarnrc.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.yarnrc.yml b/.yarnrc.yml index 8eea0010a657..27deee790900 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -126,6 +126,12 @@ npmAuditIgnoreAdvisories: # New package name format for new versions: @ethereumjs/wallet. - 'ethereumjs-wallet (deprecation)' + # The new trezor version breaks the webpack build due to issues with ESM and CommonJS + # Leading to this error on start: `Uncaught ReferenceError: exports is not defined` + # We temporarily ignore the audit failure until we can safely upgrade to the new version without breaking the webpack build + # Check Trezor 9.5.X Changelog for more info: https://github.com/trezor/trezor-suite/blob/develop/packages/connect/CHANGELOG.md + - '@trezor/connect-web (deprecation)' + plugins: - path: .yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs spec: 'https://raw.githubusercontent.com/LavaMoat/LavaMoat/main/packages/yarn-plugin-allow-scripts/bundles/@yarnpkg/plugin-allow-scripts.js' From 9811f62ff4f66562e46a74a68818c4dc14fe6793 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:19:32 +0100 Subject: [PATCH 02/17] test: remove `defaultGanacheOptions` (#30728) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** In this PR we remove the `defaultGanacheOptions` variable from all specs. 2 reasons: - the default options, are already handled in the node class level, so no need to pass default options in any spec, only custom options - we are going to use anvil, or other nodes, so this custom variable makes no sense anymore Note: skip-e2e-quality-gate is added because we modify several spec files, which can take long to run, reaching timeout as they'll all be rerun + 5 times extra, but there should be no functional change, so e2e should continue to work as before [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30728?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/MetaMask-planning/issues/4348 ## **Manual testing steps** 1. All specs should continue to work normally ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- test/e2e/helpers.js | 11 ----------- test/e2e/json-rpc/eth_newBlockFilter.spec.ts | 5 ++--- test/e2e/json-rpc/wallet_addEthereumChain.spec.ts | 2 -- test/e2e/tests/confirmations/helpers.ts | 3 +-- .../tests/metrics/metametrics-persistence.spec.js | 13 ------------- test/e2e/tests/multichain/asset-picker-send.spec.ts | 2 -- .../sendTx-revokePermissions.spec.ts | 9 +-------- .../e2e/tests/tokens/add-token-using-search.spec.ts | 3 +-- test/e2e/tests/tokens/token-details.spec.ts | 7 +------ test/e2e/tests/tokens/token-list.spec.ts | 7 +------ test/e2e/tests/tokens/token-sort.spec.ts | 8 +------- 11 files changed, 8 insertions(+), 62 deletions(-) diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index bffb4559003b..be04a81f4e59 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -531,17 +531,7 @@ const PRIVATE_KEY_TWO = const ACCOUNT_1 = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1'; const ACCOUNT_2 = '0x09781764c08de8ca82e156bbf156a3ca217c7950'; -const defaultGanacheOptions = { - accounts: [ - { - secretKey: PRIVATE_KEY, - balance: convertETHToHexGwei(DEFAULT_GANACHE_ETH_BALANCE_DEC), - }, - ], -}; - const defaultGanacheOptionsForType2Transactions = { - ...defaultGanacheOptions, // EVM version that supports type 2 transactions (EIP1559) hardfork: 'london', }; @@ -956,7 +946,6 @@ module.exports = { switchToOrOpenDapp, connectToDapp, multipleGanacheOptions, - defaultGanacheOptions, defaultGanacheOptionsForType2Transactions, multipleGanacheOptionsForType2Transactions, sendTransaction, diff --git a/test/e2e/json-rpc/eth_newBlockFilter.spec.ts b/test/e2e/json-rpc/eth_newBlockFilter.spec.ts index d208e22c23d0..5766c1e0cb6e 100644 --- a/test/e2e/json-rpc/eth_newBlockFilter.spec.ts +++ b/test/e2e/json-rpc/eth_newBlockFilter.spec.ts @@ -1,13 +1,12 @@ import { strict as assert } from 'assert'; -import { defaultGanacheOptions, withFixtures } from '../helpers'; +import { withFixtures } from '../helpers'; import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; import FixtureBuilder from '../fixture-builder'; import { Driver } from '../webdriver/driver'; describe('eth_newBlockFilter', function () { - const ganacheOptions: typeof defaultGanacheOptions & { blockTime: number } = { + const ganacheOptions: { blockTime: number } = { blockTime: 0.1, - ...defaultGanacheOptions, }; it('executes a new block filter call', async function () { await withFixtures( diff --git a/test/e2e/json-rpc/wallet_addEthereumChain.spec.ts b/test/e2e/json-rpc/wallet_addEthereumChain.spec.ts index aa747e5b1d89..6a0b64e1388b 100644 --- a/test/e2e/json-rpc/wallet_addEthereumChain.spec.ts +++ b/test/e2e/json-rpc/wallet_addEthereumChain.spec.ts @@ -7,7 +7,6 @@ import FixtureBuilder from '../fixture-builder'; import { Driver } from '../webdriver/driver'; import { withFixtures, - defaultGanacheOptions, openDapp, unlockWallet, WINDOW_TITLES, @@ -479,7 +478,6 @@ describe('Add Ethereum Chain', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDappWithChains(['0x539']) .build(), - localNodeOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { diff --git a/test/e2e/tests/confirmations/helpers.ts b/test/e2e/tests/confirmations/helpers.ts index c8a75119ccaf..49b7ee297f15 100644 --- a/test/e2e/tests/confirmations/helpers.ts +++ b/test/e2e/tests/confirmations/helpers.ts @@ -1,7 +1,6 @@ import { TransactionEnvelopeType } from '@metamask/transaction-controller'; import FixtureBuilder from '../../fixture-builder'; import { - defaultGanacheOptions, defaultGanacheOptionsForType2Transactions, withFixtures, } from '../../helpers'; @@ -44,7 +43,7 @@ export function withTransactionEnvelopeTypeFixtures( .build(), localNodeOptions: transactionEnvelopeType === TransactionEnvelopeType.legacy - ? defaultGanacheOptions + ? {} : defaultGanacheOptionsForType2Transactions, ...(smartContract && { smartContract }), ...(mocks && { testSpecificMock: mocks }), diff --git a/test/e2e/tests/metrics/metametrics-persistence.spec.js b/test/e2e/tests/metrics/metametrics-persistence.spec.js index 3c0a395dab81..1330c49b4e25 100644 --- a/test/e2e/tests/metrics/metametrics-persistence.spec.js +++ b/test/e2e/tests/metrics/metametrics-persistence.spec.js @@ -2,17 +2,12 @@ const { strict: assert } = require('assert'); const FixtureBuilder = require('../../fixture-builder'); const { withFixtures, - generateGanacheOptions, - defaultGanacheOptions, unlockWallet, - genRandInitBal, getCleanAppState, } = require('../../helpers'); describe('MetaMetrics ID persistence', function () { it('MetaMetrics ID should persist when the user opts-out and then opts-in again of MetaMetrics collection', async function () { - const { initialBalanceInHex } = genRandInitBal(); - const initialMetaMetricsId = 'test-metrics-id'; await withFixtures( @@ -23,14 +18,6 @@ describe('MetaMetrics ID persistence', function () { participateInMetaMetrics: true, }) .build(), - localNodeOptions: generateGanacheOptions({ - accounts: [ - { - secretKey: defaultGanacheOptions.accounts[0].secretKey, - balance: initialBalanceInHex, - }, - ], - }), title: this.test.fullTitle(), }, async ({ driver }) => { diff --git a/test/e2e/tests/multichain/asset-picker-send.spec.ts b/test/e2e/tests/multichain/asset-picker-send.spec.ts index 77d210959c77..66f651588e44 100644 --- a/test/e2e/tests/multichain/asset-picker-send.spec.ts +++ b/test/e2e/tests/multichain/asset-picker-send.spec.ts @@ -3,7 +3,6 @@ import { Context } from 'mocha'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import FixtureBuilder from '../../fixture-builder'; import { - defaultGanacheOptions, openActionMenuAndStartSendFlow, unlockWallet, withFixtures, @@ -17,7 +16,6 @@ describe('AssetPickerSendFlow', function () { const fixtures = { fixtures: new FixtureBuilder({ inputChainId: chainId }).build(), localNodeOptions: { - ...defaultGanacheOptions, chainId: parseInt(chainId, 16), }, }; diff --git a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts index 733c0eb10426..b88d999dda9e 100644 --- a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts +++ b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts @@ -4,11 +4,7 @@ import TransactionConfirmation from '../../page-objects/pages/confirmations/rede import { Driver } from '../../webdriver/driver'; import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants'; import FixtureBuilder from '../../fixture-builder'; -import { - withFixtures, - defaultGanacheOptions, - WINDOW_TITLES, -} from '../../helpers'; +import { withFixtures, WINDOW_TITLES } from '../../helpers'; describe('Request Queuing', function () { // TODO: add a new spec which checks that after revoking and connecting again @@ -22,9 +18,6 @@ describe('Request Queuing', function () { .withPermissionControllerConnectedToTestDapp() .withSelectedNetworkControllerPerDomain() .build(), - localNodeOptions: { - ...defaultGanacheOptions, - }, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { diff --git a/test/e2e/tests/tokens/add-token-using-search.spec.ts b/test/e2e/tests/tokens/add-token-using-search.spec.ts index b9b57d29b8b5..450ab541cdbe 100644 --- a/test/e2e/tests/tokens/add-token-using-search.spec.ts +++ b/test/e2e/tests/tokens/add-token-using-search.spec.ts @@ -1,5 +1,5 @@ import { MockedEndpoint, Mockttp } from 'mockttp'; -import { defaultGanacheOptions, withFixtures } from '../../helpers'; +import { withFixtures } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import AssetListPage from '../../page-objects/pages/home/asset-list'; @@ -48,7 +48,6 @@ describe('Add existing token using search', function () { }) .build(), localNodeOptions: { - ...defaultGanacheOptions, chainId: parseInt(CHAIN_IDS.BSC, 16), }, title: this.test?.fullTitle(), diff --git a/test/e2e/tests/tokens/token-details.spec.ts b/test/e2e/tests/tokens/token-details.spec.ts index 9488de3b433d..8a07aecf709b 100644 --- a/test/e2e/tests/tokens/token-details.spec.ts +++ b/test/e2e/tests/tokens/token-details.spec.ts @@ -3,11 +3,7 @@ import { Context } from 'mocha'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { formatCurrency } from '../../../../ui/helpers/utils/confirm-tx.util'; import FixtureBuilder from '../../fixture-builder'; -import { - defaultGanacheOptions, - unlockWallet, - withFixtures, -} from '../../helpers'; +import { unlockWallet, withFixtures } from '../../helpers'; import { Driver } from '../../webdriver/driver'; import HomePage from '../../page-objects/pages/home/homepage'; import AssetListPage from '../../page-objects/pages/home/asset-list'; @@ -26,7 +22,6 @@ describe('Token Details', function () { const fixtures = { fixtures: new FixtureBuilder({ inputChainId: chainId }).build(), localNodeOptions: { - ...defaultGanacheOptions, chainId: parseInt(chainId, 16), }, }; diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index d8ebb02e5fa3..de7c62b58e19 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -4,11 +4,7 @@ import { zeroAddress } from 'ethereumjs-util'; import { Browser } from 'selenium-webdriver'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import FixtureBuilder from '../../fixture-builder'; -import { - defaultGanacheOptions, - unlockWallet, - withFixtures, -} from '../../helpers'; +import { unlockWallet, withFixtures } from '../../helpers'; import { Driver } from '../../webdriver/driver'; import HomePage from '../../page-objects/pages/home/homepage'; import AssetListPage from '../../page-objects/pages/home/asset-list'; @@ -30,7 +26,6 @@ describe('Token List', function () { const fixtures = { fixtures: new FixtureBuilder({ inputChainId: chainId }).build(), localNodeOptions: { - ...defaultGanacheOptions, chainId: parseInt(chainId, 16), }, }; diff --git a/test/e2e/tests/tokens/token-sort.spec.ts b/test/e2e/tests/tokens/token-sort.spec.ts index b84f371a0d34..1682ef1210f8 100644 --- a/test/e2e/tests/tokens/token-sort.spec.ts +++ b/test/e2e/tests/tokens/token-sort.spec.ts @@ -1,12 +1,7 @@ import { Context } from 'mocha'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import FixtureBuilder from '../../fixture-builder'; -import { - defaultGanacheOptions, - unlockWallet, - withFixtures, - largeDelayMs, -} from '../../helpers'; +import { unlockWallet, withFixtures, largeDelayMs } from '../../helpers'; import { Driver } from '../../webdriver/driver'; import HomePage from '../../page-objects/pages/home/homepage'; import AssetListPage from '../../page-objects/pages/home/asset-list'; @@ -19,7 +14,6 @@ describe('Token List Sorting', function () { const testFixtures = { fixtures: new FixtureBuilder({ inputChainId: mainnetChainId }).build(), localNodeOptions: { - ...defaultGanacheOptions, chainId: parseInt(mainnetChainId, 16), }, }; From 74d41866d1bbf058817b34409dc2523879fa43be Mon Sep 17 00:00:00 2001 From: Michele Esposito <34438276+mikesposito@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:43:37 +0100 Subject: [PATCH 03/17] chore: bump `@metamask/{keyring, profile-sync}-controller` (#30637) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** These packages are being bumped to their latest version: ### `@metamask/keyring-controller` - **BREAKING:** `addNewKeyring` method now returns `Promise` instead of `Promise` ([#5372](https://github.com/MetaMask/core/pull/5372)) - Consumers can use the returned `KeyringMetadata.id` to access the created keyring instance via `withKeyring`. - **BREAKING:** `withKeyring` method now requires a callback argument of type `({ keyring: SelectedKeyring; metadata: KeyringMetadata }) => Promise` ([#5372](https://github.com/MetaMask/core/pull/5372)) - Bump `@metamask/keyring-internal-api` from `^4.0.3` to `^5.0.0` ([#5405](https://github.com/MetaMask/core/pull/5405)) - Bump `@metamask/eth-hd-keyring` from `^10.0.0` to `^11.0.0` ([#5405](https://github.com/MetaMask/core/pull/5405)) - Bump `@metamask/eth-simple-keyring` from `^8.1.0` to `^9.0.0` ([#5405](https://github.com/MetaMask/core/pull/5405)) ### `@metamask/profile-sync-controller` - Bump `@metamask/keyring-internal-api` from `^4.0.3` to `^5.0.0` ([#5405](https://github.com/MetaMask/core/pull/5405)) ### `@metamask/eth-ledger-bridge-keyring` - **BREAKING:** `LedgerKeyring` now implements the `Keyring` type ([#194](https://github.com/MetaMask/accounts/pull/194)) - The class does not extend `EventEmitter` anymore. - The `LedgerKeyring.accounts` class variable is now a `readonly Hex[]` array. - The `addAccounts` method signature has been changed: - An `amount` number parameter is now required to specify the number of accounts to add. - The method now returns a promise resolving to an array of `Hex` addresses. - The `unlock` method now returns `Promise`. - The `getAccounts` method now returns `Promise`. - The `deserialize` method now requires a `LedgerKeyringSerializedState` typed parameter. - The `signTransaction` method now accepts an `Hex` typed value as the `address` parameter. - The `signMessage` method now accepts an `Hex` typed value as the `withAccount` parameter. - The `signPersonalMessage` method now accepts an `Hex` typed value as the `withAccount` parameter. - The `signTypedData` method now accepts an `Hex` typed value as the `withAccount` parameter. - The `unlockAccountByAddress` method now accepts an `Hex` typed value as the `address` parameter. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30637?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: MetaMask Bot --- .../controllers/mmi-controller.test.ts | 5 +- app/scripts/controllers/mmi-controller.ts | 3 +- app/scripts/metamask-controller.js | 88 +++++++++-------- app/scripts/metamask-controller.test.js | 6 +- lavamoat/browserify/beta/policy.json | 2 +- lavamoat/browserify/flask/policy.json | 2 +- lavamoat/browserify/main/policy.json | 2 +- lavamoat/browserify/mmi/policy.json | 2 +- package.json | 10 +- shared/lib/keyring.test.ts | 95 ------------------- shared/lib/keyring.ts | 43 --------- yarn.lock | 85 +++++++++-------- 12 files changed, 112 insertions(+), 231 deletions(-) delete mode 100644 shared/lib/keyring.test.ts delete mode 100644 shared/lib/keyring.ts diff --git a/app/scripts/controllers/mmi-controller.test.ts b/app/scripts/controllers/mmi-controller.test.ts index fa32e5681e99..b31810288819 100644 --- a/app/scripts/controllers/mmi-controller.test.ts +++ b/app/scripts/controllers/mmi-controller.test.ts @@ -313,10 +313,11 @@ describe('MMIController', function () { const type = 'mock-keyring-type'; mmiController.keyringController.getKeyringsByType = jest .fn() - .mockReturnValue([]); + .mockReturnValueOnce([]) + .mockReturnValueOnce(['new-keyring']); mmiController.keyringController.addNewKeyring = jest .fn() - .mockResolvedValue('new-keyring'); + .mockResolvedValue('new-keyring-metadata'); const result = await mmiController.addKeyringIfNotExists(type); diff --git a/app/scripts/controllers/mmi-controller.ts b/app/scripts/controllers/mmi-controller.ts index 7378585a7e8f..118a21367249 100644 --- a/app/scripts/controllers/mmi-controller.ts +++ b/app/scripts/controllers/mmi-controller.ts @@ -226,7 +226,8 @@ export class MMIController { async addKeyringIfNotExists(type: KeyringTypes) { let keyring = await this.keyringController.getKeyringsByType(type)[0]; if (!keyring) { - keyring = await this.keyringController.addNewKeyring(type); + await this.keyringController.addNewKeyring(type); + [keyring] = await this.keyringController.getKeyringsByType(type); } return keyring; } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d9f48b906d5d..aae868639481 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -189,9 +189,6 @@ import { LedgerTransportTypes, } from '../../shared/constants/hardware-wallets'; import { KeyringType } from '../../shared/constants/keyring'; -///: BEGIN:ONLY_INCLUDE_IF(multi-srp) -import { findKeyringId } from '../../shared/lib/keyring'; -///: END:ONLY_INCLUDE_IF import { RestrictedMethods, ExcludedSnapPermissions, @@ -2455,11 +2452,14 @@ export default class MetamaskController extends EventEmitter { * @returns {SnapKeyring} */ async getSnapKeyring() { + // TODO: Use `withKeyring` instead let [snapKeyring] = this.keyringController.getKeyringsByType( KeyringType.snap, ); if (!snapKeyring) { - snapKeyring = await this.keyringController.addNewKeyring( + await this.keyringController.addNewKeyring(KeyringType.snap); + // TODO: Use `withKeyring` instead + [snapKeyring] = this.keyringController.getKeyringsByType( KeyringType.snap, ); } @@ -2633,7 +2633,7 @@ export default class MetamaskController extends EventEmitter { { id: source, }, - async (keyring) => ({ + async ({ keyring }) => ({ type: keyring.type, mnemonic: keyring.mnemonic, }), @@ -4316,7 +4316,7 @@ export default class MetamaskController extends EventEmitter { try { // TODO: `getKeyringsByType` is deprecated, this logic should probably be moved to the `KeyringController`. // FIXME: The `KeyringController` does not check yet for duplicated accounts with HD keyrings, see: https://github.com/MetaMask/core/issues/5411 - const alreadyImportedSrp = await this.keyringController + const alreadyImportedSrp = this.keyringController .getKeyringsByType(KeyringTypes.hd) .some((keyring) => { return ( @@ -4332,26 +4332,22 @@ export default class MetamaskController extends EventEmitter { ); } - const newKeyring = await this.keyringController.addNewKeyring( + const { id } = await this.keyringController.addNewKeyring( KeyringTypes.hd, { mnemonic, numberOfAccounts: 1, }, ); - const [newAccountAddress] = await newKeyring.getAccounts(); + const [newAccountAddress] = await this.keyringController.withKeyring( + { id }, + async ({ keyring }) => keyring.getAccounts(), + ); const account = this.accountsController.getAccountByAddress(newAccountAddress); this.accountsController.setSelectedAccount(account.id); - // TODO: Find a way to encapsulate this logic in the KeyringController itself. - const { keyrings, keyringsMetadata } = this.keyringController.state; - const keyringId = findKeyringId(keyrings, keyringsMetadata, { - address: newAccountAddress, - type: KeyringTypes.hd, - }); - - await this._addAccountsWithBalance(keyringId); + await this._addAccountsWithBalance(id); return newAccountAddress; } finally { @@ -4372,10 +4368,13 @@ export default class MetamaskController extends EventEmitter { const releaseLock = await this.createVaultMutex.acquire(); try { // addNewKeyring auto creates 1 account. - const newHdkeyring = await this.keyringController.addNewKeyring( + const { id } = await this.keyringController.addNewKeyring( KeyringTypes.hd, ); - const [newAccount] = await newHdkeyring.getAccounts(); + const [newAccount] = await this.keyringController.withKeyring( + { id }, + async ({ keyring }) => keyring.getAccounts(), + ); const account = this.accountsController.getAccountByAddress(newAccount); this.accountsController.setSelectedAccount(account.id); @@ -4451,7 +4450,7 @@ export default class MetamaskController extends EventEmitter { const accounts = await this.keyringController.withKeyring( keyringSelector, - async (keyring) => { + async ({ keyring }) => { return await keyring.getAccounts(); }, ); @@ -4487,7 +4486,7 @@ export default class MetamaskController extends EventEmitter { // This account has assets, so check the next one address = await this.keyringController.withKeyring( keyringSelector, - async (keyring) => { + async ({ keyring }) => { const [newAddress] = await keyring.addAccounts(1); return newAddress; }, @@ -4770,11 +4769,13 @@ export default class MetamaskController extends EventEmitter { // The `getKeyringForAccount` is now deprecated, so we just use `withKeyring` instead to access our keyring. return await this.keyringController.withKeyring( { address }, - ({ type: keyringType, bridge: keyringBridge }) => + ({ keyring }) => { + const { type: keyringType, bridge: keyringBridge } = keyring; // Specific case for OneKey devices, see `ONE_KEY_VIA_TREZOR_MINOR_VERSION` for further details. - keyringBridge?.minorVersion === ONE_KEY_VIA_TREZOR_MINOR_VERSION + return keyringBridge?.minorVersion === ONE_KEY_VIA_TREZOR_MINOR_VERSION ? HardwareKeyringType.oneKey - : HardwareKeyringType[keyringType], + : HardwareKeyringType[keyringType]; + }, ); } @@ -4832,23 +4833,26 @@ export default class MetamaskController extends EventEmitter { * @returns {'ledger' | 'lattice' | string | undefined} */ async getDeviceModel(address) { - return this.keyringController.withKeyring({ address }, async (keyring) => { - switch (keyring.type) { - case KeyringType.trezor: - case KeyringType.oneKey: - return keyring.getModel(); - case KeyringType.qr: - return keyring.getName(); - case KeyringType.ledger: - // TODO: get model after ledger keyring exposes method - return HardwareDeviceNames.ledger; - case KeyringType.lattice: - // TODO: get model after lattice keyring exposes method - return HardwareDeviceNames.lattice; - default: - return undefined; - } - }); + return this.keyringController.withKeyring( + { address }, + async ({ keyring }) => { + switch (keyring.type) { + case KeyringType.trezor: + case KeyringType.oneKey: + return keyring.getModel(); + case KeyringType.qr: + return keyring.getName(); + case KeyringType.ledger: + // TODO: get model after ledger keyring exposes method + return HardwareDeviceNames.ledger; + case KeyringType.lattice: + // TODO: get model after lattice keyring exposes method + return HardwareDeviceNames.lattice; + default: + return undefined; + } + }, + ); } /** @@ -4936,7 +4940,7 @@ export default class MetamaskController extends EventEmitter { const addedAccountAddress = await this.keyringController.withKeyring( keyringSelector, - async (keyring) => { + async ({ keyring }) => { if (keyring.type !== KeyringTypes.hd) { throw new Error('Cannot add account to non-HD keyring'); } @@ -7573,7 +7577,7 @@ export default class MetamaskController extends EventEmitter { return this.keyringController.withKeyring( { type: keyringType }, - async (keyring) => { + async ({ keyring }) => { if (options.hdPath && keyring.setHdPath) { keyring.setHdPath(options.hdPath); } diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 73b25ca07a65..4c89dafb6d85 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -195,6 +195,7 @@ const buildMockKeyringBridge = (publicKeyPayload) => jest.fn(() => ({ init: jest.fn(), dispose: jest.fn(), + destroy: jest.fn(), updateTransportMethod: jest.fn(), getPublicKey: jest.fn(async () => publicKeyPayload), })); @@ -214,6 +215,7 @@ jest.mock('@metamask/eth-ledger-bridge-keyring', () => ({ ...jest.requireActual('@metamask/eth-ledger-bridge-keyring'), LedgerIframeBridge: buildMockKeyringBridge({ publicKey: KNOWN_PUBLIC_KEY, + address: KNOWN_PUBLIC_KEY_ADDRESSES[0].address, chainCode: '0x1', }), })); @@ -1859,7 +1861,7 @@ describe('MetaMaskController', () => { async (type) => { jest .spyOn(metamaskController.keyringController, 'withKeyring') - .mockImplementation((_, fn) => fn({ type })); + .mockImplementation((_, fn) => fn({ keyring: { type } })); const result = await metamaskController.getHardwareTypeForMetric( '0x123', @@ -1877,7 +1879,7 @@ describe('MetaMaskController', () => { type: 'trezor', bridge: { minorVersion: ONE_KEY_VIA_TREZOR_MINOR_VERSION }, }; - return fn(keyring); + return fn({ keyring }); }); const result = await metamaskController.getHardwareTypeForMetric( diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 9b8a0b6a7a87..32228a0ea8fc 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1147,8 +1147,8 @@ "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 9b8a0b6a7a87..32228a0ea8fc 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1147,8 +1147,8 @@ "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 9b8a0b6a7a87..32228a0ea8fc 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1147,8 +1147,8 @@ "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 3bc4a066ceac..822badb94d04 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1239,8 +1239,8 @@ "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, diff --git a/package.json b/package.json index be95d01b99ad..4bae16a04478 100644 --- a/package.json +++ b/package.json @@ -271,19 +271,19 @@ "@metamask/ens-resolver-snap": "^0.1.2", "@metamask/eth-json-rpc-filters": "^9.0.0", "@metamask/eth-json-rpc-middleware": "^15.1.2", - "@metamask/eth-ledger-bridge-keyring": "^8.0.3", + "@metamask/eth-ledger-bridge-keyring": "^9.0.0", "@metamask/eth-sig-util": "^7.0.1", "@metamask/eth-snap-keyring": "^11.1.0", "@metamask/eth-token-tracker": "^10.0.2", - "@metamask/eth-trezor-keyring": "^6.0.0", + "@metamask/eth-trezor-keyring": "^6.1.1", "@metamask/etherscan-link": "^3.0.0", "@metamask/gas-fee-controller": "^22.0.3", "@metamask/jazzicon": "^2.0.0", "@metamask/json-rpc-engine": "^10.0.0", "@metamask/json-rpc-middleware-stream": "^8.0.4", "@metamask/keyring-api": "^17.2.1", - "@metamask/keyring-controller": "^19.2.0", - "@metamask/keyring-internal-api": "^4.0.3", + "@metamask/keyring-controller": "^20.0.0", + "@metamask/keyring-internal-api": "^5.0.0", "@metamask/keyring-snap-client": "^4.0.1", "@metamask/logging-controller": "^6.0.4", "@metamask/logo": "^4.0.0", @@ -305,7 +305,7 @@ "@metamask/post-message-stream": "^9.0.0", "@metamask/ppom-validator": "0.36.0", "@metamask/preinstalled-example-snap": "^0.3.0", - "@metamask/profile-sync-controller": "^8.1.1", + "@metamask/profile-sync-controller": "^9.0.0", "@metamask/providers": "^20.0.0", "@metamask/queued-request-controller": "^7.0.1", "@metamask/rate-limit-controller": "^6.0.3", diff --git a/shared/lib/keyring.test.ts b/shared/lib/keyring.test.ts deleted file mode 100644 index 23c53c39f37b..000000000000 --- a/shared/lib/keyring.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - KeyringObject, - KeyringMetadata, - KeyringTypes, -} from '@metamask/keyring-controller'; -import { findKeyringId, findKeyringIdByAddress } from './keyring'; - -const mockAddress1 = '0xb1baf6a2f4a808937bb97a2f12ccf08f1233e3d9'; -const mockAddress2 = '0xe9d2ba741180799e497a687c11ef9e99054ef2fa'; -const mockAddress3 = '0x67b2faf7959fb61eb9746571041476bbd0672569'; - -const mockHdKeyring: KeyringObject = { - type: KeyringTypes.hd, - accounts: [mockAddress1, mockAddress2], -}; -const mockSimpleKeyring: KeyringObject = { - type: KeyringTypes.simple, - accounts: [mockAddress3], -}; -const mockHdKeyringMetadata: KeyringMetadata = { id: 'keyring-1', name: '' }; -const mockSimpleKeyringMetadata: KeyringMetadata = { - id: 'keyring-2', - name: '', -}; - -const mockKeyrings: KeyringObject[] = [mockHdKeyring, mockSimpleKeyring]; - -const mockMetadata: KeyringMetadata[] = [ - mockHdKeyringMetadata, - mockSimpleKeyringMetadata, -]; - -describe('Keyring utils', () => { - describe('findKeyringId', () => { - it('finds keyring by address', () => { - expect( - findKeyringId(mockKeyrings, mockMetadata, { address: mockAddress1 }), - ).toBe(mockHdKeyringMetadata.id); - }); - - it('finds keyring by type', () => { - expect( - findKeyringId(mockKeyrings, mockMetadata, { - type: KeyringTypes.simple, - }), - ).toBe(mockSimpleKeyringMetadata.id); - }); - - it('finds keyring by both address and type', () => { - expect( - findKeyringId(mockKeyrings, mockMetadata, { - address: mockAddress3, - type: KeyringTypes.simple, - }), - ).toBe(mockSimpleKeyringMetadata.id); - }); - - it('throws error when no selector is provided', () => { - expect(() => findKeyringId(mockKeyrings, mockMetadata, {})).toThrow( - 'Must provide either address or type selector', - ); - }); - - it('throws error when keyring is not found', () => { - expect(() => - findKeyringId(mockKeyrings, mockMetadata, { - address: 'invalid-address', - }), - ).toThrow('Could not find keyring with specified criteria'); - }); - - it('throws error if not every selectors are matching', () => { - expect(() => - findKeyringId(mockKeyrings, mockMetadata, { - type: KeyringTypes.hd, - address: mockAddress3, - }), - ).toThrow('Could not find keyring with specified criteria'); - }); - }); - - describe('findKeyringIdByAddress', () => { - it('finds keyring by address', () => { - expect( - findKeyringIdByAddress(mockKeyrings, mockMetadata, mockAddress2), - ).toBe(mockHdKeyringMetadata.id); - }); - - it('throws error when address not found', () => { - expect(() => - findKeyringIdByAddress(mockKeyrings, mockMetadata, 'invalid-address'), - ).toThrow('Could not find keyring with specified criteria'); - }); - }); -}); diff --git a/shared/lib/keyring.ts b/shared/lib/keyring.ts deleted file mode 100644 index 4d7c923f236a..000000000000 --- a/shared/lib/keyring.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - KeyringObject, - KeyringMetadata, - KeyringTypes, -} from '@metamask/keyring-controller'; - -// TODO: This kind of logic should be inside the `KeyringController` (using `KeyringSelector` query, or make `addNewKeyring` returns it keyring ID alongside - -export function findKeyringId( - keyrings: KeyringObject[], - keyringsMetadata: KeyringMetadata[], - selector: { address?: string; type?: KeyringTypes }, -): string { - const keyringIndex = keyrings.findIndex((keyring) => { - if (selector.address && selector.type) { - return ( - keyring.accounts.includes(selector.address.toLowerCase()) && - keyring.type === selector.type - ); - } - if (selector.address) { - return keyring.accounts.includes(selector.address.toLowerCase()); - } - if (selector.type) { - return keyring.type === selector.type; - } - - throw new Error('Must provide either address or type selector'); - }); - if (keyringIndex === -1) { - throw new Error('Could not find keyring with specified criteria'); - } - - return keyringsMetadata[keyringIndex].id; -} - -export function findKeyringIdByAddress( - keyrings: KeyringObject[], - keyringsMetadata: KeyringMetadata[], - address: string, -): string { - return findKeyringId(keyrings, keyringsMetadata, { address }); -} diff --git a/yarn.lock b/yarn.lock index ca3aae2609aa..198e74f6c9f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5193,9 +5193,9 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-hd-keyring@npm:^10.0.0": - version: 10.0.0 - resolution: "@metamask/eth-hd-keyring@npm:10.0.0" +"@metamask/eth-hd-keyring@npm:^11.0.0": + version: 11.0.0 + resolution: "@metamask/eth-hd-keyring@npm:11.0.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@metamask/eth-sig-util": "npm:^8.2.0" @@ -5203,7 +5203,7 @@ __metadata: "@metamask/scure-bip39": "npm:^2.1.1" "@metamask/utils": "npm:^11.1.0" ethereum-cryptography: "npm:^2.1.2" - checksum: 10/d80611745171042f6ae7e0545e51563ebd705eb74e2bf131454766872d7ca57a54766af2ab398520a8fe0f58e8733a92c1df71664a2ea0e92c462661ea8a12f1 + checksum: 10/34e79c06740273518b653bfbef75371f2934ac1d73698f2a0f5f3e124300d5b43c86351f6989dc5aae5026ad2410171e75caabb7a14e9eacaea868f83be1b36d languageName: node linkType: hard @@ -5264,17 +5264,17 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-ledger-bridge-keyring@npm:^8.0.3": - version: 8.0.3 - resolution: "@metamask/eth-ledger-bridge-keyring@npm:8.0.3" +"@metamask/eth-ledger-bridge-keyring@npm:^9.0.0": + version: 9.0.0 + resolution: "@metamask/eth-ledger-bridge-keyring@npm:9.0.0" dependencies: "@ethereumjs/rlp": "npm:^5.0.2" "@ethereumjs/tx": "npm:^4.2.0" "@ethereumjs/util": "npm:^8.1.0" "@ledgerhq/hw-app-eth": "npm:^6.42.0" - "@metamask/eth-sig-util": "npm:^8.1.2" + "@metamask/eth-sig-util": "npm:^8.2.0" hdkey: "npm:^2.1.0" - checksum: 10/5b5c9f72eec882638985b11198350ace3647fa0ec92facbac3a9c1a67543a8270017c583d2d1464e2ec96cb93ff8b64509c0c8ebc395f8ce7de5ffd8f483ca63 + checksum: 10/dac1a4ff7c03ebb3c591035eb2cf0d4149ed1c1bb78baa02ed8b91e60884f91dc5639141bf4e69252974bf03217f15800401fe50c2953e3799dba30345b7c6e2 languageName: node linkType: hard @@ -5317,16 +5317,16 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-simple-keyring@npm:^8.1.0": - version: 8.1.1 - resolution: "@metamask/eth-simple-keyring@npm:8.1.1" +"@metamask/eth-simple-keyring@npm:^9.0.0": + version: 9.0.0 + resolution: "@metamask/eth-simple-keyring@npm:9.0.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@metamask/eth-sig-util": "npm:^8.2.0" "@metamask/utils": "npm:^11.1.0" ethereum-cryptography: "npm:^2.1.2" randombytes: "npm:^2.1.0" - checksum: 10/8fa7193625bedb58dffefac5120a72cd5864c18f94fae76fbe13f999f2d7bf063e95818702615942d8c9c56ecd460353fb34102a149503bdf7fdeaabcaca7d68 + checksum: 10/2f7062546288afcc986a7baf703fc518b1a26587d3675dddd97a0ea940b54020e8878b3aa94fc562bf96196e67aa5ff854b428de68eb8da65101868f4487d034 languageName: node linkType: hard @@ -5369,18 +5369,18 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-trezor-keyring@npm:^6.0.0": - version: 6.0.0 - resolution: "@metamask/eth-trezor-keyring@npm:6.0.0" +"@metamask/eth-trezor-keyring@npm:^6.1.1": + version: 6.1.1 + resolution: "@metamask/eth-trezor-keyring@npm:6.1.1" dependencies: "@ethereumjs/tx": "npm:^4.2.0" "@ethereumjs/util": "npm:^8.1.0" - "@metamask/eth-sig-util": "npm:^8.0.0" + "@metamask/eth-sig-util": "npm:^8.2.0" "@trezor/connect-plugin-ethereum": "npm:^9.0.3" "@trezor/connect-web": "npm:^9.1.11" hdkey: "npm:^2.1.0" tslib: "npm:^2.6.2" - checksum: 10/d5d799c60eeab963ef3e5533de472044b08b6f72652ecefbf26cec99784829bbcd706df57f6450ddb019c7dff7c41b0e0dad244aad62b7d03b51fc97755e2c4c + checksum: 10/b344be61ec81b8e4008d385f88d16fb68274cbe6bd7d76e66d832e6370e6eececbab42edd8cf598142dc0de7a647b5f93d6ec9be51aef3dcca4d548ba2e5bebe languageName: node linkType: hard @@ -5565,25 +5565,25 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-controller@npm:^19.2.0, @metamask/keyring-controller@npm:^19.2.1": - version: 19.2.1 - resolution: "@metamask/keyring-controller@npm:19.2.1" +"@metamask/keyring-controller@npm:^20.0.0": + version: 20.0.0 + resolution: "@metamask/keyring-controller@npm:20.0.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@keystonehq/metamask-airgapped-keyring": "npm:^0.14.1" "@metamask/base-controller": "npm:^8.0.0" "@metamask/browser-passworder": "npm:^4.3.0" - "@metamask/eth-hd-keyring": "npm:^10.0.0" + "@metamask/eth-hd-keyring": "npm:^11.0.0" "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/eth-simple-keyring": "npm:^8.1.0" + "@metamask/eth-simple-keyring": "npm:^9.0.0" "@metamask/keyring-api": "npm:^17.2.0" - "@metamask/keyring-internal-api": "npm:^4.0.3" + "@metamask/keyring-internal-api": "npm:^5.0.0" "@metamask/utils": "npm:^11.2.0" async-mutex: "npm:^0.5.0" ethereumjs-wallet: "npm:^1.0.1" immer: "npm:^9.0.6" ulid: "npm:^2.3.0" - checksum: 10/e9715a0743689c54843fd68f58ba1a577fd2f1a3ff104bd2e3d592c9246c56098f90288fab6c0d511e4a7115d2e9b835862885f37c3495aa2dd12db7df673326 + checksum: 10/cfddaed8d1548086ef7f4fb8fe6788a799378efdc8c99cf8277600ce491229d8a64614981273d2d2dbaa7e3803302d474db4ae76af75605027ca1962dbb9c709 languageName: node linkType: hard @@ -5599,6 +5599,17 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-internal-api@npm:^5.0.0": + version: 5.0.0 + resolution: "@metamask/keyring-internal-api@npm:5.0.0" + dependencies: + "@metamask/keyring-api": "npm:^17.2.1" + "@metamask/keyring-utils": "npm:^2.3.1" + "@metamask/superstruct": "npm:^3.1.0" + checksum: 10/1c691c6343691ef19c1cea6a353cbb325dbad7b10462d17139365151dc23a7f0aa74eecb9e8787a4472cc5d73424c1e050d0efb5a3b68c59c766adede40b9ea2 + languageName: node + linkType: hard + "@metamask/keyring-internal-snap-client@npm:^4.0.1": version: 4.0.1 resolution: "@metamask/keyring-internal-snap-client@npm:4.0.1" @@ -6033,13 +6044,13 @@ __metadata: languageName: node linkType: hard -"@metamask/profile-sync-controller@npm:^8.1.1": - version: 8.1.1 - resolution: "@metamask/profile-sync-controller@npm:8.1.1" +"@metamask/profile-sync-controller@npm:^9.0.0": + version: 9.0.0 + resolution: "@metamask/profile-sync-controller@npm:9.0.0" dependencies: "@metamask/base-controller": "npm:^8.0.0" "@metamask/keyring-api": "npm:^17.2.0" - "@metamask/keyring-controller": "npm:^19.2.1" + "@metamask/keyring-controller": "npm:^20.0.0" "@metamask/network-controller": "npm:^22.2.1" "@metamask/snaps-sdk": "npm:^6.17.1" "@metamask/snaps-utils": "npm:^8.10.0" @@ -6049,13 +6060,13 @@ __metadata: loglevel: "npm:^1.8.1" siwe: "npm:^2.3.2" peerDependencies: - "@metamask/accounts-controller": ^24.0.0 - "@metamask/keyring-controller": ^19.0.0 + "@metamask/accounts-controller": ^25.0.0 + "@metamask/keyring-controller": ^20.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/providers": ^18.1.0 "@metamask/snaps-controllers": ^9.19.0 webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/4b18a546c0d78f010fbf1cf16644001ba0139c60941ceb70b83c7850e2fafcd5d17b8148f8020dcfe0e8c3f897259480077fa6b4402f4d270ed68e248d628369 + checksum: 10/bcfb112b5352ccb6d6534320084ce12a1e738e97ad683bb3fb9bc4672bfd570e76ff61dd714cb31482b77b9990eea688192db54c568ab83c1a909e1d2b07383c languageName: node linkType: hard @@ -27270,11 +27281,11 @@ __metadata: "@metamask/eth-json-rpc-filters": "npm:^9.0.0" "@metamask/eth-json-rpc-middleware": "npm:^15.1.2" "@metamask/eth-json-rpc-provider": "npm:^4.1.6" - "@metamask/eth-ledger-bridge-keyring": "npm:^8.0.3" + "@metamask/eth-ledger-bridge-keyring": "npm:^9.0.0" "@metamask/eth-sig-util": "npm:^7.0.1" "@metamask/eth-snap-keyring": "npm:^11.1.0" "@metamask/eth-token-tracker": "npm:^10.0.2" - "@metamask/eth-trezor-keyring": "npm:^6.0.0" + "@metamask/eth-trezor-keyring": "npm:^6.1.1" "@metamask/etherscan-link": "npm:^3.0.0" "@metamask/forwarder": "npm:^1.1.0" "@metamask/gas-fee-controller": "npm:^22.0.3" @@ -27282,8 +27293,8 @@ __metadata: "@metamask/json-rpc-engine": "npm:^10.0.0" "@metamask/json-rpc-middleware-stream": "npm:^8.0.4" "@metamask/keyring-api": "npm:^17.2.1" - "@metamask/keyring-controller": "npm:^19.2.0" - "@metamask/keyring-internal-api": "npm:^4.0.3" + "@metamask/keyring-controller": "npm:^20.0.0" + "@metamask/keyring-internal-api": "npm:^5.0.0" "@metamask/keyring-snap-client": "npm:^4.0.1" "@metamask/logging-controller": "npm:^6.0.4" "@metamask/logo": "npm:^4.0.0" @@ -27307,7 +27318,7 @@ __metadata: "@metamask/ppom-validator": "npm:0.36.0" "@metamask/preferences-controller": "npm:^15.0.2" "@metamask/preinstalled-example-snap": "npm:^0.3.0" - "@metamask/profile-sync-controller": "npm:^8.1.1" + "@metamask/profile-sync-controller": "npm:^9.0.0" "@metamask/providers": "npm:^20.0.0" "@metamask/queued-request-controller": "npm:^7.0.1" "@metamask/rate-limit-controller": "npm:^6.0.3" From da1c33ed9973c4c096271220b778839bf754fb7f Mon Sep 17 00:00:00 2001 From: Mathieu Artu Date: Fri, 7 Mar 2025 11:57:17 +0100 Subject: [PATCH 04/17] feat: migrate profile sync controllers to the controller init pattern (#30805) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This PR migrates `AuthenticationController` and `UserStorageController` to the new controller init pattern. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30805?quickstart=1) ## **Related issues** Fixes: - https://consensyssoftware.atlassian.net/browse/IDENTITY-54 - https://consensyssoftware.atlassian.net/browse/IDENTITY-46 Related to: - https://github.com/MetaMask/metamask-extension/issues/29517 ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../controller-init/controller-list.ts | 10 +- .../authentication-controller-init.test.ts | 56 +++++++++ .../authentication-controller-init.ts | 34 ++++++ .../user-storage-controller-init.test.ts | 67 +++++++++++ .../identity/user-storage-controller-init.ts | 80 +++++++++++++ ...uthentication-controller-messenger.test.ts | 14 +++ .../authentication-controller-messenger.ts | 37 ++++++ .../messengers/identity/index.ts | 5 + .../user-storage-controller-messenger.test.ts | 12 ++ .../user-storage-controller-messenger.ts | 107 ++++++++++++++++++ .../controller-init/messengers/index.ts | 12 ++ app/scripts/controller-init/test/utils.ts | 2 + app/scripts/controller-init/types.ts | 20 ++++ app/scripts/controller-init/utils.ts | 4 +- app/scripts/metamask-controller.js | 107 +++--------------- 15 files changed, 470 insertions(+), 97 deletions(-) create mode 100644 app/scripts/controller-init/identity/authentication-controller-init.test.ts create mode 100644 app/scripts/controller-init/identity/authentication-controller-init.ts create mode 100644 app/scripts/controller-init/identity/user-storage-controller-init.test.ts create mode 100644 app/scripts/controller-init/identity/user-storage-controller-init.ts create mode 100644 app/scripts/controller-init/messengers/identity/authentication-controller-messenger.test.ts create mode 100644 app/scripts/controller-init/messengers/identity/authentication-controller-messenger.ts create mode 100644 app/scripts/controller-init/messengers/identity/index.ts create mode 100644 app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.test.ts create mode 100644 app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.ts diff --git a/app/scripts/controller-init/controller-list.ts b/app/scripts/controller-init/controller-list.ts index 07983f876376..bd82ebd27b10 100644 --- a/app/scripts/controller-init/controller-list.ts +++ b/app/scripts/controller-init/controller-list.ts @@ -30,6 +30,8 @@ import { RateLimitController, RateLimitedApiMap, } from '@metamask/rate-limit-controller'; +import { Controller as AuthenticationController } from '@metamask/profile-sync-controller/auth'; +import { Controller as UserStorageController } from '@metamask/profile-sync-controller/user-storage'; import OnboardingController from '../controllers/onboarding'; import { PreferencesController } from '../controllers/preferences-controller'; import SwapsController from '../controllers/swaps'; @@ -38,6 +40,7 @@ import SwapsController from '../controllers/swaps'; * Union of all controllers supporting or required by modular initialization. */ export type Controller = + | AuthenticationController | CronjobController | ExecutionService | GasFeeController @@ -65,13 +68,15 @@ export type Controller = | (TransactionUpdateController & { name: 'TransactionUpdateController'; state: Record; - }); + }) + | UserStorageController; /** * Flat state object for all controllers supporting or required by modular initialization. * e.g. `{ transactions: [] }`. */ export type ControllerFlatState = AccountsController['state'] & + AuthenticationController['state'] & CronjobController['state'] & GasFeeController['state'] & JsonSnapsRegistry['state'] & @@ -94,4 +99,5 @@ export type ControllerFlatState = AccountsController['state'] & SnapInsightsController['state'] & SnapInterfaceController['state'] & TransactionController['state'] & - SwapsController['state']; + SwapsController['state'] & + UserStorageController['state']; diff --git a/app/scripts/controller-init/identity/authentication-controller-init.test.ts b/app/scripts/controller-init/identity/authentication-controller-init.test.ts new file mode 100644 index 000000000000..a94f19e828d7 --- /dev/null +++ b/app/scripts/controller-init/identity/authentication-controller-init.test.ts @@ -0,0 +1,56 @@ +import { Controller as AuthenticationController } from '@metamask/profile-sync-controller/auth'; +import { Messenger } from '@metamask/base-controller'; +import { buildControllerInitRequestMock } from '../test/utils'; +import { ControllerInitRequest } from '../types'; +import { + getAuthenticationControllerMessenger, + AuthenticationControllerMessenger, +} from '../messengers/identity'; +import { AuthenticationControllerInit } from './authentication-controller-init'; + +jest.mock('@metamask/profile-sync-controller/auth'); + +function buildInitRequestMock(): jest.Mocked< + ControllerInitRequest +> { + const baseControllerMessenger = new Messenger(); + + return { + ...buildControllerInitRequestMock(), + controllerMessenger: getAuthenticationControllerMessenger( + baseControllerMessenger, + ), + initMessenger: undefined, + }; +} + +describe('AuthenticationControllerInit', () => { + const AuthenticationControllerClassMock = jest.mocked( + AuthenticationController, + ); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('returns controller instance', () => { + const requestMock = buildInitRequestMock(); + expect(AuthenticationControllerInit(requestMock).controller).toBeInstanceOf( + AuthenticationController, + ); + }); + + it('initializes with correct messenger and state', () => { + const requestMock = buildInitRequestMock(); + AuthenticationControllerInit(requestMock); + + expect(AuthenticationControllerClassMock).toHaveBeenCalledWith({ + messenger: requestMock.controllerMessenger, + state: requestMock.persistedState.AuthenticationController, + metametrics: { + getMetaMetricsId: requestMock.getMetaMetricsId, + agent: 'extension', + }, + }); + }); +}); diff --git a/app/scripts/controller-init/identity/authentication-controller-init.ts b/app/scripts/controller-init/identity/authentication-controller-init.ts new file mode 100644 index 000000000000..d09edd8dbb0c --- /dev/null +++ b/app/scripts/controller-init/identity/authentication-controller-init.ts @@ -0,0 +1,34 @@ +import { + AuthenticationControllerState, + Controller as AuthenticationController, +} from '@metamask/profile-sync-controller/auth'; +import { ControllerInitFunction } from '../types'; +import { AuthenticationControllerMessenger } from '../messengers/identity'; + +/** + * Initialize the Authentication controller. + * + * @param request - The request object. + * @param request.controllerMessenger - The messenger to use for the controller. + * @param request.persistedState - The persisted state of the extension. + * @param request.getMetaMetricsId + * @returns The initialized controller. + */ +export const AuthenticationControllerInit: ControllerInitFunction< + AuthenticationController, + AuthenticationControllerMessenger +> = ({ controllerMessenger, persistedState, getMetaMetricsId }) => { + const controller = new AuthenticationController({ + messenger: controllerMessenger, + state: + persistedState.AuthenticationController as AuthenticationControllerState, + metametrics: { + getMetaMetricsId, + agent: 'extension', + }, + }); + + return { + controller, + }; +}; diff --git a/app/scripts/controller-init/identity/user-storage-controller-init.test.ts b/app/scripts/controller-init/identity/user-storage-controller-init.test.ts new file mode 100644 index 000000000000..2abf4504502e --- /dev/null +++ b/app/scripts/controller-init/identity/user-storage-controller-init.test.ts @@ -0,0 +1,67 @@ +import { Controller as UserStorageController } from '@metamask/profile-sync-controller/user-storage'; +import { Messenger } from '@metamask/base-controller'; +import { buildControllerInitRequestMock } from '../test/utils'; +import { ControllerInitRequest } from '../types'; +import { + getUserStorageControllerMessenger, + UserStorageControllerMessenger, +} from '../messengers/identity'; +import { UserStorageControllerInit } from './user-storage-controller-init'; + +jest.mock('@metamask/profile-sync-controller/user-storage'); +jest.mock('../../../../shared/modules/mv3.utils', () => ({ + isManifestV3: true, +})); +jest.mock('../../../../shared/modules/environment', () => ({ + isProduction: () => false, +})); + +function buildInitRequestMock(): jest.Mocked< + ControllerInitRequest +> { + const baseControllerMessenger = new Messenger(); + + return { + ...buildControllerInitRequestMock(), + controllerMessenger: getUserStorageControllerMessenger( + baseControllerMessenger, + ), + initMessenger: undefined, + }; +} + +describe('UserStorageControllerInit', () => { + const UserStorageControllerClassMock = jest.mocked(UserStorageController); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('returns controller instance', () => { + const requestMock = buildInitRequestMock(); + expect(UserStorageControllerInit(requestMock).controller).toBeInstanceOf( + UserStorageController, + ); + }); + + it('initializes with correct messenger and state', () => { + const requestMock = buildInitRequestMock(); + UserStorageControllerInit(requestMock); + + expect(UserStorageControllerClassMock).toHaveBeenCalledWith({ + messenger: requestMock.controllerMessenger, + state: requestMock.persistedState.UserStorageController, + config: { + accountSyncing: { + maxNumberOfAccountsToAdd: 100, + onAccountAdded: expect.any(Function), + onAccountNameUpdated: expect.any(Function), + onAccountSyncErroneousSituation: expect.any(Function), + }, + }, + env: { + isAccountSyncingEnabled: true, + }, + }); + }); +}); diff --git a/app/scripts/controller-init/identity/user-storage-controller-init.ts b/app/scripts/controller-init/identity/user-storage-controller-init.ts new file mode 100644 index 000000000000..cea7ce0653de --- /dev/null +++ b/app/scripts/controller-init/identity/user-storage-controller-init.ts @@ -0,0 +1,80 @@ +import { + UserStorageControllerMessenger, + UserStorageControllerState, + Controller as UserStorageController, +} from '@metamask/profile-sync-controller/user-storage'; +import { captureException } from '@sentry/browser'; +import { ControllerInitFunction } from '../types'; +import { isProduction } from '../../../../shared/modules/environment'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; +import { isManifestV3 } from '../../../../shared/modules/mv3.utils'; + +/** + * Initialize the UserStorage controller. + * + * @param request - The request object. + * @param request.controllerMessenger - The messenger to use for the controller. + * @param request.persistedState - The persisted state of the extension. + * @returns The initialized controller. + */ +export const UserStorageControllerInit: ControllerInitFunction< + UserStorageController, + UserStorageControllerMessenger +> = (request) => { + const { controllerMessenger, persistedState, trackEvent } = request; + const controller = new UserStorageController({ + messenger: controllerMessenger, + state: persistedState.UserStorageController as UserStorageControllerState, + config: { + accountSyncing: { + maxNumberOfAccountsToAdd: isProduction() ? undefined : 100, + onAccountAdded: (profileId) => { + trackEvent({ + category: MetaMetricsEventCategory.ProfileSyncing, + event: MetaMetricsEventName.AccountsSyncAdded, + properties: { + profile_id: profileId, + }, + }); + }, + onAccountNameUpdated: (profileId) => { + trackEvent({ + category: MetaMetricsEventCategory.ProfileSyncing, + event: MetaMetricsEventName.AccountsSyncNameUpdated, + properties: { + profile_id: profileId, + }, + }); + }, + onAccountSyncErroneousSituation: ( + profileId, + situationMessage, + sentryContext, + ) => { + captureException( + new Error(`Account sync - ${situationMessage}`), + sentryContext, + ); + trackEvent({ + category: MetaMetricsEventCategory.ProfileSyncing, + event: MetaMetricsEventName.AccountsSyncErroneousSituation, + properties: { + profile_id: profileId, + situation_message: situationMessage, + }, + }); + }, + }, + }, + env: { + isAccountSyncingEnabled: isManifestV3, + }, + }); + + return { + controller, + }; +}; diff --git a/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.test.ts b/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.test.ts new file mode 100644 index 000000000000..0ae9857d39f0 --- /dev/null +++ b/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.test.ts @@ -0,0 +1,14 @@ +import { Messenger, RestrictedMessenger } from '@metamask/base-controller'; +import { getAuthenticationControllerMessenger } from './authentication-controller-messenger'; + +describe('getAuthenticationControllerMessenger', () => { + it('returns a restricted messenger', () => { + const messenger = new Messenger(); + const authenticationControllerMessenger = + getAuthenticationControllerMessenger(messenger); + + expect(authenticationControllerMessenger).toBeInstanceOf( + RestrictedMessenger, + ); + }); +}); diff --git a/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.ts b/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.ts new file mode 100644 index 000000000000..55d749070ad4 --- /dev/null +++ b/app/scripts/controller-init/messengers/identity/authentication-controller-messenger.ts @@ -0,0 +1,37 @@ +import { Messenger } from '@metamask/base-controller'; +import { + KeyringControllerGetStateAction, + KeyringControllerLockEvent, + KeyringControllerUnlockEvent, +} from '@metamask/keyring-controller'; +import { HandleSnapRequest } from '@metamask/snaps-controllers'; + +type MessengerActions = KeyringControllerGetStateAction | HandleSnapRequest; + +type MessengerEvents = + | KeyringControllerLockEvent + | KeyringControllerUnlockEvent; + +export type AuthenticationControllerMessenger = ReturnType< + typeof getAuthenticationControllerMessenger +>; + +/** + * Get a restricted messenger for the Authentication controller. This is scoped to the + * actions and events that the Authentication controller is allowed to handle. + * + * @param messenger - The messenger to restrict. + * @returns The restricted messenger. + */ +export function getAuthenticationControllerMessenger( + messenger: Messenger, +) { + return messenger.getRestricted({ + name: 'AuthenticationController', + allowedActions: [ + 'KeyringController:getState', + 'SnapController:handleRequest', + ], + allowedEvents: ['KeyringController:lock', 'KeyringController:unlock'], + }); +} diff --git a/app/scripts/controller-init/messengers/identity/index.ts b/app/scripts/controller-init/messengers/identity/index.ts new file mode 100644 index 000000000000..444363b3bb3e --- /dev/null +++ b/app/scripts/controller-init/messengers/identity/index.ts @@ -0,0 +1,5 @@ +export { getAuthenticationControllerMessenger } from './authentication-controller-messenger'; +export type { AuthenticationControllerMessenger } from './authentication-controller-messenger'; + +export { getUserStorageControllerMessenger } from './user-storage-controller-messenger'; +export type { UserStorageControllerMessenger } from './user-storage-controller-messenger'; diff --git a/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.test.ts b/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.test.ts new file mode 100644 index 000000000000..e8e1f3e1ffd0 --- /dev/null +++ b/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.test.ts @@ -0,0 +1,12 @@ +import { Messenger, RestrictedMessenger } from '@metamask/base-controller'; +import { getUserStorageControllerMessenger } from './user-storage-controller-messenger'; + +describe('getUserStorageControllerMessenger', () => { + it('returns a restricted messenger', () => { + const messenger = new Messenger(); + const userStorageControllerMessenger = + getUserStorageControllerMessenger(messenger); + + expect(userStorageControllerMessenger).toBeInstanceOf(RestrictedMessenger); + }); +}); diff --git a/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.ts b/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.ts new file mode 100644 index 000000000000..6eb82b061779 --- /dev/null +++ b/app/scripts/controller-init/messengers/identity/user-storage-controller-messenger.ts @@ -0,0 +1,107 @@ +import type { UserStorageControllerStateChangeEvent } from '@metamask/profile-sync-controller/user-storage'; +import { Messenger } from '@metamask/base-controller'; +import { + KeyringControllerGetStateAction, + KeyringControllerLockEvent, + KeyringControllerUnlockEvent, + KeyringControllerWithKeyringAction, +} from '@metamask/keyring-controller'; +import { HandleSnapRequest } from '@metamask/snaps-controllers'; +import { + AuthenticationControllerGetBearerToken, + AuthenticationControllerGetSessionProfile, + AuthenticationControllerIsSignedIn, + AuthenticationControllerPerformSignIn, +} from '@metamask/profile-sync-controller/auth'; +import { + AccountsControllerAccountAddedEvent, + AccountsControllerAccountRenamedEvent, + AccountsControllerListAccountsAction, + AccountsControllerUpdateAccountMetadataAction, +} from '@metamask/accounts-controller'; +import { + NetworkControllerAddNetworkAction, + NetworkControllerGetStateAction, + NetworkControllerNetworkRemovedEvent, + NetworkControllerRemoveNetworkAction, + NetworkControllerUpdateNetworkAction, +} from '@metamask/network-controller'; + +type MessengerActions = + // Keyring Requests + | KeyringControllerGetStateAction + // Snap Requests + | HandleSnapRequest + // Auth Requests + | AuthenticationControllerGetBearerToken + | AuthenticationControllerGetSessionProfile + | AuthenticationControllerPerformSignIn + | AuthenticationControllerIsSignedIn + // Account Syncing + | AccountsControllerListAccountsAction + | AccountsControllerUpdateAccountMetadataAction + | KeyringControllerWithKeyringAction + // Network Syncing + | NetworkControllerGetStateAction + | NetworkControllerAddNetworkAction + | NetworkControllerRemoveNetworkAction + | NetworkControllerUpdateNetworkAction; + +type MessengerEvents = + | UserStorageControllerStateChangeEvent + | KeyringControllerLockEvent + | KeyringControllerUnlockEvent + // Account Syncing Events + | AccountsControllerAccountAddedEvent + | AccountsControllerAccountRenamedEvent + // Network Syncing Events + | NetworkControllerNetworkRemovedEvent; + +export type UserStorageControllerMessenger = ReturnType< + typeof getUserStorageControllerMessenger +>; + +/** + * Get a restricted messenger for the User Storage controller. This is scoped to the + * actions and events that the User Storage controller is allowed to handle. + * + * @param messenger - The messenger to restrict. + * @returns The restricted messenger. + */ +export function getUserStorageControllerMessenger( + messenger: Messenger, +) { + return messenger.getRestricted({ + name: 'UserStorageController', + allowedActions: [ + // Keyring Controller Requests + 'KeyringController:getState', + 'KeyringController:withKeyring', + // Snap Controller Requests + 'SnapController:handleRequest', + // Auth Controller Requests + 'AuthenticationController:getBearerToken', + 'AuthenticationController:getSessionProfile', + 'AuthenticationController:isSignedIn', + 'AuthenticationController:performSignIn', + // Accounts Controller Requests + 'AccountsController:listAccounts', + 'AccountsController:updateAccountMetadata', + // Network Controller Requests + 'NetworkController:getState', + 'NetworkController:addNetwork', + 'NetworkController:removeNetwork', + 'NetworkController:updateNetwork', + ], + allowedEvents: [ + // Keyring Controller Events + 'KeyringController:lock', + 'KeyringController:unlock', + // Accounts Controller Events + 'AccountsController:accountAdded', + 'AccountsController:accountRenamed', + // Network Controller Events + 'NetworkController:networkRemoved', + ], + }); +} diff --git a/app/scripts/controller-init/messengers/index.ts b/app/scripts/controller-init/messengers/index.ts index 92eba17c9066..41e810cc4725 100644 --- a/app/scripts/controller-init/messengers/index.ts +++ b/app/scripts/controller-init/messengers/index.ts @@ -25,8 +25,16 @@ import { getMultichainNetworkControllerMessenger, getMultichainAssetsRatesControllerMessenger, } from './multichain'; +import { + getAuthenticationControllerMessenger, + getUserStorageControllerMessenger, +} from './identity'; export const CONTROLLER_MESSENGERS = { + AuthenticationController: { + getMessenger: getAuthenticationControllerMessenger, + getInitMessenger: noop, + }, CronjobController: { getMessenger: getCronjobControllerMessenger, getInitMessenger: noop, @@ -82,4 +90,8 @@ export const CONTROLLER_MESSENGERS = { getMessenger: getTransactionControllerMessenger, getInitMessenger: getTransactionControllerInitMessenger, }, + UserStorageController: { + getMessenger: getUserStorageControllerMessenger, + getInitMessenger: noop, + }, } as const; diff --git a/app/scripts/controller-init/test/utils.ts b/app/scripts/controller-init/test/utils.ts index e050a99579c7..93b105d3cc0d 100644 --- a/app/scripts/controller-init/test/utils.ts +++ b/app/scripts/controller-init/test/utils.ts @@ -26,5 +26,7 @@ export function buildControllerInitRequestMock(): jest.Mocked< removeAllConnections: jest.fn(), setupUntrustedCommunicationEip1193: jest.fn(), showNotification: jest.fn(), + trackEvent: jest.fn(), + getMetaMetricsId: jest.fn(), }; } diff --git a/app/scripts/controller-init/types.ts b/app/scripts/controller-init/types.ts index 9af50172feea..67f35d3da8e6 100644 --- a/app/scripts/controller-init/types.ts +++ b/app/scripts/controller-init/types.ts @@ -10,6 +10,10 @@ import { Duplex } from 'readable-stream'; import { SubjectType } from '@metamask/permission-controller'; import type { TransactionMetricsRequest } from '../../../shared/types/metametrics'; import { MessageSender } from '../../../types/global'; +import { + MetaMetricsEventOptions, + MetaMetricsEventPayload, +} from '../../../shared/constants/metametrics'; import { Controller, ControllerFlatState } from './controller-list'; /** The supported controller names. */ @@ -162,6 +166,22 @@ export type ControllerInitRequest< url?: string, ) => Promise; + /** + * Get the MetaMetrics ID. + */ + getMetaMetricsId: () => string; + + /** + * submits a metametrics event, not waiting for it to complete or allowing its error to bubble up + * + * @param payload - details of the event + * @param options - options for handling/routing the event + */ + trackEvent: ( + payload: MetaMetricsEventPayload, + options?: MetaMetricsEventOptions, + ) => void; + /** * Required initialization messenger instance. * Generated using the callback specified in `getInitMessengerCallback`. diff --git a/app/scripts/controller-init/utils.ts b/app/scripts/controller-init/utils.ts index a17de8e09aa5..6903d0197d53 100644 --- a/app/scripts/controller-init/utils.ts +++ b/app/scripts/controller-init/utils.ts @@ -37,6 +37,7 @@ type ControllerMessengerCallback = ( ) => BaseRestrictedControllerMessenger; export type ControllersToInitialize = + | 'AuthenticationController' | 'CronjobController' | 'ExecutionService' | 'MultichainAssetsController' @@ -49,7 +50,8 @@ export type ControllersToInitialize = | 'SnapInsightsController' | 'SnapInterfaceController' | 'PPOMController' - | 'TransactionController'; + | 'TransactionController' + | 'UserStorageController'; type InitFunction = ControllerInitFunction< diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index aae868639481..1fa62e13ad87 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -136,10 +136,7 @@ import { abiERC1155, abiERC721 } from '@metamask/metamask-eth-abis'; import { isEvmAccountType } from '@metamask/keyring-api'; import { hexToBigInt, toCaipChainId } from '@metamask/utils'; import { normalize } from '@metamask/eth-sig-util'; -import { - AuthenticationController, - UserStorageController, -} from '@metamask/profile-sync-controller'; + import { TRIGGER_TYPES, Controller as NotificationServicesController, @@ -242,7 +239,6 @@ import { BridgeUserAction, BridgeBackgroundAction, } from '../../shared/types/bridge'; -import { isProduction } from '../../shared/modules/environment'; import { ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) handleMMITransactionUpdate, @@ -375,6 +371,8 @@ import { SnapInterfaceControllerInit, SnapsRegistryInit, } from './controller-init/snaps'; +import { AuthenticationControllerInit } from './controller-init/identity/authentication-controller-init'; +import { UserStorageControllerInit } from './controller-init/identity/user-storage-controller-init'; export const METAMASK_CONTROLLER_EVENTS = { // Fired after state changes that impact the extension badge (unapproved msg count) @@ -1253,95 +1251,6 @@ export default class MetamaskController extends EventEmitter { }); // Notification Controllers - this.authenticationController = new AuthenticationController.Controller({ - state: initState.AuthenticationController, - messenger: this.controllerMessenger.getRestricted({ - name: 'AuthenticationController', - allowedActions: [ - 'KeyringController:getState', - 'SnapController:handleRequest', - ], - allowedEvents: ['KeyringController:lock', 'KeyringController:unlock'], - }), - metametrics: { - getMetaMetricsId: () => this.metaMetricsController.getMetaMetricsId(), - agent: 'extension', - }, - }); - - this.userStorageController = new UserStorageController.Controller({ - state: initState.UserStorageController, - config: { - accountSyncing: { - maxNumberOfAccountsToAdd: isProduction() ? undefined : 100, - onAccountAdded: (profileId) => { - this.metaMetricsController.trackEvent({ - category: MetaMetricsEventCategory.ProfileSyncing, - event: MetaMetricsEventName.AccountsSyncAdded, - properties: { - profile_id: profileId, - }, - }); - }, - onAccountNameUpdated: (profileId) => { - this.metaMetricsController.trackEvent({ - category: MetaMetricsEventCategory.ProfileSyncing, - event: MetaMetricsEventName.AccountsSyncNameUpdated, - properties: { - profile_id: profileId, - }, - }); - }, - onAccountSyncErroneousSituation: ( - profileId, - situationMessage, - sentryContext, - ) => { - captureException( - new Error(`Account sync - ${situationMessage}`), - sentryContext, - ); - this.metaMetricsController.trackEvent({ - category: MetaMetricsEventCategory.ProfileSyncing, - event: MetaMetricsEventName.AccountsSyncErroneousSituation, - properties: { - profile_id: profileId, - situation_message: situationMessage, - }, - }); - }, - }, - }, - env: { - isAccountSyncingEnabled: isManifestV3, - }, - messenger: this.controllerMessenger.getRestricted({ - name: 'UserStorageController', - allowedActions: [ - 'KeyringController:getState', - 'KeyringController:withKeyring', - 'SnapController:handleRequest', - 'AuthenticationController:getBearerToken', - 'AuthenticationController:getSessionProfile', - 'AuthenticationController:isSignedIn', - 'AuthenticationController:performSignOut', - 'AuthenticationController:performSignIn', - 'AccountsController:listAccounts', - 'AccountsController:updateAccountMetadata', - 'NetworkController:getState', - 'NetworkController:addNetwork', - 'NetworkController:removeNetwork', - 'NetworkController:updateNetwork', - ], - allowedEvents: [ - 'KeyringController:lock', - 'KeyringController:unlock', - 'AccountsController:accountAdded', - 'AccountsController:accountRenamed', - 'NetworkController:networkRemoved', - ], - }), - }); /** @type {import('@metamask/notification-services-controller/push-services').NotificationServicesPushControllerMessenger} */ const notificationServicesPushControllerMessenger = @@ -2044,6 +1953,8 @@ export default class MetamaskController extends EventEmitter { MultichainTransactionsController: MultichainTransactionsControllerInit, ///: END:ONLY_INCLUDE_IF MultichainNetworkController: MultichainNetworkControllerInit, + AuthenticationController: AuthenticationControllerInit, + UserStorageController: UserStorageControllerInit, }; const { @@ -2083,6 +1994,8 @@ export default class MetamaskController extends EventEmitter { ///: END:ONLY_INCLUDE_IF this.multichainNetworkController = controllersByName.MultichainNetworkController; + this.authenticationController = controllersByName.AuthenticationController; + this.userStorageController = controllersByName.UserStorageController; this.controllerMessenger.subscribe( 'TransactionController:transactionStatusUpdated', @@ -7665,6 +7578,12 @@ export default class MetamaskController extends EventEmitter { setupUntrustedCommunicationEip1193: this.setupUntrustedCommunicationEip1193.bind(this), showNotification: this.platform._showNotification, + getMetaMetricsId: this.metaMetricsController.getMetaMetricsId.bind( + this.metaMetricsController, + ), + trackEvent: this.metaMetricsController.trackEvent.bind( + this.metaMetricsController, + ), }; return initControllers({ From 32c9974a47c473d6c30c3665ecfc775c8becadd3 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Fri, 7 Mar 2025 11:52:36 +0000 Subject: [PATCH 05/17] chore: bump ethereumjs (#30716) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Upgrade all `@ethereumjs/*` packages including the keyrings and `KeyringController` since they depend on `ethereumjs` packages internally. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30716?quickstart=1) ## **Related issues** ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: Michele Esposito Co-authored-by: MetaMask Bot Co-authored-by: Michele Esposito <34438276+mikesposito@users.noreply.github.com> --- .../transaction-controller-init.test.ts | 1 - .../transaction-controller-init.ts | 2 - .../transaction-controller-messenger.ts | 1 - lavamoat/browserify/beta/policy.json | 360 +++++++++++++---- lavamoat/browserify/flask/policy.json | 360 +++++++++++++---- lavamoat/browserify/main/policy.json | 360 +++++++++++++---- lavamoat/browserify/mmi/policy.json | 366 ++++++++++++++---- package.json | 16 +- test/stub/keyring-bridge.js | 16 +- test/stub/keyring-utils.js | 1 + yarn.lock | 209 ++++++---- 11 files changed, 1312 insertions(+), 380 deletions(-) diff --git a/app/scripts/controller-init/confirmations/transaction-controller-init.test.ts b/app/scripts/controller-init/confirmations/transaction-controller-init.test.ts index ff46b277fac1..155f41e29ba9 100644 --- a/app/scripts/controller-init/confirmations/transaction-controller-init.test.ts +++ b/app/scripts/controller-init/confirmations/transaction-controller-init.test.ts @@ -39,7 +39,6 @@ function buildControllerMock( function buildInitRequestMock(): jest.Mocked< ControllerInitRequest< - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. TransactionControllerMessenger, TransactionControllerInitMessenger > diff --git a/app/scripts/controller-init/confirmations/transaction-controller-init.ts b/app/scripts/controller-init/confirmations/transaction-controller-init.ts index ea252f2f6439..57103bc365bc 100644 --- a/app/scripts/controller-init/confirmations/transaction-controller-init.ts +++ b/app/scripts/controller-init/confirmations/transaction-controller-init.ts @@ -48,7 +48,6 @@ import { TransactionMetricsRequest } from '../../../../shared/types/metametrics' export const TransactionControllerInit: ControllerInitFunction< TransactionController, - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. TransactionControllerMessenger, TransactionControllerInitMessenger > = (request) => { @@ -189,7 +188,6 @@ function getApi( function getControllers( request: ControllerInitRequest< - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. TransactionControllerMessenger, TransactionControllerInitMessenger >, diff --git a/app/scripts/controller-init/messengers/transaction-controller-messenger.ts b/app/scripts/controller-init/messengers/transaction-controller-messenger.ts index ad6eecac45bb..e9cef872c80d 100644 --- a/app/scripts/controller-init/messengers/transaction-controller-messenger.ts +++ b/app/scripts/controller-init/messengers/transaction-controller-messenger.ts @@ -56,7 +56,6 @@ export type TransactionControllerInitMessenger = ReturnType< export function getTransactionControllerMessenger( messenger: Messenger, ): TransactionControllerMessenger { - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. return messenger.getRestricted({ name: 'TransactionController', allowedActions: [ diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 32228a0ea8fc..9fdff5d7b884 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -40,31 +40,47 @@ }, "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": true, + "webpack>events": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, + "webpack>events": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, @@ -73,7 +89,42 @@ "TextEncoder": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": { "globals": { "TextEncoder": true } @@ -93,25 +144,35 @@ "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": { + "packages": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "eth-lattice-keyring>@ethereumjs/tx": { "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, @@ -122,25 +183,165 @@ "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, "@ethereumjs/tx>@ethereumjs/util": { "globals": { - "console.warn": true + "console.warn": true, + "fetch": true }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/controller-utils>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, "@metamask/smart-transactions-controller>@ethereumjs/util": { @@ -149,11 +350,24 @@ "fetch": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true } }, + "eth-lattice-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, "@ethersproject/abi": { "globals": { "console.log": true @@ -622,8 +836,8 @@ }, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -633,7 +847,7 @@ }, "@keystonehq/bc-ur-registry-eth": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -654,7 +868,7 @@ }, "@keystonehq/metamask-airgapped-keyring": { "packages": { - "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": true, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, "@keystonehq/bc-ur-registry-eth": true, "@metamask/obs-store": true, @@ -875,12 +1089,11 @@ }, "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/eth-snap-keyring": true, "@metamask/keyring-api": true, "@metamask/keyring-controller": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/accounts-controller>@metamask/keyring-utils": true, "@metamask/utils": true, "@ethereumjs/tx>ethereum-cryptography": true, "uuid": true @@ -921,7 +1134,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "ethers>@ethersproject/address": true, "@ethersproject/bignumber": true, "@ethersproject/contracts": true, @@ -1002,14 +1215,6 @@ "immer": true } }, - "@metamask/transaction-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, "@metamask/browser-passworder": { "globals": { "CryptoKey": true, @@ -1039,7 +1244,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@ethereumjs/util": true, "@metamask/controller-utils>@metamask/ethjs-unit": true, "@metamask/utils": true, "@metamask/controller-utils>@spruceid/siwe-parser": true, @@ -1076,7 +1281,7 @@ "TextEncoder": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": true, "@metamask/snaps-sdk>@metamask/key-tree": true, "@metamask/scure-bip39": true, @@ -1144,7 +1349,7 @@ "packages": { "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, @@ -1160,7 +1365,7 @@ }, "@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/abi-utils": true, "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1171,8 +1376,8 @@ }, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1183,8 +1388,8 @@ }, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1196,7 +1401,7 @@ "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1207,8 +1412,8 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1219,8 +1424,8 @@ }, "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1231,8 +1436,8 @@ }, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1243,8 +1448,8 @@ }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1255,8 +1460,8 @@ }, "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1267,7 +1472,7 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, "browserify>buffer": true, @@ -1286,7 +1491,7 @@ "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, "@metamask/keyring-api": true, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": true, "@metamask/utils>@metamask/superstruct": true, "@metamask/utils": true, "webpack>events": true, @@ -1315,12 +1520,12 @@ }, "packages": { "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, "@trezor/connect-web": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, @@ -1448,7 +1653,7 @@ "console.log": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/browser-passworder": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, @@ -1473,6 +1678,26 @@ "@metamask/keyring-snap-client>uuid": true } }, + "@metamask/accounts-controller>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { "URL": true @@ -1860,7 +2085,7 @@ "setInterval": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@ethereumjs/tx": true, "@metamask/smart-transactions-controller>@ethereumjs/util": true, "@ethersproject/bytes": true, "@metamask/controller-utils": true, @@ -2067,11 +2292,10 @@ "packages": { "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/abi": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/base-controller": true, + "@metamask/base-controller": true, "@metamask/controller-utils": true, "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/gas-fee-controller": true, @@ -3392,7 +3616,7 @@ "copy-to-clipboard>toggle-selection": true } }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { + "eth-lattice-keyring>gridplus-sdk>crc-32": { "globals": { "DO_NOT_EXPORT_CRC": true, "define": true @@ -3644,7 +3868,7 @@ }, "packages": { "eth-lattice-keyring>@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, "crypto-browserify": true, @@ -3915,7 +4139,7 @@ "eth-lattice-keyring>gridplus-sdk>borc": true, "ethereumjs-util>ethereum-cryptography>bs58check": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "@metamask/ppom-validator>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, "ethers>@ethersproject/sha2>hash.js": true, @@ -4343,7 +4567,7 @@ "react-markdown>unist-util-visit": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": { "globals": { "Headers": true, "TextDecoder": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 32228a0ea8fc..9fdff5d7b884 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -40,31 +40,47 @@ }, "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": true, + "webpack>events": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, + "webpack>events": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, @@ -73,7 +89,42 @@ "TextEncoder": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": { "globals": { "TextEncoder": true } @@ -93,25 +144,35 @@ "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": { + "packages": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "eth-lattice-keyring>@ethereumjs/tx": { "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, @@ -122,25 +183,165 @@ "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, "@ethereumjs/tx>@ethereumjs/util": { "globals": { - "console.warn": true + "console.warn": true, + "fetch": true }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/controller-utils>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, "@metamask/smart-transactions-controller>@ethereumjs/util": { @@ -149,11 +350,24 @@ "fetch": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true } }, + "eth-lattice-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, "@ethersproject/abi": { "globals": { "console.log": true @@ -622,8 +836,8 @@ }, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -633,7 +847,7 @@ }, "@keystonehq/bc-ur-registry-eth": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -654,7 +868,7 @@ }, "@keystonehq/metamask-airgapped-keyring": { "packages": { - "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": true, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, "@keystonehq/bc-ur-registry-eth": true, "@metamask/obs-store": true, @@ -875,12 +1089,11 @@ }, "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/eth-snap-keyring": true, "@metamask/keyring-api": true, "@metamask/keyring-controller": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/accounts-controller>@metamask/keyring-utils": true, "@metamask/utils": true, "@ethereumjs/tx>ethereum-cryptography": true, "uuid": true @@ -921,7 +1134,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "ethers>@ethersproject/address": true, "@ethersproject/bignumber": true, "@ethersproject/contracts": true, @@ -1002,14 +1215,6 @@ "immer": true } }, - "@metamask/transaction-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, "@metamask/browser-passworder": { "globals": { "CryptoKey": true, @@ -1039,7 +1244,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@ethereumjs/util": true, "@metamask/controller-utils>@metamask/ethjs-unit": true, "@metamask/utils": true, "@metamask/controller-utils>@spruceid/siwe-parser": true, @@ -1076,7 +1281,7 @@ "TextEncoder": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": true, "@metamask/snaps-sdk>@metamask/key-tree": true, "@metamask/scure-bip39": true, @@ -1144,7 +1349,7 @@ "packages": { "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, @@ -1160,7 +1365,7 @@ }, "@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/abi-utils": true, "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1171,8 +1376,8 @@ }, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1183,8 +1388,8 @@ }, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1196,7 +1401,7 @@ "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1207,8 +1412,8 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1219,8 +1424,8 @@ }, "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1231,8 +1436,8 @@ }, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1243,8 +1448,8 @@ }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1255,8 +1460,8 @@ }, "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1267,7 +1472,7 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, "browserify>buffer": true, @@ -1286,7 +1491,7 @@ "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, "@metamask/keyring-api": true, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": true, "@metamask/utils>@metamask/superstruct": true, "@metamask/utils": true, "webpack>events": true, @@ -1315,12 +1520,12 @@ }, "packages": { "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, "@trezor/connect-web": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, @@ -1448,7 +1653,7 @@ "console.log": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/browser-passworder": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, @@ -1473,6 +1678,26 @@ "@metamask/keyring-snap-client>uuid": true } }, + "@metamask/accounts-controller>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { "URL": true @@ -1860,7 +2085,7 @@ "setInterval": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@ethereumjs/tx": true, "@metamask/smart-transactions-controller>@ethereumjs/util": true, "@ethersproject/bytes": true, "@metamask/controller-utils": true, @@ -2067,11 +2292,10 @@ "packages": { "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/abi": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/base-controller": true, + "@metamask/base-controller": true, "@metamask/controller-utils": true, "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/gas-fee-controller": true, @@ -3392,7 +3616,7 @@ "copy-to-clipboard>toggle-selection": true } }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { + "eth-lattice-keyring>gridplus-sdk>crc-32": { "globals": { "DO_NOT_EXPORT_CRC": true, "define": true @@ -3644,7 +3868,7 @@ }, "packages": { "eth-lattice-keyring>@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, "crypto-browserify": true, @@ -3915,7 +4139,7 @@ "eth-lattice-keyring>gridplus-sdk>borc": true, "ethereumjs-util>ethereum-cryptography>bs58check": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "@metamask/ppom-validator>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, "ethers>@ethersproject/sha2>hash.js": true, @@ -4343,7 +4567,7 @@ "react-markdown>unist-util-visit": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": { "globals": { "Headers": true, "TextDecoder": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 32228a0ea8fc..9fdff5d7b884 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -40,31 +40,47 @@ }, "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": true, + "webpack>events": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, + "webpack>events": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, @@ -73,7 +89,42 @@ "TextEncoder": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": { "globals": { "TextEncoder": true } @@ -93,25 +144,35 @@ "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": { + "packages": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "eth-lattice-keyring>@ethereumjs/tx": { "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, @@ -122,25 +183,165 @@ "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, "@ethereumjs/tx>@ethereumjs/util": { "globals": { - "console.warn": true + "console.warn": true, + "fetch": true }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/controller-utils>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, "@metamask/smart-transactions-controller>@ethereumjs/util": { @@ -149,11 +350,24 @@ "fetch": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true } }, + "eth-lattice-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, "@ethersproject/abi": { "globals": { "console.log": true @@ -622,8 +836,8 @@ }, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -633,7 +847,7 @@ }, "@keystonehq/bc-ur-registry-eth": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -654,7 +868,7 @@ }, "@keystonehq/metamask-airgapped-keyring": { "packages": { - "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": true, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, "@keystonehq/bc-ur-registry-eth": true, "@metamask/obs-store": true, @@ -875,12 +1089,11 @@ }, "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/eth-snap-keyring": true, "@metamask/keyring-api": true, "@metamask/keyring-controller": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/accounts-controller>@metamask/keyring-utils": true, "@metamask/utils": true, "@ethereumjs/tx>ethereum-cryptography": true, "uuid": true @@ -921,7 +1134,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "ethers>@ethersproject/address": true, "@ethersproject/bignumber": true, "@ethersproject/contracts": true, @@ -1002,14 +1215,6 @@ "immer": true } }, - "@metamask/transaction-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, "@metamask/browser-passworder": { "globals": { "CryptoKey": true, @@ -1039,7 +1244,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@ethereumjs/util": true, "@metamask/controller-utils>@metamask/ethjs-unit": true, "@metamask/utils": true, "@metamask/controller-utils>@spruceid/siwe-parser": true, @@ -1076,7 +1281,7 @@ "TextEncoder": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": true, "@metamask/snaps-sdk>@metamask/key-tree": true, "@metamask/scure-bip39": true, @@ -1144,7 +1349,7 @@ "packages": { "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, @@ -1160,7 +1365,7 @@ }, "@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/abi-utils": true, "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1171,8 +1376,8 @@ }, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1183,8 +1388,8 @@ }, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1196,7 +1401,7 @@ "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1207,8 +1412,8 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1219,8 +1424,8 @@ }, "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1231,8 +1436,8 @@ }, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1243,8 +1448,8 @@ }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1255,8 +1460,8 @@ }, "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1267,7 +1472,7 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, "browserify>buffer": true, @@ -1286,7 +1491,7 @@ "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, "@metamask/keyring-api": true, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": true, "@metamask/utils>@metamask/superstruct": true, "@metamask/utils": true, "webpack>events": true, @@ -1315,12 +1520,12 @@ }, "packages": { "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, "@trezor/connect-web": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, @@ -1448,7 +1653,7 @@ "console.log": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/browser-passworder": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, @@ -1473,6 +1678,26 @@ "@metamask/keyring-snap-client>uuid": true } }, + "@metamask/accounts-controller>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { "URL": true @@ -1860,7 +2085,7 @@ "setInterval": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@ethereumjs/tx": true, "@metamask/smart-transactions-controller>@ethereumjs/util": true, "@ethersproject/bytes": true, "@metamask/controller-utils": true, @@ -2067,11 +2292,10 @@ "packages": { "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/abi": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/base-controller": true, + "@metamask/base-controller": true, "@metamask/controller-utils": true, "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/gas-fee-controller": true, @@ -3392,7 +3616,7 @@ "copy-to-clipboard>toggle-selection": true } }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { + "eth-lattice-keyring>gridplus-sdk>crc-32": { "globals": { "DO_NOT_EXPORT_CRC": true, "define": true @@ -3644,7 +3868,7 @@ }, "packages": { "eth-lattice-keyring>@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, "crypto-browserify": true, @@ -3915,7 +4139,7 @@ "eth-lattice-keyring>gridplus-sdk>borc": true, "ethereumjs-util>ethereum-cryptography>bs58check": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "@metamask/ppom-validator>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, "ethers>@ethersproject/sha2>hash.js": true, @@ -4343,7 +4567,7 @@ "react-markdown>unist-util-visit": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": { "globals": { "Headers": true, "TextDecoder": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 822badb94d04..b8d0b1e62ac8 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -40,31 +40,47 @@ }, "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": true, + "webpack>events": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, + "webpack>events": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": { + "packages": { + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "webpack>events": true } }, @@ -73,7 +89,42 @@ "TextEncoder": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true + } + }, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": { "globals": { "TextEncoder": true } @@ -93,25 +144,35 @@ "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true + } + }, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": { + "packages": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": { "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "eth-lattice-keyring>@ethereumjs/tx": { "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, @@ -122,25 +183,165 @@ "packages": { "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@ethersproject/providers": true, "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@ethereumjs/tx>@ethereumjs/common>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, "@ethereumjs/tx>@ethereumjs/util": { "globals": { - "console.warn": true + "console.warn": true, + "fetch": true }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/controller-utils>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/controller-utils>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/eth-trezor-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/eth-trezor-keyring>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true + } + }, + "@metamask/keyring-controller>@ethereumjs/util": { + "globals": { + "console.warn": true, + "fetch": true + }, + "packages": { + "@metamask/keyring-controller>@ethereumjs/util>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, "@metamask/smart-transactions-controller>@ethereumjs/util": { @@ -149,11 +350,24 @@ "fetch": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util>@ethereumjs/rlp": true, "@ethereumjs/tx>ethereum-cryptography": true, "webpack>events": true } }, + "eth-lattice-keyring>@ethereumjs/util": { + "globals": { + "console.warn": true + }, + "packages": { + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, + "browserify>insert-module-globals>is-buffer": true, + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": true + } + }, "@ethersproject/abi": { "globals": { "console.log": true @@ -622,8 +836,8 @@ }, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -633,7 +847,7 @@ }, "@keystonehq/bc-ur-registry-eth": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, "browserify>buffer": true, "@metamask/eth-trezor-keyring>hdkey": true, @@ -654,7 +868,7 @@ }, "@keystonehq/metamask-airgapped-keyring": { "packages": { - "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@ethereumjs/tx": true, "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, "@keystonehq/bc-ur-registry-eth": true, "@metamask/obs-store": true, @@ -827,7 +1041,7 @@ }, "@metamask-institutional/custody-controller": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask-institutional/custody-keyring": true, "@metamask/obs-store": true } @@ -839,7 +1053,7 @@ "console.warn": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask-institutional/custody-keyring>@metamask-institutional/configuration-client": true, "@metamask-institutional/sdk": true, "@metamask-institutional/types": true, @@ -893,7 +1107,7 @@ "setInterval": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask-institutional/sdk": true, "@metamask-institutional/transaction-update>@metamask-institutional/websocket-client": true, "@metamask/obs-store": true, @@ -967,12 +1181,11 @@ }, "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/eth-snap-keyring": true, "@metamask/keyring-api": true, "@metamask/keyring-controller": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/accounts-controller>@metamask/keyring-utils": true, "@metamask/utils": true, "@ethereumjs/tx>ethereum-cryptography": true, "uuid": true @@ -1013,7 +1226,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "ethers>@ethersproject/address": true, "@ethersproject/bignumber": true, "@ethersproject/contracts": true, @@ -1094,14 +1307,6 @@ "immer": true } }, - "@metamask/transaction-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, "@metamask/browser-passworder": { "globals": { "CryptoKey": true, @@ -1131,7 +1336,7 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@ethereumjs/util": true, "@metamask/controller-utils>@metamask/ethjs-unit": true, "@metamask/utils": true, "@metamask/controller-utils>@spruceid/siwe-parser": true, @@ -1168,7 +1373,7 @@ "TextEncoder": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": true, "@metamask/snaps-sdk>@metamask/key-tree": true, "@metamask/scure-bip39": true, @@ -1236,7 +1441,7 @@ "packages": { "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, @@ -1252,7 +1457,7 @@ }, "@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/abi-utils": true, "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1263,8 +1468,8 @@ }, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1275,8 +1480,8 @@ }, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1288,7 +1493,7 @@ "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1299,8 +1504,8 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1311,8 +1516,8 @@ }, "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1323,8 +1528,8 @@ }, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1335,8 +1540,8 @@ }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1347,8 +1552,8 @@ }, "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/utils>@ethereumjs/tx>@ethereumjs/rlp": true, + "eth-lattice-keyring>@ethereumjs/util": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, @@ -1359,7 +1564,7 @@ }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@ethereumjs/util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/eth-sig-util": true, "@metamask/utils": true, "browserify>buffer": true, @@ -1378,7 +1583,7 @@ "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, "@metamask/keyring-api": true, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, - "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": true, "@metamask/utils>@metamask/superstruct": true, "@metamask/utils": true, "webpack>events": true, @@ -1407,12 +1612,12 @@ }, "packages": { "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@ethereumjs/util": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, "@trezor/connect-web": true, "browserify>buffer": true, - "webpack>events": true, "@metamask/eth-trezor-keyring>hdkey": true } }, @@ -1540,7 +1745,7 @@ "console.log": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/keyring-controller>@ethereumjs/util": true, "@metamask/base-controller": true, "@metamask/browser-passworder": true, "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, @@ -1565,6 +1770,26 @@ "@metamask/keyring-snap-client>uuid": true } }, + "@metamask/accounts-controller>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, + "@metamask/eth-snap-keyring>@metamask/keyring-utils": { + "globals": { + "URL": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils": true, + "bitcoin-address-validation": true + } + }, "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { "URL": true @@ -1952,7 +2177,7 @@ "setInterval": true }, "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@ethereumjs/tx": true, "@metamask/smart-transactions-controller>@ethereumjs/util": true, "@ethersproject/bytes": true, "@metamask/controller-utils": true, @@ -2159,11 +2384,10 @@ "packages": { "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/abi": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/base-controller": true, + "@metamask/base-controller": true, "@metamask/controller-utils": true, "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/gas-fee-controller": true, @@ -3484,7 +3708,7 @@ "copy-to-clipboard>toggle-selection": true } }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { + "eth-lattice-keyring>gridplus-sdk>crc-32": { "globals": { "DO_NOT_EXPORT_CRC": true, "define": true @@ -3736,7 +3960,7 @@ }, "packages": { "eth-lattice-keyring>@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, + "eth-lattice-keyring>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, "crypto-browserify": true, @@ -4007,7 +4231,7 @@ "eth-lattice-keyring>gridplus-sdk>borc": true, "ethereumjs-util>ethereum-cryptography>bs58check": true, "browserify>buffer": true, - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>gridplus-sdk>crc-32": true, "@metamask/ppom-validator>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, "ethers>@ethersproject/sha2>hash.js": true, @@ -4435,7 +4659,7 @@ "react-markdown>unist-util-visit": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "eth-lattice-keyring>@ethereumjs/util>micro-ftch": { "globals": { "Headers": true, "TextDecoder": true, diff --git a/package.json b/package.json index 4bae16a04478..615cf9af4535 100644 --- a/package.json +++ b/package.json @@ -230,7 +230,7 @@ "@babel/runtime": "patch:@babel/runtime@npm%3A7.25.9#~/.yarn/patches/@babel-runtime-npm-7.25.9-fe8c62510a.patch", "@blockaid/ppom_release": "^1.5.3", "@ensdomains/content-hash": "^2.5.7", - "@ethereumjs/tx": "^4.1.1", + "@ethereumjs/tx": "^5.4.0", "@ethersproject/abi": "^5.6.4", "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -256,7 +256,7 @@ "@metamask-institutional/types": "^1.2.0", "@metamask/abi-utils": "^2.0.2", "@metamask/account-watcher": "^4.1.2", - "@metamask/accounts-controller": "^24.1.0", + "@metamask/accounts-controller": "^26.0.0", "@metamask/address-book-controller": "^6.0.3", "@metamask/announcement-controller": "^7.0.3", "@metamask/approval-controller": "^7.0.0", @@ -271,19 +271,19 @@ "@metamask/ens-resolver-snap": "^0.1.2", "@metamask/eth-json-rpc-filters": "^9.0.0", "@metamask/eth-json-rpc-middleware": "^15.1.2", - "@metamask/eth-ledger-bridge-keyring": "^9.0.0", + "@metamask/eth-ledger-bridge-keyring": "^10.0.0", "@metamask/eth-sig-util": "^7.0.1", - "@metamask/eth-snap-keyring": "^11.1.0", + "@metamask/eth-snap-keyring": "^12.0.0", "@metamask/eth-token-tracker": "^10.0.2", - "@metamask/eth-trezor-keyring": "^6.1.1", + "@metamask/eth-trezor-keyring": "^8.0.0", "@metamask/etherscan-link": "^3.0.0", "@metamask/gas-fee-controller": "^22.0.3", "@metamask/jazzicon": "^2.0.0", "@metamask/json-rpc-engine": "^10.0.0", "@metamask/json-rpc-middleware-stream": "^8.0.4", "@metamask/keyring-api": "^17.2.1", - "@metamask/keyring-controller": "^20.0.0", - "@metamask/keyring-internal-api": "^5.0.0", + "@metamask/keyring-controller": "^21.0.0", + "@metamask/keyring-internal-api": "^6.0.0", "@metamask/keyring-snap-client": "^4.0.1", "@metamask/logging-controller": "^6.0.4", "@metamask/logo": "^4.0.0", @@ -322,7 +322,7 @@ "@metamask/snaps-sdk": "^6.19.0", "@metamask/snaps-utils": "^9.0.1", "@metamask/solana-wallet-snap": "^1.10.0", - "@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A45.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-45.0.0-010fef9da6.patch", + "@metamask/transaction-controller": "^46.0.0", "@metamask/user-operation-controller": "^24.0.1", "@metamask/utils": "^11.1.0", "@ngraveio/bc-ur": "^1.1.12", diff --git a/test/stub/keyring-bridge.js b/test/stub/keyring-bridge.js index 3d4b4824ed82..13ddb7d9be2c 100644 --- a/test/stub/keyring-bridge.js +++ b/test/stub/keyring-bridge.js @@ -1,7 +1,7 @@ -import { Transaction } from '@ethereumjs/tx'; +import { TransactionFactory } from '@ethereumjs/tx'; import { signTypedData, SignTypedDataVersion } from '@metamask/eth-sig-util'; -import { bufferToHex } from 'ethereumjs-util'; -import { addHexPrefix, Common } from './keyring-utils'; +import { bigIntToHex, bytesToHex } from '@metamask/utils'; +import { Common } from './keyring-utils'; // BIP32 Public Key: xpub6ELgkkwgfoky9h9fFu4Auvx6oHvJ6XfwiS1NE616fe9Uf4H3JHtLGjCePVkb6RFcyDCqVvjXhNXbDNDqs6Kjoxw7pTAeP1GSEiLHmA5wYa9 // BIP32 Private Key: xprvA1MLMFQnqSCfwD5C9sXAYo1NFG5oh4x6MD5mRhbV7JcVnFwtkka5ivtAYDYJsr9GS242p3QZMbsMZC1GZ2uskNeTj9VhYxrCqRG6U5UPXp5 @@ -92,7 +92,7 @@ export class FakeTrezorBridge extends FakeKeyringBridge { hardfork: 'istanbul', }); - const signedTransaction = Transaction.fromTxData(transaction, { + const signedTransaction = TransactionFactory.fromTxData(transaction, { common, }).sign(Buffer.from(KNOWN_PRIVATE_KEYS[0], 'hex')); @@ -100,10 +100,10 @@ export class FakeTrezorBridge extends FakeKeyringBridge { id: 1, success: true, payload: { - v: signedTransaction.v, - r: signedTransaction.r, - s: signedTransaction.s, - serializedTx: addHexPrefix(bufferToHex(signedTransaction.serialize())), + v: bigIntToHex(signedTransaction.v), + r: bigIntToHex(signedTransaction.r), + s: bigIntToHex(signedTransaction.s), + serializedTx: bytesToHex(signedTransaction.serialize()), }, }; } diff --git a/test/stub/keyring-utils.js b/test/stub/keyring-utils.js index 2990e63dc26d..603f973c485b 100644 --- a/test/stub/keyring-utils.js +++ b/test/stub/keyring-utils.js @@ -15,6 +15,7 @@ export class Common { constructor({ chain, hardfork }) { this.chain = chain; this.hardfork = hardfork; + this.customCrypto = {}; } /** diff --git a/yarn.lock b/yarn.lock index 198e74f6c9f5..6dc4ecc01ecf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4829,16 +4829,16 @@ __metadata: languageName: node linkType: hard -"@metamask/accounts-controller@npm:^24.1.0": - version: 24.1.0 - resolution: "@metamask/accounts-controller@npm:24.1.0" +"@metamask/accounts-controller@npm:^26.0.0": + version: 26.0.0 + resolution: "@metamask/accounts-controller@npm:26.0.0" dependencies: - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/util": "npm:^9.1.0" "@metamask/base-controller": "npm:^8.0.0" - "@metamask/eth-snap-keyring": "npm:^11.1.0" + "@metamask/eth-snap-keyring": "npm:^12.0.0" "@metamask/keyring-api": "npm:^17.2.0" - "@metamask/keyring-internal-api": "npm:^4.0.3" - "@metamask/keyring-utils": "npm:^2.3.1" + "@metamask/keyring-internal-api": "npm:^6.0.0" + "@metamask/keyring-utils": "npm:^3.0.0" "@metamask/network-controller": "npm:^22.2.1" "@metamask/snaps-sdk": "npm:^6.17.1" "@metamask/snaps-utils": "npm:^8.10.0" @@ -4848,12 +4848,12 @@ __metadata: immer: "npm:^9.0.6" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/keyring-controller": ^19.0.0 + "@metamask/keyring-controller": ^21.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/providers": ^18.1.0 "@metamask/snaps-controllers": ^9.19.0 webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/71b512c23168c1b19e54a0cc55f8c7cb8179eca38756e9be58956a4b17603e08be55034506fd04cf29222c47f6e8d52b6553bbe40d7aa1ee12d3babbf5545fc0 + checksum: 10/6b2c7d638cc335b0de62042ff62d65fec7c317b3a5dda2e8e8bb5db61c6ec428df322d2f214fa94863186ffcba0291542cb5930a0ee0b240a6aca4d785ba29d1 languageName: node linkType: hard @@ -5054,13 +5054,13 @@ __metadata: linkType: hard "@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0, @metamask/controller-utils@npm:^11.4.2, @metamask/controller-utils@npm:^11.4.4, @metamask/controller-utils@npm:^11.5.0": - version: 11.5.0 - resolution: "@metamask/controller-utils@npm:11.5.0" + version: 11.6.0 + resolution: "@metamask/controller-utils@npm:11.6.0" dependencies: - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/util": "npm:^9.1.0" "@metamask/eth-query": "npm:^4.0.0" "@metamask/ethjs-unit": "npm:^0.3.0" - "@metamask/utils": "npm:^11.1.0" + "@metamask/utils": "npm:^11.2.0" "@spruceid/siwe-parser": "npm:2.1.0" "@types/bn.js": "npm:^5.1.5" bignumber.js: "npm:^9.1.2" @@ -5070,7 +5070,7 @@ __metadata: fast-deep-equal: "npm:^3.1.3" peerDependencies: "@babel/runtime": ^7.0.0 - checksum: 10/ef3ca4c36fdd4658233467d639154321015be7985008d90c5e870ef69f92024143fe81908e398e6e79e10f9b40d5c33e8742beae0ed5690db0fbce3731fbfd0b + checksum: 10/0bbb36cb2a8107362ecc13ad4227922f9eba5a5cfb7f7742c6b7a6a1023bd1c4d93a0e6cdfd0cef49228a719950753c26d0ee77598cbafd69944b0f89f6e6452 languageName: node linkType: hard @@ -5207,6 +5207,20 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-hd-keyring@npm:^12.0.0": + version: 12.0.0 + resolution: "@metamask/eth-hd-keyring@npm:12.0.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/key-tree": "npm:^10.0.2" + "@metamask/scure-bip39": "npm:^2.1.1" + "@metamask/utils": "npm:^11.1.0" + ethereum-cryptography: "npm:^2.1.2" + checksum: 10/9567238a11c0e3a331a477fbe6ad5ee42b10bb943efdff9696bf178127b9d5aac2ce02295221fa19d18981231251ee25053034b7780495e2c2fc7427c5c02516 + languageName: node + linkType: hard + "@metamask/eth-json-rpc-filters@npm:^9.0.0": version: 9.0.0 resolution: "@metamask/eth-json-rpc-filters@npm:9.0.0" @@ -5264,17 +5278,17 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-ledger-bridge-keyring@npm:^9.0.0": - version: 9.0.0 - resolution: "@metamask/eth-ledger-bridge-keyring@npm:9.0.0" +"@metamask/eth-ledger-bridge-keyring@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/eth-ledger-bridge-keyring@npm:10.0.0" dependencies: "@ethereumjs/rlp": "npm:^5.0.2" - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@ledgerhq/hw-app-eth": "npm:^6.42.0" "@metamask/eth-sig-util": "npm:^8.2.0" hdkey: "npm:^2.1.0" - checksum: 10/dac1a4ff7c03ebb3c591035eb2cf0d4149ed1c1bb78baa02ed8b91e60884f91dc5639141bf4e69252974bf03217f15800401fe50c2953e3799dba30345b7c6e2 + checksum: 10/a1e4e410aa051fa85abdff044eab4ae3fd594442186b53d1c21d12817d2ece51e510f86ecd9e69658fc2c3cbbf53d5941eb4ea93928f74c11e0ff5e399781a2e languageName: node linkType: hard @@ -5317,6 +5331,19 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-simple-keyring@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/eth-simple-keyring@npm:10.0.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/utils": "npm:^11.1.0" + ethereum-cryptography: "npm:^2.1.2" + randombytes: "npm:^2.1.0" + checksum: 10/e749e16cbbd3b542cda3e727ee1efb16f597c8583a0ca0bbb457b500397c0b492ecdf07965a67cec3b4bfb25fc56caa01810b23b918939dd104eea759caa339a + languageName: node + linkType: hard + "@metamask/eth-simple-keyring@npm:^9.0.0": version: 9.0.0 resolution: "@metamask/eth-simple-keyring@npm:9.0.0" @@ -5330,24 +5357,24 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-snap-keyring@npm:^11.1.0": - version: 11.1.0 - resolution: "@metamask/eth-snap-keyring@npm:11.1.0" +"@metamask/eth-snap-keyring@npm:^12.0.0": + version: 12.0.0 + resolution: "@metamask/eth-snap-keyring@npm:12.0.0" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" + "@ethereumjs/tx": "npm:^5.4.0" "@metamask/base-controller": "npm:^7.1.1" "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:^17.2.0" - "@metamask/keyring-internal-api": "npm:^4.0.3" + "@metamask/keyring-api": "npm:^17.2.1" + "@metamask/keyring-internal-api": "npm:^5.0.0" "@metamask/keyring-internal-snap-client": "npm:^4.0.1" - "@metamask/keyring-utils": "npm:^2.3.0" + "@metamask/keyring-utils": "npm:^3.0.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" "@types/uuid": "npm:^9.0.8" uuid: "npm:^9.0.1" peerDependencies: - "@metamask/keyring-api": ^17.2.0 - checksum: 10/b01abdcb2bd44c6fdf8fef3b897cdb78f99b5cf0a01d8c00d4fbad28b071c9073c9fdbfca974b452db6dddd44c6c0918b7bdb8705af0bc4393d1f9efa73ae33b + "@metamask/keyring-api": ^17.2.1 + checksum: 10/9c57c618f4401b7a983daea3578090d763fcacdaf30431aaa3301360cda6537443534b37c191a3640891a9eee105e33b41a966187e5fb172f5022e1b40412222 languageName: node linkType: hard @@ -5369,18 +5396,19 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-trezor-keyring@npm:^6.1.1": - version: 6.1.1 - resolution: "@metamask/eth-trezor-keyring@npm:6.1.1" +"@metamask/eth-trezor-keyring@npm:^8.0.0": + version: 8.0.0 + resolution: "@metamask/eth-trezor-keyring@npm:8.0.0" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/utils": "npm:^11.1.0" "@trezor/connect-plugin-ethereum": "npm:^9.0.3" "@trezor/connect-web": "npm:^9.1.11" hdkey: "npm:^2.1.0" tslib: "npm:^2.6.2" - checksum: 10/b344be61ec81b8e4008d385f88d16fb68274cbe6bd7d76e66d832e6370e6eececbab42edd8cf598142dc0de7a647b5f93d6ec9be51aef3dcca4d548ba2e5bebe + checksum: 10/6b4713887211db1c99997969c10f21502e49779746021cb6023d2d2b34a5e489976275befe94825fbac9c569e8b59d1e33cd69fc6f3989b13236c545aa04ed0c languageName: node linkType: hard @@ -5587,6 +5615,28 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-controller@npm:^21.0.0": + version: 21.0.0 + resolution: "@metamask/keyring-controller@npm:21.0.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@keystonehq/metamask-airgapped-keyring": "npm:^0.14.1" + "@metamask/base-controller": "npm:^8.0.0" + "@metamask/browser-passworder": "npm:^4.3.0" + "@metamask/eth-hd-keyring": "npm:^12.0.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/eth-simple-keyring": "npm:^10.0.0" + "@metamask/keyring-api": "npm:^17.2.0" + "@metamask/keyring-internal-api": "npm:^6.0.0" + "@metamask/utils": "npm:^11.2.0" + async-mutex: "npm:^0.5.0" + ethereumjs-wallet: "npm:^1.0.1" + immer: "npm:^9.0.6" + ulid: "npm:^2.3.0" + checksum: 10/aee572da64d757417397fee74a44be1c3f0ea3168c6880cb211d99d71b5e1b457d1684760b9d347820c0d90f0052783105e60697e9315ae257d3ae12c852190a + languageName: node + linkType: hard + "@metamask/keyring-internal-api@npm:^4.0.3": version: 4.0.3 resolution: "@metamask/keyring-internal-api@npm:4.0.3" @@ -5610,6 +5660,17 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-internal-api@npm:^6.0.0": + version: 6.0.0 + resolution: "@metamask/keyring-internal-api@npm:6.0.0" + dependencies: + "@metamask/keyring-api": "npm:^17.2.1" + "@metamask/keyring-utils": "npm:^3.0.0" + "@metamask/superstruct": "npm:^3.1.0" + checksum: 10/069945b3423e7b6bd0b8735d65e17c968e494bc3f8c06e585d6e27f09ced0027541440c9e90ffbcd59b1daf91d7848c09be010a8ceb547ed3c4f6465e810b7a8 + languageName: node + linkType: hard + "@metamask/keyring-internal-snap-client@npm:^4.0.1": version: 4.0.1 resolution: "@metamask/keyring-internal-snap-client@npm:4.0.1" @@ -5650,6 +5711,18 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-utils@npm:^3.0.0": + version: 3.0.0 + resolution: "@metamask/keyring-utils@npm:3.0.0" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.1.0" + bitcoin-address-validation: "npm:^2.2.3" + checksum: 10/eff3c0b9a86d6a25c5dd443946ba3ff56cb94fcb915a4eb061089819805e1e78eba2ea5cfb12a47ec4606542870c417de422f755947389ab9f3a4f08e96742db + languageName: node + linkType: hard + "@metamask/logging-controller@npm:^6.0.4": version: 6.0.4 resolution: "@metamask/logging-controller@npm:6.0.4" @@ -6484,51 +6557,17 @@ __metadata: languageName: node linkType: hard -"@metamask/transaction-controller@npm:45.0.0": - version: 45.0.0 - resolution: "@metamask/transaction-controller@npm:45.0.0" - dependencies: - "@ethereumjs/common": "npm:^3.2.0" - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/abi": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/base-controller": "npm:^7.1.1" - "@metamask/controller-utils": "npm:^11.5.0" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/nonce-tracker": "npm:^6.0.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.1.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - eth-method-registry: "npm:^4.0.0" - fast-json-patch: "npm:^3.1.1" - lodash: "npm:^4.17.21" - uuid: "npm:^8.3.2" - peerDependencies: - "@babel/runtime": ^7.0.0 - "@metamask/accounts-controller": ^23.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/eth-block-tracker": ">=9" - "@metamask/gas-fee-controller": ^22.0.0 - "@metamask/network-controller": ^22.0.0 - checksum: 10/42fc91e4ebb0ad83f8230c2060c392d0ba5fd555a2d3f407862c4574f195f1cb2b57ea025ea332e55a1196605602209219a828c565bd6a13d3135557d7427e24 - languageName: node - linkType: hard - -"@metamask/transaction-controller@patch:@metamask/transaction-controller@npm%3A45.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-45.0.0-010fef9da6.patch": - version: 45.0.0 - resolution: "@metamask/transaction-controller@patch:@metamask/transaction-controller@npm%3A45.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-45.0.0-010fef9da6.patch::version=45.0.0&hash=e00dfe" +"@metamask/transaction-controller@npm:^46.0.0": + version: 46.0.0 + resolution: "@metamask/transaction-controller@npm:46.0.0" dependencies: - "@ethereumjs/common": "npm:^3.2.0" - "@ethereumjs/tx": "npm:^4.2.0" + "@ethereumjs/common": "npm:^4.4.0" + "@ethereumjs/tx": "npm:^5.4.0" "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/base-controller": "npm:^7.1.1" + "@metamask/base-controller": "npm:^8.0.0" "@metamask/controller-utils": "npm:^11.5.0" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" @@ -6543,12 +6582,12 @@ __metadata: uuid: "npm:^8.3.2" peerDependencies: "@babel/runtime": ^7.0.0 - "@metamask/accounts-controller": ^23.0.0 + "@metamask/accounts-controller": ^24.0.0 "@metamask/approval-controller": ^7.0.0 "@metamask/eth-block-tracker": ">=9" "@metamask/gas-fee-controller": ^22.0.0 "@metamask/network-controller": ^22.0.0 - checksum: 10/b65d8d04031c3bbba2f95dcf66d22bcd0ef83c66fb3b341943ff6d81befbf370f826e9b9f0d73fccf3686a6550c2c0d3e80ad394618273964cc5efc1cb1d31fe + checksum: 10/d74a6ab0c08527f56741d89b6e0b7b0ceca9b5d8cc6ebbb36ea4f084b1cabbd146608015adbf69412ecbd378aec4028105938a91415b57b872f580669cb977a6 languageName: node linkType: hard @@ -27225,7 +27264,7 @@ __metadata: "@babel/runtime": "patch:@babel/runtime@npm%3A7.25.9#~/.yarn/patches/@babel-runtime-npm-7.25.9-fe8c62510a.patch" "@blockaid/ppom_release": "npm:^1.5.3" "@ensdomains/content-hash": "npm:^2.5.7" - "@ethereumjs/tx": "npm:^4.1.1" + "@ethereumjs/tx": "npm:^5.4.0" "@ethersproject/abi": "npm:^5.6.4" "@ethersproject/bignumber": "npm:^5.7.0" "@ethersproject/bytes": "npm:^5.7.0" @@ -27256,7 +27295,7 @@ __metadata: "@metamask-institutional/types": "npm:^1.2.0" "@metamask/abi-utils": "npm:^2.0.2" "@metamask/account-watcher": "npm:^4.1.2" - "@metamask/accounts-controller": "npm:^24.1.0" + "@metamask/accounts-controller": "npm:^26.0.0" "@metamask/address-book-controller": "npm:^6.0.3" "@metamask/announcement-controller": "npm:^7.0.3" "@metamask/api-specs": "npm:^0.10.15" @@ -27281,11 +27320,11 @@ __metadata: "@metamask/eth-json-rpc-filters": "npm:^9.0.0" "@metamask/eth-json-rpc-middleware": "npm:^15.1.2" "@metamask/eth-json-rpc-provider": "npm:^4.1.6" - "@metamask/eth-ledger-bridge-keyring": "npm:^9.0.0" + "@metamask/eth-ledger-bridge-keyring": "npm:^10.0.0" "@metamask/eth-sig-util": "npm:^7.0.1" - "@metamask/eth-snap-keyring": "npm:^11.1.0" + "@metamask/eth-snap-keyring": "npm:^12.0.0" "@metamask/eth-token-tracker": "npm:^10.0.2" - "@metamask/eth-trezor-keyring": "npm:^6.1.1" + "@metamask/eth-trezor-keyring": "npm:^8.0.0" "@metamask/etherscan-link": "npm:^3.0.0" "@metamask/forwarder": "npm:^1.1.0" "@metamask/gas-fee-controller": "npm:^22.0.3" @@ -27293,8 +27332,8 @@ __metadata: "@metamask/json-rpc-engine": "npm:^10.0.0" "@metamask/json-rpc-middleware-stream": "npm:^8.0.4" "@metamask/keyring-api": "npm:^17.2.1" - "@metamask/keyring-controller": "npm:^20.0.0" - "@metamask/keyring-internal-api": "npm:^5.0.0" + "@metamask/keyring-controller": "npm:^21.0.0" + "@metamask/keyring-internal-api": "npm:^6.0.0" "@metamask/keyring-snap-client": "npm:^4.0.1" "@metamask/logging-controller": "npm:^6.0.4" "@metamask/logo": "npm:^4.0.0" @@ -27337,7 +27376,7 @@ __metadata: "@metamask/solana-wallet-snap": "npm:^1.10.0" "@metamask/test-bundler": "npm:^1.0.0" "@metamask/test-dapp": "npm:9.0.0" - "@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A45.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-45.0.0-010fef9da6.patch" + "@metamask/transaction-controller": "npm:^46.0.0" "@metamask/user-operation-controller": "npm:^24.0.1" "@metamask/utils": "npm:^11.1.0" "@ngraveio/bc-ur": "npm:^1.1.12" From 135d0d2cf05c646901eb4134abea1c41c70940a4 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Fri, 7 Mar 2025 18:26:49 +0530 Subject: [PATCH 06/17] fix: Display alerts on add network request if there are pending confirmations (#30634) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Add confirmation reject warning when user adds a new network. As user confirms the warning pending confirmations are deleted. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30634?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/MetaMask-planning/issues/4292 ## **Manual testing steps** 1. Enable EVM multichain locally using env variable `EVM_MULTICHAIN_ENABLED` 2. Submit a confirmation 3. Add new network - ensure a warning appears and pending confirmations are deleted as user confirms the warning ## **Screenshots/Recordings** Uploading Screen Recording 2025-02-28 at 4.30.58 PM.mov… ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I’ve included tests if applicable - [X] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- app/_locales/en/messages.json | 7 ++ app/_locales/en_GB/messages.json | 7 ++ app/scripts/lib/approval/utils.test.ts | 28 ++++- app/scripts/lib/approval/utils.ts | 119 ++++++++++++------ .../handlers/add-ethereum-chain.js | 3 + .../handlers/add-ethereum-chain.test.js | 6 + .../handlers/ethereum-chain-utils.js | 4 + .../handlers/ethereum-chain-utils.test.ts | 8 ++ app/scripts/metamask-controller.js | 47 +++++-- builds.yml | 4 + test/data/confirmations/helper.ts | 1 + .../multiple-alert-modal.test.tsx | 55 ++++++++ .../multiple-alert-modal.tsx | 16 ++- .../app/confirm/info/row/constants.ts | 1 + .../alerts/TemplateAlertContext.tsx | 41 +++--- .../alerts/useAddEthereumChainAlerts.test.ts | 64 ++++++++++ .../alerts/useAddEthereumChainAlerts.ts | 52 ++++++++ .../alerts/useAlertActions.test.ts | 50 ++++++++ .../confirmation/alerts/useAlertsActions.tsx | 50 ++++++++ .../useTemplateConfirmationAlerts.test.ts | 37 +++++- .../alerts/useTemplateConfirmationAlerts.ts | 22 ++-- .../confirmation/confirmation.js | 1 - ui/selectors/selectors.js | 15 +++ 23 files changed, 546 insertions(+), 92 deletions(-) create mode 100644 ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.test.ts create mode 100644 ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.ts create mode 100644 ui/pages/confirmations/confirmation/alerts/useAlertActions.test.ts create mode 100644 ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index ac39224ee8c1..e2b422ed9dbf 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -3695,6 +3695,10 @@ "pending": { "message": "Pending" }, + "pendingConfirmationAddNetworkAlertMessage": { + "message": "Updating network will cancel $1 pending transactions from this site.", + "description": "Number of transactions." + }, "pendingTransactionAlertMessage": { "message": "This transaction won't go through until a previous transaction is complete. $1", "description": "$1 represents the words 'how to cancel or speed up a transaction' in a hyperlink" @@ -4431,6 +4435,9 @@ "reviewAlerts": { "message": "Review alerts" }, + "reviewPendingTransactions": { + "message": "Review pending transactions" + }, "reviewPermissions": { "message": "Review permissions" }, diff --git a/app/_locales/en_GB/messages.json b/app/_locales/en_GB/messages.json index ac39224ee8c1..e2b422ed9dbf 100644 --- a/app/_locales/en_GB/messages.json +++ b/app/_locales/en_GB/messages.json @@ -3695,6 +3695,10 @@ "pending": { "message": "Pending" }, + "pendingConfirmationAddNetworkAlertMessage": { + "message": "Updating network will cancel $1 pending transactions from this site.", + "description": "Number of transactions." + }, "pendingTransactionAlertMessage": { "message": "This transaction won't go through until a previous transaction is complete. $1", "description": "$1 represents the words 'how to cancel or speed up a transaction' in a hyperlink" @@ -4431,6 +4435,9 @@ "reviewAlerts": { "message": "Review alerts" }, + "reviewPendingTransactions": { + "message": "Review pending transactions" + }, "reviewPermissions": { "message": "Review permissions" }, diff --git a/app/scripts/lib/approval/utils.test.ts b/app/scripts/lib/approval/utils.test.ts index 14c472df89ba..fc7840faea31 100644 --- a/app/scripts/lib/approval/utils.test.ts +++ b/app/scripts/lib/approval/utils.test.ts @@ -7,7 +7,7 @@ import { ApprovalType } from '@metamask/controller-utils'; import { providerErrors } from '@metamask/rpc-errors'; import { DIALOG_APPROVAL_TYPES } from '@metamask/snaps-rpc-methods'; import { SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES } from '../../../../shared/constants/app'; -import { rejectAllApprovals } from './utils'; +import { rejectAllApprovals, rejectOriginApprovals } from './utils'; const ID_MOCK = '123'; const ID_MOCK_2 = '456'; @@ -100,4 +100,30 @@ describe('Approval Utils', () => { expect(deleteInterface).toHaveBeenCalledWith(INTERFACE_ID_MOCK); }); }); + + describe('rejectOriginApprovals', () => { + it('rejects approval requests from given origin', () => { + const origin = 'https://example.com'; + const approvalController = createApprovalControllerMock([ + { id: ID_MOCK, origin, type: ApprovalType.Transaction }, + { + id: ID_MOCK_2, + origin: 'www.test.com', + type: ApprovalType.EthSignTypedData, + }, + ]); + + rejectOriginApprovals({ + approvalController, + deleteInterface: () => undefined, + origin, + }); + + expect(approvalController.reject).toHaveBeenCalledTimes(1); + expect(approvalController.reject).toHaveBeenCalledWith( + ID_MOCK, + providerErrors.userRejectedRequest(), + ); + }); + }); }); diff --git a/app/scripts/lib/approval/utils.ts b/app/scripts/lib/approval/utils.ts index 538478ea4652..b54f664e7cc6 100644 --- a/app/scripts/lib/approval/utils.ts +++ b/app/scripts/lib/approval/utils.ts @@ -1,8 +1,11 @@ -import { ApprovalController } from '@metamask/approval-controller'; +import { + ApprovalController, + ApprovalRequest, +} from '@metamask/approval-controller'; import { ApprovalType } from '@metamask/controller-utils'; import { DIALOG_APPROVAL_TYPES } from '@metamask/snaps-rpc-methods'; import { providerErrors } from '@metamask/rpc-errors'; -import { createProjectLogger } from '@metamask/utils'; +import { createProjectLogger, Json } from '@metamask/utils'; ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) import { SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES } from '../../../../shared/constants/app'; ///: END:ONLY_INCLUDE_IF @@ -20,44 +23,78 @@ export function rejectAllApprovals({ const approvalRequests = Object.values(approvalRequestsById); for (const approvalRequest of approvalRequests) { - const { id, type } = approvalRequest; - const interfaceId = approvalRequest.requestData?.id as string; - - switch (type) { - case ApprovalType.SnapDialogAlert: - case ApprovalType.SnapDialogPrompt: - case DIALOG_APPROVAL_TYPES.default: - log('Rejecting snap dialog', { id, interfaceId }); - approvalController.accept(id, null); - deleteInterface?.(interfaceId); - break; - - case ApprovalType.SnapDialogConfirmation: - log('Rejecting snap confirmation', { id, interfaceId }); - approvalController.accept(id, false); - deleteInterface?.(interfaceId); - break; - - ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) - case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountCreation: - case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountRemoval: - case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.showSnapAccountRedirect: - log('Rejecting snap account confirmation', { id }); - approvalController.accept(id, false); - break; - ///: END:ONLY_INCLUDE_IF - - default: - log('Rejecting pending approval', { id }); - approvalController.reject( - id, - providerErrors.userRejectedRequest({ - data: { - cause: 'rejectAllApprovals', - }, - }), - ); - break; - } + rejectApproval({ + approvalController, + approvalRequest, + deleteInterface, + }); + } +} + +export function rejectOriginApprovals({ + approvalController, + deleteInterface, + origin, +}: { + approvalController: ApprovalController; + deleteInterface?: (id: string) => void; + origin: string; +}) { + const approvalRequestsById = approvalController.state.pendingApprovals; + const approvalRequests = Object.values(approvalRequestsById); + + const originApprovalRequests = approvalRequests.filter( + (approvalRequest) => approvalRequest.origin === origin, + ); + + for (const approvalRequest of originApprovalRequests) { + rejectApproval({ + approvalController, + approvalRequest, + deleteInterface, + }); + } +} + +function rejectApproval({ + approvalController, + approvalRequest, + deleteInterface, +}: { + approvalController: ApprovalController; + approvalRequest: ApprovalRequest>; + deleteInterface?: (id: string) => void; +}) { + const { id, type, origin } = approvalRequest; + const interfaceId = approvalRequest.requestData?.id as string; + + switch (type) { + case ApprovalType.SnapDialogAlert: + case ApprovalType.SnapDialogPrompt: + case DIALOG_APPROVAL_TYPES.default: + log('Rejecting snap dialog', { id, interfaceId, origin, type }); + approvalController.accept(id, null); + deleteInterface?.(interfaceId); + break; + + case ApprovalType.SnapDialogConfirmation: + log('Rejecting snap confirmation', { id, interfaceId, origin, type }); + approvalController.accept(id, false); + deleteInterface?.(interfaceId); + break; + + ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) + case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountCreation: + case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountRemoval: + case SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.showSnapAccountRedirect: + log('Rejecting snap account confirmation', { id, origin, type }); + approvalController.accept(id, false); + break; + ///: END:ONLY_INCLUDE_IF + + default: + log('Rejecting pending approval', { id, origin, type }); + approvalController.reject(id, providerErrors.userRejectedRequest()); + break; } } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js index 486861d5e11d..aadf641c7a7e 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js @@ -21,6 +21,7 @@ const addEthereumChain = { getCurrentChainIdForDomain: true, getCaveat: true, requestPermittedChainsPermissionIncrementalForOrigin: true, + rejectApprovalRequestsForOrigin: true, }, }; @@ -40,6 +41,7 @@ async function addEthereumChainHandler( getCurrentChainIdForDomain, getCaveat, requestPermittedChainsPermissionIncrementalForOrigin, + rejectApprovalRequestsForOrigin, }, ) { let validParams; @@ -188,5 +190,6 @@ async function addEthereumChainHandler( setActiveNetwork, getCaveat, requestPermittedChainsPermissionIncrementalForOrigin, + rejectApprovalRequestsForOrigin, }); } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js index a75f2725789b..70da89c97b77 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js @@ -78,6 +78,7 @@ const createMockedHandler = () => { rpcEndpoints: [{ networkClientId: 123 }], }), requestPermittedChainsPermissionIncrementalForOrigin: jest.fn(), + rejectApprovalRequestsForOrigin: jest.fn(), }; const response = {}; const handler = (request) => @@ -188,6 +189,7 @@ describe('addEthereumChainHandler', () => { setActiveNetwork: mocks.setActiveNetwork, requestPermittedChainsPermissionIncrementalForOrigin: mocks.requestPermittedChainsPermissionIncrementalForOrigin, + rejectApprovalRequestsForOrigin: mocks.rejectApprovalRequestsForOrigin, }, ); }); @@ -253,6 +255,8 @@ describe('addEthereumChainHandler', () => { setActiveNetwork: mocks.setActiveNetwork, requestPermittedChainsPermissionIncrementalForOrigin: mocks.requestPermittedChainsPermissionIncrementalForOrigin, + rejectApprovalRequestsForOrigin: + mocks.rejectApprovalRequestsForOrigin, }, ); }); @@ -298,6 +302,8 @@ describe('addEthereumChainHandler', () => { setActiveNetwork: mocks.setActiveNetwork, requestPermittedChainsPermissionIncrementalForOrigin: mocks.requestPermittedChainsPermissionIncrementalForOrigin, + rejectApprovalRequestsForOrigin: + mocks.rejectApprovalRequestsForOrigin, }, ); }); diff --git a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js index 5ba2211ce0b3..1f8d74f004be 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js @@ -170,6 +170,7 @@ export function validateAddEthereumChainParams(params) { * @param {Function} hooks.getCaveat - The callback to get the CAIP-25 caveat for the origin. * @param {Function} hooks.requestPermittedChainsPermissionIncrementalForOrigin - The callback to add a new chain to the permittedChains-equivalent CAIP-25 permission. * @param {Function} hooks.setTokenNetworkFilter - The callback to set the token network filter. + * @param {Function} hooks.rejectApprovalRequestsForOrigin - The callback to reject all pending approval requests for the origin. * @returns a null response on success or an error if user rejects an approval when autoApprove is false or on unexpected errors. */ export async function switchChain( @@ -183,6 +184,7 @@ export async function switchChain( getCaveat, requestPermittedChainsPermissionIncrementalForOrigin, setTokenNetworkFilter, + rejectApprovalRequestsForOrigin, }, ) { try { @@ -207,6 +209,8 @@ export async function switchChain( }); } + rejectApprovalRequestsForOrigin?.(); + await setActiveNetwork(networkClientId); setTokenNetworkFilter(chainId); response.result = null; diff --git a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.test.ts b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.test.ts index 7c159f5312ba..66a21c6facdb 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.test.ts +++ b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.test.ts @@ -15,6 +15,7 @@ describe('Ethereum Chain Utils', () => { getCaveat: jest.fn(), requestPermittedChainsPermissionIncrementalForOrigin: jest.fn(), setTokenNetworkFilter: jest.fn(), + rejectApprovalRequestsForOrigin: jest.fn(), }; const response: { result?: true } = {}; const switchChain = (chainId: Hex, networkClientId: string) => @@ -39,6 +40,13 @@ describe('Ethereum Chain Utils', () => { }); }); + it('calls rejectApprovalRequestsForOrigin if passed', async () => { + const { mocks, switchChain } = createMockedSwitchChain(); + await switchChain('0x1', 'mainnet'); + + expect(mocks.rejectApprovalRequestsForOrigin).toHaveBeenCalledTimes(1); + }); + describe('with no existing CAIP-25 permission', () => { it('requests a switch chain approval without autoApprove if autoApprove: false', async () => { const { mocks, switchChain } = createMockedSwitchChain(); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 1fa62e13ad87..585a20e0619d 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -344,7 +344,10 @@ import { PatchStore } from './lib/PatchStore'; import { sanitizeUIState } from './lib/state-utils'; import BridgeStatusController from './controllers/bridge-status/bridge-status-controller'; import { BRIDGE_STATUS_CONTROLLER_NAME } from './controllers/bridge-status/constants'; -import { rejectAllApprovals } from './lib/approval/utils'; +import { + rejectAllApprovals, + rejectOriginApprovals, +} from './lib/approval/utils'; import { handleBridgeTransactionComplete, handleBridgeTransactionFailed, @@ -4066,6 +4069,20 @@ export default class MetamaskController extends EventEmitter { }; } + rejectOriginPendingApprovals(origin) { + const deleteInterface = (id) => + this.controllerMessenger.call( + 'SnapInterfaceController:deleteInterface', + id, + ); + + rejectOriginApprovals({ + approvalController: this.approvalController, + deleteInterface, + origin, + }); + } + async exportAccount(address, password) { await this.verifyPassword(password); return this.keyringController.exportAccount(password, address); @@ -5923,18 +5940,20 @@ export default class MetamaskController extends EventEmitter { engine.push(createSelectedNetworkMiddleware(this.controllerMessenger)); // Add a middleware that will switch chain on each request (as needed) - const requestQueueMiddleware = createQueuedRequestMiddleware({ - enqueueRequest: this.queuedRequestController.enqueueRequest.bind( - this.queuedRequestController, - ), - shouldEnqueueRequest: (request) => { - return methodsThatShouldBeEnqueued.includes(request.method); - }, - // This will be removed once we can actually remove useRequestQueue state - // i.e. unrevert https://github.com/MetaMask/core/pull/5065 - useRequestQueue: () => true, - }); - engine.push(requestQueueMiddleware); + if (process.env.EVM_MULTICHAIN_ENABLED !== true) { + const requestQueueMiddleware = createQueuedRequestMiddleware({ + enqueueRequest: this.queuedRequestController.enqueueRequest.bind( + this.queuedRequestController, + ), + shouldEnqueueRequest: (request) => { + return methodsThatShouldBeEnqueued.includes(request.method); + }, + // This will be removed once we can actually remove useRequestQueue state + // i.e. unrevert https://github.com/MetaMask/core/pull/5065 + useRequestQueue: () => true, + }); + engine.push(requestQueueMiddleware); + } // If the origin is not in the selectedNetworkController's `domains` state // when the provider engine is created, the selectedNetworkController will @@ -6178,6 +6197,8 @@ export default class MetamaskController extends EventEmitter { this.permissionController, origin, ), + rejectApprovalRequestsForOrigin: () => + this.rejectOriginPendingApprovals(origin), ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) handleMmiAuthenticate: diff --git a/builds.yml b/builds.yml index aab81be90cad..8d620492d38e 100644 --- a/builds.yml +++ b/builds.yml @@ -29,6 +29,7 @@ buildTypes: - REJECT_INVALID_SNAPS_PLATFORM_VERSION: true - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/7.0.0/index.html - ACCOUNT_SNAPS_DIRECTORY_URL: https://snaps.metamask.io/account-management + - EVM_MULTICHAIN_ENABLED: false # Main build uses the default browser manifest manifestOverrides: false # Build name used in multiple user-readable places @@ -56,6 +57,7 @@ buildTypes: - REJECT_INVALID_SNAPS_PLATFORM_VERSION: true - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/7.0.0/index.html - ACCOUNT_SNAPS_DIRECTORY_URL: https://snaps.metamask.io/account-management + - EVM_MULTICHAIN_ENABLED: false # Modifies how the version is displayed. # eg. instead of 10.25.0 -> 10.25.0-beta.2 isPrerelease: true @@ -88,6 +90,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' + - EVM_MULTICHAIN_ENABLED: false isPrerelease: true manifestOverrides: ./app/build-types/flask/manifest/ buildNameOverride: MetaMask Flask @@ -110,6 +113,7 @@ buildTypes: - SUPPORT_LINK: https://support.metamask-institutional.io - SUPPORT_REQUEST_LINK: https://support.metamask-institutional.io - SENTRY_DSN: SENTRY_MMI_DSN + - EVM_MULTICHAIN_ENABLED: false # For some reason, MMI uses this type of versioning # Leaving it on for backwards compatibility isPrerelease: true diff --git a/test/data/confirmations/helper.ts b/test/data/confirmations/helper.ts index 026ad4a3adce..334034262760 100644 --- a/test/data/confirmations/helper.ts +++ b/test/data/confirmations/helper.ts @@ -81,6 +81,7 @@ export const getMockPersonalSignConfirmState = ( [unapprovedPersonalSignMsg.id]: { id: unapprovedPersonalSignMsg.id, type: ApprovalType.PersonalSign, + origin: 'https://metamask.github.io', }, }, unapprovedPersonalMsgs: { diff --git a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx index 3d176e57ccd0..3e96334c4e3e 100644 --- a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx +++ b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx @@ -199,6 +199,61 @@ describe('MultipleAlertModal', () => { expect(getByText(alertsMock[0].message)).toBeInTheDocument(); }); + describe('FieldAlerts not present', () => { + const alertsMockWithoutField = [ + { + key: FROM_ALERT_KEY_MOCK, + severity: Severity.Warning, + message: 'Alert 1', + reason: 'Reason 1', + alertDetails: ['Detail 1', 'Detail 2'], + }, + { + key: DATA_ALERT_KEY_MOCK, + severity: Severity.Danger, + message: 'Alert 2', + }, + { + key: CONTRACT_ALERT_KEY_MOCK, + severity: Severity.Info, + message: 'Alert 3', + }, + ]; + + const mockStoreWithAlertsWithoutField = configureMockStore([])({ + ...STATE_MOCK, + confirmAlerts: { + alerts: { [OWNER_ID_MOCK]: alertsMockWithoutField }, + confirmed: {}, + }, + }); + + it('does not render if displayAllAlerts is false', () => { + const { queryByText } = renderWithProvider( + , + mockStoreWithAlertsWithoutField, + ); + + expect(queryByText('alert-modal-button')).toBeNull(); + }); + + it('renders alerts if displayAllAlerts is true', () => { + const { getByTestId } = renderWithProvider( + , + mockStoreWithAlertsWithoutField, + ); + + expect(getByTestId('alert-modal-button')).toBeInTheDocument(); + }); + }); + describe('Navigation', () => { it('calls next alert when the next button is clicked', () => { const { getByTestId, getByText } = renderWithProvider( diff --git a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.tsx b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.tsx index 62875bffcfe0..30307f9d1dca 100644 --- a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.tsx +++ b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.tsx @@ -24,6 +24,8 @@ import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts'; export type MultipleAlertModalProps = { /** The key of the initial alert to display. */ alertKey?: string; + /** If true the modal will display non-field alerts also. */ + displayAllAlerts?: boolean; /** The function to be executed when the button in the alert modal is clicked. */ onFinalAcknowledgeClick: () => void; /** The function to be executed when the modal needs to be closed. */ @@ -146,15 +148,17 @@ function PageNavigation({ export function MultipleAlertModal({ alertKey, + displayAllAlerts = false, onClose, onFinalAcknowledgeClick, ownerId, showCloseIcon = true, skipAlertNavigation = false, }: MultipleAlertModalProps) { - const { isAlertConfirmed, fieldAlerts: alerts } = useAlerts(ownerId); + const { isAlertConfirmed, fieldAlerts, alerts } = useAlerts(ownerId); + const alertsToDisplay = displayAllAlerts ? alerts : fieldAlerts; - const initialAlertIndex = alerts.findIndex( + const initialAlertIndex = alertsToDisplay.findIndex( (alert: Alert) => alert.key === alertKey, ); @@ -163,7 +167,7 @@ export function MultipleAlertModal({ ); // If the selected alert is not found, default to the first alert - const selectedAlert = alerts[selectedIndex] ?? alerts[0]; + const selectedAlert = alertsToDisplay[selectedIndex] ?? alertsToDisplay[0]; const hasUnconfirmedAlerts = alerts.some( (alert: Alert) => @@ -186,7 +190,7 @@ export function MultipleAlertModal({ return; } - if (selectedIndex + 1 === alerts.length) { + if (selectedIndex + 1 === alertsToDisplay.length) { if (!hasUnconfirmedAlerts) { onFinalAcknowledgeClick(); return; @@ -200,7 +204,7 @@ export function MultipleAlertModal({ onFinalAcknowledgeClick, handleNextButtonClick, selectedIndex, - alerts.length, + alertsToDisplay.length, hasUnconfirmedAlerts, skipAlertNavigation, ]); @@ -213,7 +217,7 @@ export function MultipleAlertModal({ onClose={onClose} headerStartAccessory={ ; - onCancel: () => void; onSubmit: () => void; -}> = ({ children, pendingConfirmation, onCancel, onSubmit }) => { +}> = ({ children, pendingConfirmation, onSubmit }) => { const [isAlertsModalVisible, setAlertsModalVisible] = useState(false); const alertOwnerId = pendingConfirmation?.id; - useTemplateConfirmationAlerts(alertOwnerId); + useTemplateConfirmationAlerts(pendingConfirmation); const { hasAlerts } = useAlerts(alertOwnerId); - // todo: action implementations to come here as alerts are implemented - const processAction = useCallback((actionKey: string) => { - switch (actionKey) { - default: - console.error('Unknown alert action key:', actionKey); - break; - } - }, []); + const showAlertsModal = useCallback(() => { + setAlertsModalVisible(true); + }, [setAlertsModalVisible]); + + const hideAlertModal = useCallback(() => { + setAlertsModalVisible(false); + }, [setAlertsModalVisible]); + + const onFinalSubmit = useCallback(() => { + hideAlertModal(); + onSubmit(); + }, [hideAlertModal, onSubmit]); + + const processAction = useAlertsActions(hideAlertModal, pendingConfirmation); return ( // AlertMetricsProvider is added as it is required for alert modals to work @@ -58,16 +64,17 @@ export const TemplateAlertContextProvider: React.FC<{ setAlertsModalVisible(true), + showAlertsModal, }} > <> {isAlertsModalVisible && ( - setAlertsModalVisible(false)} - onCancel={onCancel} - onSubmit={onSubmit} + onFinalAcknowledgeClick={onFinalSubmit} + onClose={hideAlertModal} + showCloseIcon={false} + displayAllAlerts /> )} {children} diff --git a/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.test.ts new file mode 100644 index 000000000000..b3e7551567da --- /dev/null +++ b/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.test.ts @@ -0,0 +1,64 @@ +import { ApprovalRequest } from '@metamask/approval-controller'; +import { ApprovalType } from '@metamask/controller-utils'; + +import mockState from '../../../../../test/data/mock-state.json'; +import { getMockPersonalSignConfirmState } from '../../../../../test/data/confirmations/helper'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts'; + +import { useAddEthereumChainAlerts } from './useAddEthereumChainAlerts'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn(), +})); + +const PENDING_APPROVAL_MOCK = { + id: 'testApprovalId', + requestData: { testProperty: 'testValue' }, + type: ApprovalType.AddEthereumChain, + origin: 'https://metamask.github.io', + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any +} as ApprovalRequest; + +const ADD_ETH_CHAIN_ALERT = [ + { + actions: [ + { key: 'showPendingConfirmation', label: 'Review pending transactions' }, + ], + key: 'pendingConfirmationFromSameOrigin', + message: + 'Updating network will cancel 1 pending transactions from this site.', + reason: 'Are you sure?', + severity: 'warning', + }, +] as AlertActions.Alert[]; + +describe('useAddEthereumChainAlerts', () => { + it('returns alert if there are pending confirmations', () => { + const state = getMockPersonalSignConfirmState(); + const { result } = renderHookWithProvider( + () => useAddEthereumChainAlerts(PENDING_APPROVAL_MOCK), + { + ...state, + metamask: { + ...state.metamask, + pendingApprovals: { + ...state.metamask.pendingApprovals, + [PENDING_APPROVAL_MOCK.id]: PENDING_APPROVAL_MOCK, + }, + }, + }, + ); + expect(result.current).toStrictEqual(ADD_ETH_CHAIN_ALERT); + }); + + it('does not returns alert if there are no pending confirmations', () => { + const { result } = renderHookWithProvider( + () => useAddEthereumChainAlerts(PENDING_APPROVAL_MOCK), + mockState, + ); + expect(result.current).toStrictEqual([]); + }); +}); diff --git a/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.ts b/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.ts new file mode 100644 index 000000000000..65b2cb0de08a --- /dev/null +++ b/ui/pages/confirmations/confirmation/alerts/useAddEthereumChainAlerts.ts @@ -0,0 +1,52 @@ +import { ApprovalRequest } from '@metamask/approval-controller'; +import { ApprovalType } from '@metamask/controller-utils'; +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; + +import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts'; +import { AlertActionKey } from '../../../../components/app/confirm/info/row/constants'; +import { Severity } from '../../../../helpers/constants/design-system'; +import { getApprovalsByOrigin } from '../../../../selectors'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; + +const VALIDATED_APPROVAL_TYPES = [ + ApprovalType.AddEthereumChain, + ApprovalType.SwitchEthereumChain, +]; + +export function useAddEthereumChainAlerts( + pendingConfirmation: ApprovalRequest<{ id: string }>, +): Alert[] { + const pendingConfirmationsFromOrigin = useSelector((state) => + getApprovalsByOrigin(state, pendingConfirmation?.origin), + ); + + const t = useI18nContext(); + return useMemo(() => { + if ( + pendingConfirmationsFromOrigin?.length <= 1 || + !VALIDATED_APPROVAL_TYPES.includes( + pendingConfirmation?.type as ApprovalType, + ) + ) { + return []; + } + + return [ + { + actions: [ + { + key: AlertActionKey.ShowPendingConfirmation, + label: t('reviewPendingTransactions'), + }, + ], + key: 'pendingConfirmationFromSameOrigin', + message: t('pendingConfirmationAddNetworkAlertMessage', [ + pendingConfirmationsFromOrigin.length - 1, + ]), + reason: t('areYouSure'), + severity: Severity.Warning, + }, + ]; + }, [pendingConfirmation?.type, pendingConfirmationsFromOrigin?.length, t]); +} diff --git a/ui/pages/confirmations/confirmation/alerts/useAlertActions.test.ts b/ui/pages/confirmations/confirmation/alerts/useAlertActions.test.ts new file mode 100644 index 000000000000..b2be85b61914 --- /dev/null +++ b/ui/pages/confirmations/confirmation/alerts/useAlertActions.test.ts @@ -0,0 +1,50 @@ +import { ApprovalRequest } from '@metamask/approval-controller'; + +import mockState from '../../../../../test/data/mock-state.json'; +import { getMockPersonalSignConfirmState } from '../../../../../test/data/confirmations/helper'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { AlertActionKey } from '../../../../components/app/confirm/info/row/constants'; +import * as ConfirmationNavigation from '../../hooks/useConfirmationNavigation'; +import { useAlertsActions } from './useAlertsActions'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn(), +})); + +const PENDING_APPROVAL_MOCK = { + id: 'testApprovalId', + origin: 'https://metamask.github.io', + requestData: { testProperty: 'testValue' }, + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any +} as ApprovalRequest; + +describe('useAlertActions', () => { + it('returns method processAction to process alert actions', () => { + const { result } = renderHookWithProvider( + () => useAlertsActions(() => undefined, PENDING_APPROVAL_MOCK), + mockState, + ); + expect(typeof result.current).toBe('function'); + }); + + it('handles action "ShowPendingConfirmation"', () => { + const mockNavigateToIndex = jest.fn(); + const mockHideAlertModal = jest.fn(); + jest + .spyOn(ConfirmationNavigation, 'useConfirmationNavigation') + .mockReturnValue({ + getIndex: jest.fn(), + navigateToIndex: mockNavigateToIndex, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + const { result } = renderHookWithProvider( + () => useAlertsActions(mockHideAlertModal, PENDING_APPROVAL_MOCK), + getMockPersonalSignConfirmState(), + ); + result.current(AlertActionKey.ShowPendingConfirmation); + expect(mockNavigateToIndex).toHaveBeenCalledTimes(1); + expect(mockHideAlertModal).toHaveBeenCalledTimes(1); + }); +}); diff --git a/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx b/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx new file mode 100644 index 000000000000..122676277594 --- /dev/null +++ b/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx @@ -0,0 +1,50 @@ +import { ApprovalRequest } from '@metamask/approval-controller'; +import { useCallback } from 'react'; +import { useSelector } from 'react-redux'; + +import { AlertActionKey } from '../../../../components/app/confirm/info/row/constants'; +import { getApprovalsByOrigin } from '../../../../selectors'; +import { useConfirmationNavigation } from '../../hooks/useConfirmationNavigation'; + +export const useAlertsActions = ( + hideAlertModal: () => void, + pendingConfirmation: ApprovalRequest<{ id: string }>, +) => { + const pendingConfirmationsFromOrigin = useSelector((state) => + getApprovalsByOrigin(state, pendingConfirmation?.origin), + ); + + const { getIndex, navigateToIndex } = useConfirmationNavigation(); + + const navigateToPendingConfirmation = useCallback(() => { + const { id } = pendingConfirmation; + const pendingConfirmations = pendingConfirmationsFromOrigin?.filter( + (confirmation) => confirmation.id !== id, + ); + const nextIndex = getIndex(pendingConfirmations[0]?.id); + navigateToIndex(nextIndex); + hideAlertModal(); + }, [ + getIndex, + pendingConfirmation, + pendingConfirmationsFromOrigin, + hideAlertModal, + navigateToIndex, + ]); + + const processAction = useCallback( + (actionKey: string) => { + switch (actionKey) { + case AlertActionKey.ShowPendingConfirmation: + navigateToPendingConfirmation(); + break; + default: + console.error('Unknown alert action key:', actionKey); + break; + } + }, + [navigateToPendingConfirmation], + ); + + return processAction; +}; diff --git a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts index f8fc844ae289..10e79f6e0354 100644 --- a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts +++ b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts @@ -1,8 +1,11 @@ +import { ApprovalRequest } from '@metamask/approval-controller'; import { useDispatch } from 'react-redux'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; import mockState from '../../../../../test/data/mock-state.json'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts'; +import * as AddEthereumChainAlerts from './useAddEthereumChainAlerts'; + import { useTemplateConfirmationAlerts } from './useTemplateConfirmationAlerts'; jest.mock('react-redux', () => ({ @@ -10,24 +13,46 @@ jest.mock('react-redux', () => ({ useDispatch: jest.fn(), })); -describe('setAlerts', () => { +const PENDING_APPROVAL_MOCK = { + id: 'testApprovalId', + requestData: { testProperty: 'testValue' }, + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any +} as ApprovalRequest; + +const MOCK_ADD_ETH_CHAIN_ALERT = [ + { + key: 'pendingConfirmationFromSameOrigin', + message: 'dummy_message', + reason: 'dummy_reason', + severity: 'warning', + }, +] as AlertActions.Alert[]; + +describe('updateConfirmationAlerts', () => { it('calls updateAlerts to update alerts in state', () => { const mockDispatch = jest.fn(); (useDispatch as jest.Mock).mockReturnValue(mockDispatch); + jest + .spyOn(AddEthereumChainAlerts, 'useAddEthereumChainAlerts') + .mockReturnValue(MOCK_ADD_ETH_CHAIN_ALERT); const mockUpdateAlerts = jest.spyOn(AlertActions, 'updateAlerts'); renderHookWithProvider( - () => useTemplateConfirmationAlerts('123'), + () => useTemplateConfirmationAlerts(PENDING_APPROVAL_MOCK), mockState, ); expect(mockDispatch).toHaveBeenCalledTimes(1); expect(mockUpdateAlerts).toHaveBeenCalledTimes(1); expect(mockDispatch).toHaveBeenCalledWith({ - alerts: [], - ownerId: '123', + alerts: MOCK_ADD_ETH_CHAIN_ALERT, + ownerId: PENDING_APPROVAL_MOCK.id, type: 'UPDATE_ALERTS', }); - expect(mockUpdateAlerts).toHaveBeenCalledWith('123', []); + expect(mockUpdateAlerts).toHaveBeenCalledWith( + PENDING_APPROVAL_MOCK.id, + MOCK_ADD_ETH_CHAIN_ALERT, + ); }); }); diff --git a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts index cb369e844815..c8ca2891df1f 100644 --- a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts +++ b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts @@ -1,24 +1,32 @@ -import { useEffect, useMemo } from 'react'; +import { ApprovalRequest } from '@metamask/approval-controller'; import { useDispatch } from 'react-redux'; +import { useEffect, useMemo } from 'react'; + import { Alert, clearAlerts, updateAlerts, } from '../../../../ducks/confirm-alerts/confirm-alerts'; -// import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { useAddEthereumChainAlerts } from './useAddEthereumChainAlerts'; -export const useTemplateConfirmationAlerts = (alertOwnerId: string) => { +export const useTemplateConfirmationAlerts = ( + pendingConfirmation: ApprovalRequest<{ id: string }>, +) => { const dispatch = useDispatch(); - // const t = useI18nContext(); - const alerts: Alert[] = useMemo(() => [], []); + const addEthereumChainAlerts = useAddEthereumChainAlerts(pendingConfirmation); + const alerts: Alert[] = useMemo( + () => addEthereumChainAlerts, + [addEthereumChainAlerts], + ); + const alertOwnerId = pendingConfirmation?.id; useEffect(() => { dispatch(updateAlerts(alertOwnerId, alerts)); - }, [alerts, alertOwnerId]); + }, [alerts, alertOwnerId, dispatch]); useEffect(() => { return () => { dispatch(clearAlerts(alertOwnerId)); }; - }, []); + }, [alertOwnerId, dispatch]); }; diff --git a/ui/pages/confirmations/confirmation/confirmation.js b/ui/pages/confirmations/confirmation/confirmation.js index 54c985206f48..3a21d88694af 100644 --- a/ui/pages/confirmations/confirmation/confirmation.js +++ b/ui/pages/confirmations/confirmation/confirmation.js @@ -498,7 +498,6 @@ export default function ConfirmationPage({
confirmations, ); +/** + * Get pending confirmation from specified origin. + * + * @param state - Redux state object. + * @param origin - Origin to ger approvals from. + * @returns array of approvals from an origin + */ +export const getApprovalsByOrigin = (state, origin) => { + const pendingApprovals = getMemoizedUnapprovedConfirmations(state); + + return pendingApprovals?.filter( + (confirmation) => confirmation.origin === origin, + ); +}; + /** * Get a memoized version of the unapproved templated confirmations. */ From 97e2028d250520eff209fa49455bfb400fee8dbf Mon Sep 17 00:00:00 2001 From: Micaela Estabillo <100321200+micaelae@users.noreply.github.com> Date: Fri, 7 Mar 2025 05:11:16 -0800 Subject: [PATCH 07/17] fix: Bridge and Send pages crash when there's no solana account (#30793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** See ticket for details [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30793?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/30792 ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- ui/hooks/useMultichainBalances.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/hooks/useMultichainBalances.ts b/ui/hooks/useMultichainBalances.ts index 807a1f60ffd4..59c643fefb78 100644 --- a/ui/hooks/useMultichainBalances.ts +++ b/ui/hooks/useMultichainBalances.ts @@ -49,8 +49,8 @@ const useNonEvmAssetsWithBalances = (): ( return []; } - const assetIds = assetsByAccountId[nonEvmAccount.id]; - const balancesByAssetId = nonEvmBalancesByAccountId[nonEvmAccount.id]; + const assetIds = assetsByAccountId?.[nonEvmAccount.id]; + const balancesByAssetId = nonEvmBalancesByAccountId?.[nonEvmAccount.id]; if (!balancesByAssetId || !assetIds) { return []; } From b9e9ec06ed8281dcc2588aae134999aea00c0718 Mon Sep 17 00:00:00 2001 From: Alejandro Garcia Anglada Date: Fri, 7 Mar 2025 15:29:18 +0100 Subject: [PATCH 08/17] feat: update solana version (#30857) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Update solana version: https://github.com/MetaMask/snap-solana-wallet/releases/tag/v1.11.0 [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30857?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 615cf9af4535..8810a942c25c 100644 --- a/package.json +++ b/package.json @@ -321,7 +321,7 @@ "@metamask/snaps-rpc-methods": "^11.13.1", "@metamask/snaps-sdk": "^6.19.0", "@metamask/snaps-utils": "^9.0.1", - "@metamask/solana-wallet-snap": "^1.10.0", + "@metamask/solana-wallet-snap": "^1.11.0", "@metamask/transaction-controller": "^46.0.0", "@metamask/user-operation-controller": "^24.0.1", "@metamask/utils": "^11.1.0", diff --git a/yarn.lock b/yarn.lock index 6dc4ecc01ecf..0f49473b6eb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6506,10 +6506,10 @@ __metadata: languageName: node linkType: hard -"@metamask/solana-wallet-snap@npm:^1.10.0": - version: 1.10.0 - resolution: "@metamask/solana-wallet-snap@npm:1.10.0" - checksum: 10/d7a1538fad9adf92f78334b5422aba81182bb70d06ddc3319b10df563f742d9df53ac2b7d501191fc2cb3ced8b405fe39e764c2d33e81fdc1596ff027e0e40f6 +"@metamask/solana-wallet-snap@npm:^1.11.0": + version: 1.11.0 + resolution: "@metamask/solana-wallet-snap@npm:1.11.0" + checksum: 10/2d6e9a0ed37805a48cedbf3f7ff039223270e1e54abf0a942696356bdfb6c5623df56fe52cee8763a0cf35eacda23aab9810dcf61e5bb5ce64f2144c3075f63d languageName: node linkType: hard @@ -27373,7 +27373,7 @@ __metadata: "@metamask/snaps-rpc-methods": "npm:^11.13.1" "@metamask/snaps-sdk": "npm:^6.19.0" "@metamask/snaps-utils": "npm:^9.0.1" - "@metamask/solana-wallet-snap": "npm:^1.10.0" + "@metamask/solana-wallet-snap": "npm:^1.11.0" "@metamask/test-bundler": "npm:^1.0.0" "@metamask/test-dapp": "npm:9.0.0" "@metamask/transaction-controller": "npm:^46.0.0" From a0119599e8cb8fd5ff79fde51503fb61d63b81e1 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:46:13 +0100 Subject: [PATCH 09/17] test: add send DAI spec using Anvil state (#30804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** In this PR, I add a new spec for Sending DAI, leveraging Anvil state injection. This is the base work for changing the Swap specs to use this approach instead of Tenderly. Another PR will follow up with a Swap spec using the same approach. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30804?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Check ci ## **Screenshots/Recordings** Spec flow: https://github.com/user-attachments/assets/ad3b0ef1-9aa6-4d83-8fa6-389e0f66d6dd ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- test/e2e/seeder/network-states/with50Dai.json | 14 ++++ .../send-erc20-with-loaded-state.spec.ts | 80 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 test/e2e/seeder/network-states/with50Dai.json create mode 100644 test/e2e/tests/tokens/send-erc20-with-loaded-state.spec.ts diff --git a/test/e2e/seeder/network-states/with50Dai.json b/test/e2e/seeder/network-states/with50Dai.json new file mode 100644 index 000000000000..4721d5232d5f --- /dev/null +++ b/test/e2e/seeder/network-states/with50Dai.json @@ -0,0 +1,14 @@ +{ + "accounts": { + "0x6b175474e89094c44da98b954eedeac495271d0f": { + "nonce": 0, + "balance": "0x", + "code": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c80637ecebe00116100b8578063a9059cbb1161007c578063a9059cbb146106b4578063b753a98c1461071a578063bb35783b14610768578063bf353dbb146107d6578063dd62ed3e1461082e578063f2d5d56b146108a657610142565b80637ecebe00146104a15780638fcbaf0c146104f957806395d89b411461059f5780639c52a7f1146106225780639dc29fac1461066657610142565b8063313ce5671161010a578063313ce567146102f25780633644e5151461031657806340c10f191461033457806354fd4d501461038257806365fae35e1461040557806370a082311461044957610142565b806306fdde0314610147578063095ea7b3146101ca57806318160ddd1461023057806323b872dd1461024e57806330adf81f146102d4575b600080fd5b61014f6108f4565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561018f578082015181840152602081019050610174565b50505050905090810190601f1680156101bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610216600480360360408110156101e057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061092d565b604051808215151515815260200191505060405180910390f35b610238610a1f565b6040518082815260200191505060405180910390f35b6102ba6004803603606081101561026457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a25565b604051808215151515815260200191505060405180910390f35b6102dc610f3a565b6040518082815260200191505060405180910390f35b6102fa610f61565b604051808260ff1660ff16815260200191505060405180910390f35b61031e610f66565b6040518082815260200191505060405180910390f35b6103806004803603604081101561034a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f6c565b005b61038a611128565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103ca5780820151818401526020810190506103af565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104476004803603602081101561041b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611161565b005b61048b6004803603602081101561045f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061128f565b6040518082815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112a7565b6040518082815260200191505060405180910390f35b61059d600480360361010081101561051057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506112bf565b005b6105a76117fa565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105e75780820151818401526020810190506105cc565b50505050905090810190601f1680156106145780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106646004803603602081101561063857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611833565b005b6106b26004803603604081101561067c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611961565b005b610700600480360360408110156106ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611df4565b604051808215151515815260200191505060405180910390f35b6107666004803603604081101561073057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e09565b005b6107d46004803603606081101561077e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e19565b005b610818600480360360208110156107ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e2a565b6040518082815260200191505060405180910390f35b6108906004803603604081101561084457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e42565b6040518082815260200191505060405180910390f35b6108f2600480360360408110156108bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e67565b005b6040518060400160405280600e81526020017f44616920537461626c65636f696e00000000000000000000000000000000000081525081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60015481565b600081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610adc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4461692f696e73756666696369656e742d62616c616e6365000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610bb457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b15610db25781600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610cab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4461692f696e73756666696369656e742d616c6c6f77616e636500000000000081525060200191505060405180910390fd5b610d31600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e77565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610dfb600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e77565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e87600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e91565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b81565b601281565b60055481565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611020576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b611069600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e91565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506110b860015482611e91565b6001819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611215576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505961012081016040526020815260e0602082015260e0600060408301376024356004353360003560e01c60e01b61012085a45050565b60026020528060005260406000206000915090505481565b60046020528060005260406000206000915090505481565b60006005547fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b8a8a8a8a8a604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018215151515815260200196505050505050506040516020818303038152906040528051906020012060405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16141561148c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4461692f696e76616c69642d616464726573732d30000000000000000000000081525060200191505060405180910390fd5b60018185858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114e9573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614611593576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f696e76616c69642d7065726d6974000000000000000000000000000081525060200191505060405180910390fd5b60008614806115a25750854211155b611614576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f7065726d69742d65787069726564000000000000000000000000000081525060200191505060405180910390fd5b600460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505587146116d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4461692f696e76616c69642d6e6f6e636500000000000000000000000000000081525060200191505060405180910390fd5b6000856116e4576000611706565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b905080600360008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a350505050505050505050565b6040518060400160405280600381526020017f444149000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146118e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505961012081016040526020815260e0602082015260e0600060408301376024356004353360003560e01c60e01b61012085a45050565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611a16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4461692f696e73756666696369656e742d62616c616e6365000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611aee57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b15611cec5780600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611be5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4461692f696e73756666696369656e742d616c6c6f77616e636500000000000081525060200191505060405180910390fd5b611c6b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e77565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b611d35600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e77565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d8460015482611e77565b600181905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000611e01338484610a25565b905092915050565b611e14338383610a25565b505050565b611e24838383610a25565b50505050565b60006020528060005260406000206000915090505481565b6003602052816000526040600020602052806000526040600020600091509150505481565b611e72823383610a25565b505050565b6000828284039150811115611e8b57600080fd5b92915050565b6000828284019150811015611ea557600080fd5b9291505056fea265627a7a72315820c0ae2c29860c0a59d5586a579abbcddfe4bcef0524a87301425cbc58c3e94e3164736f6c634300050c0032", + "storage": { + "0xffee91b17be552e72300cc0c61358eeed4d30ec88b85fc5c2f792d0c45209d31": "0x000000000000000000000000000000000000000000000002B5E3AF16B1880000" + } + } + }, + "blocks": [], + "transactions": [] +} diff --git a/test/e2e/tests/tokens/send-erc20-with-loaded-state.spec.ts b/test/e2e/tests/tokens/send-erc20-with-loaded-state.spec.ts new file mode 100644 index 000000000000..9f3b21bbf268 --- /dev/null +++ b/test/e2e/tests/tokens/send-erc20-with-loaded-state.spec.ts @@ -0,0 +1,80 @@ +import { withFixtures } from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; +import ActivityListPage from '../../page-objects/pages/home/activity-list'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import HomePage from '../../page-objects/pages/home/homepage'; +import SendTokenPage from '../../page-objects/pages/send/send-token-page'; +import TokenOverviewPage from '../../page-objects/pages/token-overview-page'; +import TokenTransferTransactionConfirmation from '../../page-objects/pages/confirmations/redesign/token-transfer-confirmation'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +describe('Send ERC20', function () { + it('should send DAI', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withNetworkControllerOnMainnet() + .withTokensController({ + allTokens: { + '0x1': { + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1': [ + { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + symbol: 'DAI', + decimals: 18, + isERC721: false, + aggregators: [], + }, + ], + }, + }, + }) + .build(), + title: this.test?.fullTitle(), + localNodeOptions: [ + { + type: 'anvil', + options: { + chainId: 1, + loadState: './test/e2e/seeder/network-states/with50Dai.json', + }, + }, + ], + }, + async ({ driver, localNodes }) => { + await loginWithBalanceValidation(driver, localNodes[0]); + + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + await homePage.check_pageIsLoaded(); + await assetListPage.clickOnAsset('DAI'); + + // Send DAI + const tokenOverviewPage = new TokenOverviewPage(driver); + await tokenOverviewPage.check_pageIsLoaded(); + await tokenOverviewPage.clickSend(); + + const sendTokenPage = new SendTokenPage(driver); + await sendTokenPage.check_pageIsLoaded(); + await sendTokenPage.fillRecipient( + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + ); + await sendTokenPage.fillAmount('10'); + await sendTokenPage.goToNextScreen(); + + // Check transaction in the Activity list + const tokenTransferTransactionConfirmation = + new TokenTransferTransactionConfirmation(driver); + await tokenTransferTransactionConfirmation.check_walletInitiatedHeadingTitle(); + await tokenTransferTransactionConfirmation.check_networkParagraph(); + await tokenTransferTransactionConfirmation.check_networkFeeParagraph(); + + await tokenTransferTransactionConfirmation.clickFooterConfirmButton(); + await homePage.check_pageIsLoaded(); + const activityList = new ActivityListPage(driver); + await activityList.check_confirmedTxNumberDisplayedInActivity(); + await activityList.check_txAmountInActivity('-10 DAI'); + }, + ); + }); +}); From 08ca2e7ee51fc7ec71270d83295f8eba7d81c90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Regadas?= Date: Fri, 7 Mar 2025 16:37:41 +0000 Subject: [PATCH 10/17] chore: show solana swaps in activity list (#30811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Swap Txs were not showing before because the data changes slightly, meaning that for swaps we have more than one value in the From and To arrays, so we need to find the common address (own wallet address) in both and use that data to show in the activity list. ## **Related issues** Fixes: Swaps not showing in activity list: https://consensyssoftware.atlassian.net/browse/SOL-191 ## **Manual testing steps** 1. Run thisbranch and import a solana account with swaps txs 2. Open the activity list 3. You should be able to see them listed there ## **Screenshots/Recordings** ### **Before** NA ### **After** ![Screenshot 2025-03-06 at 15 13 56](https://github.com/user-attachments/assets/fded3b02-efbc-4d93-aff0-608c2aadae5b) ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: Alejandro Garcia Anglada --- test/data/mock-accounts.ts | 3 +- ...tichain-transaction-details-modal.test.tsx | 114 ++++++++++--- .../multichain-transaction-details-modal.tsx | 140 +++++++++++----- .../transaction-list.component.js | 65 +++++++- .../transaction-list/transaction-list.test.js | 150 +++++++++++++++++- 5 files changed, 407 insertions(+), 65 deletions(-) diff --git a/test/data/mock-accounts.ts b/test/data/mock-accounts.ts index 932ed9b736f0..8241621c9f11 100644 --- a/test/data/mock-accounts.ts +++ b/test/data/mock-accounts.ts @@ -78,7 +78,7 @@ export const MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET: InternalAccount = { export const MOCK_ACCOUNT_SOLANA_MAINNET: InternalAccount = { id: 'a3f9c2d4-6b8e-4d3a-9b2e-7f4b8e1a9c3d', - address: '3yZe7d5m8V9x2Q1w4u6t8b9n7k5j3h2g1f4d6s8a9p7q2r5t8v', + address: '8A4AptCThfbuknsbteHgGKXczfJpfjuVA9SLTSGaaLGC', options: {}, methods: [SolMethod.SendAndConfirmTransaction], scopes: [SolScope.Mainnet], @@ -96,4 +96,5 @@ export const MOCK_ACCOUNTS = { [MOCK_ACCOUNT_ERC4337.id]: MOCK_ACCOUNT_ERC4337, [MOCK_ACCOUNT_BIP122_P2WPKH.id]: MOCK_ACCOUNT_BIP122_P2WPKH, [MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET.id]: MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET, + [MOCK_ACCOUNT_SOLANA_MAINNET.id]: MOCK_ACCOUNT_SOLANA_MAINNET, }; diff --git a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx index ca64e9475c9f..43cab4929809 100644 --- a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx +++ b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx @@ -1,9 +1,14 @@ import React from 'react'; import { CaipChainId } from '@metamask/utils'; -import { CaipAssetType, TransactionStatus } from '@metamask/keyring-api'; +import { + CaipAssetType, + Transaction, + TransactionStatus, +} from '@metamask/keyring-api'; import { screen, fireEvent } from '@testing-library/react'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { MOCK_ACCOUNT_SOLANA_MAINNET } from '../../../../test/data/mock-accounts'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MultichainNetworks } from '../../../../shared/constants/multichain/networks'; import { MultichainTransactionDetailsModal } from './multichain-transaction-details-modal'; @@ -60,24 +65,53 @@ const mockTransaction = { ], }; +const mockSwapTransaction = { + type: 'swap' as const, + status: TransactionStatus.Confirmed as TransactionStatus, + timestamp: new Date('2023-09-30T12:56:00').getTime(), + id: '5Y64J6gUNd67hM63Aeks3qVLGWRM3A52PFFjqKSPTVDdAZFbaPDHHLTFCs3ioeFcAAXFmqcUftZeLJVZCzqovAJ4', + chain: MultichainNetworks.SOLANA as CaipChainId, + account: 'test-account-id', + events: [], + from: [ + { + address: MOCK_ACCOUNT_SOLANA_MAINNET.address, + asset: { + fungible: true as const, + type: 'native' as CaipAssetType, + amount: '2.5', + unit: 'SOL', + }, + }, + ], + to: [ + { + address: MOCK_ACCOUNT_SOLANA_MAINNET.address, + asset: { + fungible: true as const, + type: 'token' as CaipAssetType, + amount: '100', + unit: 'USDC', + }, + }, + ], + fees: [ + { + type: 'base' as const, + asset: { + fungible: true as const, + type: 'native' as CaipAssetType, + amount: '0.000005', + unit: 'SOL', + }, + }, + ], +}; + const mockProps = { transaction: mockTransaction, onClose: jest.fn(), - multichainNetwork: { - nickname: 'Bitcoin', - isEvmNetwork: false, - chainId: 'bip122:000000000019d6689c085ae165831e93' as CaipChainId, - network: { - type: 'bitcoin', - chainId: 'bip122:000000000019d6689c085ae165831e93' as CaipChainId, - ticker: 'BTC', - nickname: 'Bitcoin', - isAddressCompatible: (_address: string) => true, - rpcPrefs: { - blockExplorerUrl: 'https://explorer.bitcoin.com', - }, - }, - }, + userAddress: MOCK_ACCOUNT_SOLANA_MAINNET.address, }; describe('MultichainTransactionDetailsModal', () => { @@ -92,7 +126,13 @@ describe('MultichainTransactionDetailsModal', () => { jest.clearAllMocks(); }); - const renderComponent = (props = mockProps) => { + const renderComponent = ( + props: { + transaction: Transaction; + onClose: jest.Mock; + userAddress: string; + } = mockProps, + ) => { return renderWithProvider( @@ -125,7 +165,14 @@ describe('MultichainTransactionDetailsModal', () => { it('displays network fee when present', () => { renderComponent(); - expect(screen.getByText('1.0001 BTC')).toBeInTheDocument(); + + const feeElement = + screen.queryByTestId('transaction-network-fee') || + screen.queryByTestId('transaction-base-fee'); + + expect(feeElement).not.toBeNull(); + expect(feeElement?.textContent).toContain('1.0001'); + expect(feeElement?.textContent).toContain('BTC'); }); it('calls onClose when close button is clicked', () => { @@ -236,4 +283,35 @@ describe('MultichainTransactionDetailsModal', () => { `https://blockstream.info/testnet/address/${address}`, ); }); + + it('renders Solana swap transaction details correctly', () => { + const userAddress = MOCK_ACCOUNT_SOLANA_MAINNET.address; + const swapProps = { + transaction: mockSwapTransaction, + onClose: jest.fn(), + userAddress, + }; + + renderComponent(swapProps); + + expect(screen.getByText('Swap')).toBeInTheDocument(); + expect(screen.getByTestId('transaction-amount')).toHaveTextContent( + '2.5 SOL', + ); + + const addressStart = userAddress.substring(0, 6); + const addressElements = screen.getAllByText((_content, element) => { + return element?.textContent?.includes(addressStart) || false; + }); + + expect(addressElements.length).toBeGreaterThan(0); + + const feeElement = + screen.queryByTestId('transaction-network-fee') || + screen.queryByTestId('transaction-base-fee'); + + expect(feeElement).not.toBeNull(); + expect(feeElement?.textContent).toContain('0.000005'); + expect(feeElement?.textContent).toContain('SOL'); + }); }); diff --git a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.tsx b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.tsx index 27d13f33222d..54bf8b8f50ad 100644 --- a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.tsx +++ b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.tsx @@ -1,6 +1,11 @@ import React, { useContext } from 'react'; import { capitalize } from 'lodash'; -import { Transaction, TransactionStatus } from '@metamask/keyring-api'; +import { + Transaction, + TransactionStatus, + Asset, + TransactionType, +} from '@metamask/keyring-api'; import { Display, FlexDirection, @@ -48,11 +53,13 @@ import { export type MultichainTransactionDetailsModalProps = { transaction: Transaction; onClose: () => void; + userAddress: string; }; export function MultichainTransactionDetailsModal({ transaction, onClose, + userAddress, }: MultichainTransactionDetailsModalProps) { const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); @@ -70,7 +77,7 @@ export function MultichainTransactionDetailsModal({ } }; - const getAssetDisplay = (asset: typeof fromAsset) => { + const getAssetDisplay = (asset: Asset | null) => { if (!asset) { return null; } @@ -83,22 +90,42 @@ export function MultichainTransactionDetailsModal({ return null; }; - if (!transaction?.from?.[0] || !transaction?.to?.[0]) { - return null; + const { id: txId, fees, timestamp, status, chain, type } = transaction; + + let fromAddress, toAddress, asset; + + const txFromEntry = transaction.from?.find( + (entry) => entry?.address === userAddress, + ); + const txToEntry = transaction.to?.find( + (entry) => entry?.address === userAddress, + ); + + switch (type) { + case TransactionType.Swap: + fromAddress = txFromEntry?.address || ''; + toAddress = txToEntry?.address || ''; + asset = txFromEntry?.asset || null; + break; + case TransactionType.Send: + fromAddress = + txFromEntry?.address || transaction.from?.[0]?.address || ''; + toAddress = transaction.to?.[0]?.address || ''; + asset = txFromEntry?.asset || transaction.from?.[0]?.asset || null; + break; + case TransactionType.Receive: + fromAddress = transaction.from?.[0]?.address || ''; + toAddress = txToEntry?.address || transaction.to?.[0]?.address || ''; + asset = txToEntry?.asset || transaction.to?.[0]?.asset || null; + break; + default: + fromAddress = transaction.from?.[0]?.address || ''; + toAddress = transaction.to?.[0]?.address || ''; + asset = transaction.to?.[0]?.asset || null; } - // We only support 1 recipient for "from" and "to" for now: - const { - id: txId, - from: [{ address: fromAddress, asset: fromAsset }], - to: [{ address: toAddress }], - fees: [{ asset: feeAsset }], - fees, - timestamp, - status, - chain, - type, - } = transaction; + const baseFee = fees?.find((fee) => fee.type === 'base')?.asset; + const priorityFee = fees?.find((fee) => fee.type === 'priority')?.asset; return ( {/* Status */} {/* From */} - {getAssetDisplay(fromAsset)} + {getAssetDisplay(asset)} - {/* Network Fee */} + {/* Network Fees */} {fees?.length > 0 && ( - - - {t('networkFee')} - - - - {getAssetDisplay(feeAsset)} - - - + <> + {baseFee && ( + + + {t('networkFee')} + + + + {getAssetDisplay(baseFee)} + + + + )} + + {priorityFee && ( + + + {t('priorityFee')} + + + + {getAssetDisplay(priorityFee)} + + + + )} + )} diff --git a/ui/components/app/transaction-list/transaction-list.component.js b/ui/components/app/transaction-list/transaction-list.component.js index 6417990b8689..dcaa91fc955c 100644 --- a/ui/components/app/transaction-list/transaction-list.component.js +++ b/ui/components/app/transaction-list/transaction-list.component.js @@ -334,6 +334,35 @@ export default function TransactionList({ setSelectedTransaction(transaction); }, []); + const getTransactionDisplayAmount = (transaction, userAddress) => { + const userFromEntry = transaction.from?.find( + (entry) => entry.address === userAddress, + ); + + const userToEntry = transaction.to?.find( + (entry) => entry.address === userAddress, + ); + + // Amount of the token sent + if (userFromEntry?.asset?.amount) { + return `-${userFromEntry.asset.amount} ${userFromEntry.asset.unit || ''}`; + } + + // Amount of the token received + if (userToEntry?.asset?.amount) { + return `${userToEntry.asset.amount} ${userToEntry.asset.unit || ''}`; + } + + // Fallback: Amount of the token received + if (transaction.from?.[0]?.asset?.amount) { + return `${transaction.from?.[0]?.asset?.amount} ${ + transaction.from?.[0]?.asset?.unit || '' + }`; + } + + return ''; + }; + const multichainNetwork = useMultichainSelector( getMultichainNetwork, selectedAccount, @@ -341,6 +370,28 @@ export default function TransactionList({ const trackEvent = useContext(MetaMetricsContext); + const formatTransactionTitle = (transaction, userAddress) => { + switch (transaction.type) { + case TransactionType.swap: { + const userToEntry = transaction.to?.find( + (entry) => entry.address === userAddress, + ); + const userFromEntry = transaction.from?.find( + (entry) => entry.address === userAddress, + ); + + if (userFromEntry && userToEntry) { + return `${t('swap')} ${userFromEntry.asset.unit} ${'to'} ${ + userToEntry.asset.unit + }`; + } + return capitalize(transaction.type); + } + default: + return capitalize(transaction.type); + } + }; + if (!isEvmAccountType(selectedAccount.type)) { const addressLink = getMultichainAccountUrl( selectedAccount.address, @@ -354,6 +405,7 @@ export default function TransactionList({ toggleShowDetails(null)} + userAddress={selectedAccount.address} /> )} @@ -427,17 +479,20 @@ export default function TransactionList({ title="Primary Currency" variant="body-lg-medium" > - {transaction.from?.[0]?.asset?.amount && - transaction.from[0]?.asset?.unit - ? `${transaction.from[0].asset.amount} ${transaction.from[0].asset.unit}` - : ''} + {getTransactionDisplayAmount( + transaction, + selectedAccount.address, + )} } title={ transaction.isBridgeTx ? t('bridge') - : capitalize(transaction.type) + : formatTransactionTitle( + transaction, + selectedAccount.address, + ) } // eslint-disable-next-line react/jsx-no-duplicate-props subtitle={ diff --git a/ui/components/app/transaction-list/transaction-list.test.js b/ui/components/app/transaction-list/transaction-list.test.js index 48e42fb2c309..9fa56b4494ce 100644 --- a/ui/components/app/transaction-list/transaction-list.test.js +++ b/ui/components/app/transaction-list/transaction-list.test.js @@ -3,7 +3,10 @@ import { fireEvent } from '@testing-library/react'; import { renderWithProvider } from '../../../../test/jest'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; -import { MOCK_ACCOUNT_BIP122_P2WPKH } from '../../../../test/data/mock-accounts'; +import { + MOCK_ACCOUNT_BIP122_P2WPKH, + MOCK_ACCOUNT_SOLANA_MAINNET, +} from '../../../../test/data/mock-accounts'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, @@ -60,6 +63,135 @@ const btcState = { }, }; +const solanaSwapState = { + metamask: { + ...mockState.metamask, + nonEvmTransactions: { + [MOCK_ACCOUNT_SOLANA_MAINNET.id]: { + transactions: [ + { + id: '2pfnv4drhnitfzCFKxiRoJMzFQpG7wZ9mpRQVk7xm5TQ27g6FZH95HVF6KgwQBS872yGtyhuq57jXXS1y29ub11', + timestamp: 1740480781, + chain: MultichainNetworks.SOLANA, + status: 'confirmed', + type: 'swap', + from: [ + { + address: '8kR2HTHzPtTJuzpFZ8jtGCQ9TpahPaWbZfTNRs2GJdxq', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.000073111', + }, + }, + { + address: MOCK_ACCOUNT_SOLANA_MAINNET.address, + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.01', + }, + }, + { + address: 'HUCjBnmd4FoUjCCMYQ9xFz1ce1r8vWAd8uMhUQakE2FR', + asset: { + fungible: true, + type: '', + unit: 'BONK', + amount: '2583.728601', + }, + }, + { + address: '3msVd34R5KxonDzyNSV5nT19UtUeJ2RF1NaQhvVPNLxL', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.000073111', + }, + }, + ], + to: [ + { + address: 'CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.000000723', + }, + }, + { + address: 'HUCjBnmd4FoUjCCMYQ9xFz1ce1r8vWAd8uMhUQakE2FR', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.00007238', + }, + }, + { + address: MOCK_ACCOUNT_SOLANA_MAINNET.address, + asset: { + fungible: true, + type: '', + unit: 'BONK', + amount: '2583.72', + }, + }, + { + address: '3msVd34R5KxonDzyNSV5nT19UtUeJ2RF1NaQhvVPNLxL', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.01', + }, + }, + ], + fees: [ + { + type: 'base', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.000005', + }, + }, + { + type: 'priority', + asset: { + fungible: true, + type: '', + unit: 'SOL', + amount: '0.000069798', + }, + }, + ], + events: [{ status: 'confirmed', timestamp: 1740480781 }], + }, + ], + next: null, + lastUpdated: expect.any(Number), + }, + }, + internalAccounts: { + ...mockState.metamask.internalAccounts, + accounts: { + ...mockState.metamask.internalAccounts.accounts, + [MOCK_ACCOUNT_SOLANA_MAINNET.id]: MOCK_ACCOUNT_SOLANA_MAINNET, + }, + selectedAccount: MOCK_ACCOUNT_SOLANA_MAINNET.id, + }, + selectedAddress: MOCK_ACCOUNT_SOLANA_MAINNET.address, + completedOnboarding: true, + transactions: [], + }, +}; + const mockTrackEvent = jest.fn(); const render = (state = defaultState) => { @@ -182,4 +314,20 @@ describe('TransactionList', () => { ), ).toBeNull(); }); + + it('renders TransactionList component and shows a Solana Swap Tx in the activity list', () => { + const { getByText, getByRole, getByTestId } = render(solanaSwapState); + + expect(getByText('Confirmed')).toBeInTheDocument(); + expect(getByText('Swap SOL to BONK')).toBeInTheDocument(); + + expect(getByTestId('activity-list-item')).toBeInTheDocument(); + + expect(getByText('-0.01 SOL')).toBeInTheDocument(); + + const viewOnExplorerBtn = getByRole('button', { + name: 'View on block explorer', + }); + expect(viewOnExplorerBtn).toBeInTheDocument(); + }); }); From d2d990b553eb4d59d70ce274a481d647c8176225 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Fri, 7 Mar 2025 17:45:45 +0100 Subject: [PATCH 11/17] chore: Update `CODEOWNERS` file for template renderer (#30855) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This updates the `CODEOWNERS` file for the `ui/components/app/metamask-template-renderer` folder to be co-owned by the confirmations team and Snaps team. Related to: MetaMask/snaps#3206 [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30855?quickstart=1) ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: Frederik Bolding --- .github/CODEOWNERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 80ccc370ffe0..54c1250b648f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -111,7 +111,9 @@ app/scripts/controllers/swaps @MetaMask/swaps-engineers **/snaps/** @MetaMask/snaps-devs shared/constants/permissions.ts @MetaMask/snaps-devs ui/helpers/utils/permission.js @MetaMask/snaps-devs -ui/hooks/useTransactionInsights.js @MetaMask/snaps-devs + +# Co-owned by Confirmations and Snaps +ui/components/app/metamask-template-renderer @MetaMask/confirmations @MetaMask/snaps-devs # Wallet UX ui/components/multichain @MetaMask/wallet-ux From a0b8be98fbc4b477a11bb3eea1838ba0157dd84a Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:01:15 +0100 Subject: [PATCH 12/17] test: remove `generateGanacheOptions` (#30854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Removing unnecesay `generateGanacheOptions` method, in the process of anvil migration. Skipping quality gate as there are no functional changes. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30854?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Check ci jobs - Everything should continue to work normally ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- test/e2e/helpers.js | 19 ------------------- test/e2e/json-rpc/eth_sendTransaction.spec.js | 19 +++---------------- test/e2e/tests/bridge/bridge-test-utils.ts | 5 ++--- test/e2e/tests/metrics/swaps.spec.js | 7 ------- .../tests/swap-send/swap-send-test-utils.ts | 3 +-- .../tests/transaction/edit-gas-fee.spec.js | 13 ++++--------- .../tests/transaction/gas-estimates.spec.js | 9 ++------- .../transaction/multiple-transactions.spec.js | 5 ++--- .../transaction/navigate-transactions.spec.js | 11 +++++------ test/e2e/tests/transaction/send-edit.spec.js | 8 ++------ test/e2e/tests/transaction/send-max.spec.js | 12 ++++++------ .../stuck-approved-transaction.spec.ts | 4 ++-- 12 files changed, 29 insertions(+), 86 deletions(-) diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index be04a81f4e59..f72a80ce38cf 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -555,24 +555,6 @@ const multipleGanacheOptionsForType2Transactions = { hardfork: 'london', }; -const generateGanacheOptions = ({ - secretKey = PRIVATE_KEY, - balance = convertETHToHexGwei(DEFAULT_GANACHE_ETH_BALANCE_DEC), - ...otherProps -}) => { - const accounts = [ - { - secretKey, - balance, - }, - ]; - - return { - accounts, - ...otherProps, // eg: hardfork - }; -}; - // Edit priority gas fee form const editGasFeeForm = async (driver, gasLimit, gasPrice) => { const inputs = await driver.findElements('input[type="number"]'); @@ -953,7 +935,6 @@ module.exports = { unlockWallet, logInWithBalanceValidation, locateAccountBalanceDOM, - generateGanacheOptions, WALLET_PASSWORD, WINDOW_TITLES, convertETHToHexGwei, diff --git a/test/e2e/json-rpc/eth_sendTransaction.spec.js b/test/e2e/json-rpc/eth_sendTransaction.spec.js index 2a3981ab7cfc..41caabc2155e 100644 --- a/test/e2e/json-rpc/eth_sendTransaction.spec.js +++ b/test/e2e/json-rpc/eth_sendTransaction.spec.js @@ -1,10 +1,5 @@ const { strict: assert } = require('assert'); -const { - withFixtures, - unlockWallet, - WINDOW_TITLES, - generateGanacheOptions, -} = require('../helpers'); +const { withFixtures, unlockWallet, WINDOW_TITLES } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); describe('eth_sendTransaction', function () { @@ -18,11 +13,7 @@ describe('eth_sendTransaction', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ - hardfork: 'london', - mnemonic: - 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent', - }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -68,11 +59,7 @@ describe('eth_sendTransaction', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ - hardfork: 'london', - mnemonic: - 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent', - }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { diff --git a/test/e2e/tests/bridge/bridge-test-utils.ts b/test/e2e/tests/bridge/bridge-test-utils.ts index 57c9bbfb6565..1af3103dd6e0 100644 --- a/test/e2e/tests/bridge/bridge-test-utils.ts +++ b/test/e2e/tests/bridge/bridge-test-utils.ts @@ -1,6 +1,5 @@ import { Mockttp } from 'mockttp'; import FixtureBuilder from '../../fixture-builder'; -import { generateGanacheOptions } from '../../helpers'; import { BRIDGE_CLIENT_ID, BRIDGE_DEV_API_BASE_URL, @@ -139,10 +138,10 @@ export const getBridgeFixtures = ( testSpecificMock: mockServer(featureFlags), smartContract: SMART_CONTRACTS.HST, ethConversionInUsd: ETH_CONVERSION_RATE_USD, - localNodeOptions: generateGanacheOptions({ + localNodeOptions: { hardfork: 'london', chain: { chainId: CHAIN_IDS.MAINNET }, - }), + }, title, }; }; diff --git a/test/e2e/tests/metrics/swaps.spec.js b/test/e2e/tests/metrics/swaps.spec.js index 0023eda78de6..93eac6d2f846 100644 --- a/test/e2e/tests/metrics/swaps.spec.js +++ b/test/e2e/tests/metrics/swaps.spec.js @@ -3,11 +3,9 @@ const { toHex } = require('@metamask/controller-utils'); const FixtureBuilder = require('../../fixture-builder'); const { withFixtures, - generateGanacheOptions, unlockWallet, getEventPayloads, assertInAnyOrder, - genRandInitBal, } = require('../../helpers'); const { buildQuote, @@ -94,8 +92,6 @@ async function mockSegmentAndMetaswapRequests(mockServer) { // TODO: (MM-PENDING) These tests are planned for deprecation as part of swaps testing revamp describe('Swap Eth for another Token', function () { it('Completes a Swap between ETH and DAI after changing initial rate', async function () { - const { initialBalanceInHex } = genRandInitBal(); - await withFixtures( { fixtures: new FixtureBuilder() @@ -104,9 +100,6 @@ describe('Swap Eth for another Token', function () { participateInMetaMetrics: true, }) .build(), - localNodeOptions: generateGanacheOptions({ - balance: initialBalanceInHex, - }), title: this.test.fullTitle(), testSpecificMock: mockSegmentAndMetaswapRequests, }, diff --git a/test/e2e/tests/swap-send/swap-send-test-utils.ts b/test/e2e/tests/swap-send/swap-send-test-utils.ts index b3617237715d..46ca47de9c4d 100644 --- a/test/e2e/tests/swap-send/swap-send-test-utils.ts +++ b/test/e2e/tests/swap-send/swap-send-test-utils.ts @@ -2,7 +2,6 @@ import { strict as assert } from 'assert'; import { Mockttp } from 'mockttp'; import FixtureBuilder from '../../fixture-builder'; import { SWAPS_API_V2_BASE_URL } from '../../../../shared/constants/swaps'; -import { generateGanacheOptions } from '../../helpers'; import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; import { SWAP_SEND_QUOTES_RESPONSE_ETH_TST } from './mocks/eth-data'; @@ -296,7 +295,7 @@ export const getSwapSendFixtures = ( smartContract: SMART_CONTRACTS.HST, ethConversionInUsd: ETH_CONVERSION_RATE_USD, testSpecificMock: mockSwapsApi(swapsQuotes, swapsQuery), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title, }; }; diff --git a/test/e2e/tests/transaction/edit-gas-fee.spec.js b/test/e2e/tests/transaction/edit-gas-fee.spec.js index bd2cf598d90b..c389f56f45b2 100644 --- a/test/e2e/tests/transaction/edit-gas-fee.spec.js +++ b/test/e2e/tests/transaction/edit-gas-fee.spec.js @@ -4,12 +4,7 @@ const { createDappTransaction, } = require('../../page-objects/flows/transaction'); -const { - withFixtures, - unlockWallet, - generateGanacheOptions, - WINDOW_TITLES, -} = require('../../helpers'); +const { withFixtures, unlockWallet, WINDOW_TITLES } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Editing Confirm Transaction', function () { @@ -17,7 +12,7 @@ describe('Editing Confirm Transaction', function () { await withFixtures( { fixtures: new FixtureBuilder().build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -97,7 +92,7 @@ describe('Editing Confirm Transaction', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -178,7 +173,7 @@ describe('Editing Confirm Transaction', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), dapp: true, }, diff --git a/test/e2e/tests/transaction/gas-estimates.spec.js b/test/e2e/tests/transaction/gas-estimates.spec.js index 043b8d852da0..ba76ed305c8d 100644 --- a/test/e2e/tests/transaction/gas-estimates.spec.js +++ b/test/e2e/tests/transaction/gas-estimates.spec.js @@ -2,19 +2,14 @@ const { withFixtures, logInWithBalanceValidation, openActionMenuAndStartSendFlow, - generateGanacheOptions, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); const { CHAIN_IDS } = require('../../../../shared/constants/network'); const { GAS_API_BASE_URL } = require('../../../../shared/constants/swaps'); describe('Gas estimates generated by MetaMask', function () { - const preLondonGanacheOptions = generateGanacheOptions({ - hardfork: 'berlin', - }); - const postLondonGanacheOptions = generateGanacheOptions({ - hardfork: 'london', - }); + const preLondonGanacheOptions = { hardfork: 'berlin' }; + const postLondonGanacheOptions = { hardfork: 'london' }; describe('Send on a network that is EIP-1559 compatible', function () { it('show expected gas defaults', async function () { diff --git a/test/e2e/tests/transaction/multiple-transactions.spec.js b/test/e2e/tests/transaction/multiple-transactions.spec.js index 1053a413c808..c7404c653db0 100644 --- a/test/e2e/tests/transaction/multiple-transactions.spec.js +++ b/test/e2e/tests/transaction/multiple-transactions.spec.js @@ -4,7 +4,6 @@ const { openDapp, regularDelayMs, unlockWallet, - generateGanacheOptions, WINDOW_TITLES, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); @@ -17,7 +16,7 @@ describe('Multiple transactions', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -79,7 +78,7 @@ describe('Multiple transactions', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { diff --git a/test/e2e/tests/transaction/navigate-transactions.spec.js b/test/e2e/tests/transaction/navigate-transactions.spec.js index 6bcd74ec477e..ad8496eadea4 100644 --- a/test/e2e/tests/transaction/navigate-transactions.spec.js +++ b/test/e2e/tests/transaction/navigate-transactions.spec.js @@ -10,7 +10,6 @@ const { openDapp, locateAccountBalanceDOM, unlockWallet, - generateGanacheOptions, WINDOW_TITLES, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); @@ -25,7 +24,7 @@ describe('Navigate transactions', function () { .withPreferencesControllerTxSimulationsDisabled() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), dapp: true, }, @@ -65,7 +64,7 @@ describe('Navigate transactions', function () { .withPermissionControllerConnectedToTestDapp() .withPreferencesControllerTxSimulationsDisabled() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -99,7 +98,7 @@ describe('Navigate transactions', function () { .withPreferencesControllerTxSimulationsDisabled() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), dapp: true, }, @@ -124,7 +123,7 @@ describe('Navigate transactions', function () { .withPreferencesControllerTxSimulationsDisabled() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), dapp: true, }, @@ -149,7 +148,7 @@ describe('Navigate transactions', function () { .withPreferencesControllerTxSimulationsDisabled() .withPermissionControllerConnectedToTestDapp() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), dapp: true, }, diff --git a/test/e2e/tests/transaction/send-edit.spec.js b/test/e2e/tests/transaction/send-edit.spec.js index d90cad998f27..a99cf4af1921 100644 --- a/test/e2e/tests/transaction/send-edit.spec.js +++ b/test/e2e/tests/transaction/send-edit.spec.js @@ -3,11 +3,7 @@ const { createInternalTransaction, } = require('../../page-objects/flows/transaction'); -const { - withFixtures, - unlockWallet, - generateGanacheOptions, -} = require('../../helpers'); +const { withFixtures, unlockWallet } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Editing Confirm Transaction', function () { @@ -110,7 +106,7 @@ describe('Editing Confirm Transaction', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { diff --git a/test/e2e/tests/transaction/send-max.spec.js b/test/e2e/tests/transaction/send-max.spec.js index 41d2e44891f0..9454cd572ac0 100644 --- a/test/e2e/tests/transaction/send-max.spec.js +++ b/test/e2e/tests/transaction/send-max.spec.js @@ -1,4 +1,4 @@ -const { withFixtures, generateGanacheOptions } = require('../../helpers'); +const { withFixtures } = require('../../helpers'); const { createInternalTransactionWithMaxAmount, reviewTransaction, @@ -25,7 +25,7 @@ describe('Sending with max amount', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, driverOptions: { timeOut: 15000 }, title: this.test.fullTitle(), }, @@ -55,7 +55,7 @@ describe('Sending with max amount', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -122,7 +122,7 @@ describe('Sending with max amount', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { @@ -177,7 +177,7 @@ describe('Sending with max amount', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, driverOptions: { timeOut: 15000 }, title: this.test.fullTitle(), }, @@ -252,7 +252,7 @@ describe('Sending with max amount', function () { }, }) .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test.fullTitle(), }, async ({ driver }) => { diff --git a/test/e2e/tests/transaction/stuck-approved-transaction.spec.ts b/test/e2e/tests/transaction/stuck-approved-transaction.spec.ts index 5d0d12fcb21f..54df27530167 100644 --- a/test/e2e/tests/transaction/stuck-approved-transaction.spec.ts +++ b/test/e2e/tests/transaction/stuck-approved-transaction.spec.ts @@ -1,5 +1,5 @@ import { Suite } from 'mocha'; -import { withFixtures, generateGanacheOptions } from '../../helpers'; +import { withFixtures } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; import { Driver } from '../../webdriver/driver'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; @@ -13,7 +13,7 @@ describe('Editing Confirm Transaction', function (this: Suite) { fixtures: new FixtureBuilder() .withTransactionControllerApprovedTransaction() .build(), - localNodeOptions: generateGanacheOptions({ hardfork: 'london' }), + localNodeOptions: { hardfork: 'london' }, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { From bb8cbdff8858ff36e48f08319d962eab3f6bdacd Mon Sep 17 00:00:00 2001 From: Gustavo Silva Date: Fri, 7 Mar 2025 17:35:49 +0000 Subject: [PATCH 13/17] fix: mms-2025 text ellipsis (#30845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Add ellipsis to the text in the activity list [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30845?quickstart=1) ## **Related issues** Fixes: [mms-2025](https://consensyssoftware.atlassian.net/jira/software/projects/MMS/boards/447?assignee=624321812e101c006a8cfb7e&selectedIssue=MMS-2025) ## **Manual testing steps** 1. Create a bridge to Binance smart chain 2. Check the activity text of the transaction 3. ## **Screenshots/Recordings** ### **Before** Screenshot 2025-03-06 at 22 47 52 ### **After** Screenshot 2025-03-06 at 22 44 34 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../__snapshots__/activity-list-item.test.js.snap | 4 ++-- .../multichain/activity-list-item/activity-list-item.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/components/multichain/activity-list-item/__snapshots__/activity-list-item.test.js.snap b/ui/components/multichain/activity-list-item/__snapshots__/activity-list-item.test.js.snap index 8f0c24760246..90ddf48ba4f3 100644 --- a/ui/components/multichain/activity-list-item/__snapshots__/activity-list-item.test.js.snap +++ b/ui/components/multichain/activity-list-item/__snapshots__/activity-list-item.test.js.snap @@ -13,7 +13,7 @@ exports[`ActivityListItem should match snapshot with no props 1`] = ` class="mm-box activity-list-item__content-container mm-box--display-inline-flex mm-box--justify-content-space-between mm-box--width-full" >

Date: Fri, 7 Mar 2025 11:40:32 -0600 Subject: [PATCH 14/17] fix: Perf: Prevent MultipleNotifications rerenders (#30288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** The `MultipleNotifications` component rerenders on a non-matching array of `null` values. This prevents that issue. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30288?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- ui/pages/home/home.component.js | 495 ++++++++++++++++---------------- 1 file changed, 251 insertions(+), 244 deletions(-) diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index e78708618356..1ccabf28c376 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -387,256 +387,263 @@ export default class Home extends PureComponent { t('outdatedBrowserNotification') ); - return ( - - {newNftAddedMessage === 'success' ? ( - - - - {t('newNftAddedMessage')} - - - - } - /> - ) : null} - {removeNftMessage === 'success' ? ( - - - - {t('removeNftMessage')} - - - - } - /> - ) : null} - {removeNftMessage === 'error' ? ( - - - - {t('removeNftErrorMessage')} - - - - } - /> - ) : null} - {newNetworkAddedName ? ( - - - - {t('newNetworkAdded', [newNetworkAddedName])} + const items = [ + newNftAddedMessage === 'success' ? ( + + + + {t('newNftAddedMessage')} + + + + } + /> + ) : null, + removeNftMessage === 'success' ? ( + + + + {t('removeNftMessage')} + + + + } + /> + ) : null, + removeNftMessage === 'error' ? ( + + + + {t('removeNftErrorMessage')} + + + + } + /> + ) : null, + newNetworkAddedName ? ( + + + + {t('newNetworkAdded', [newNetworkAddedName])} + + clearNewNetworkAdded()} + className="home__new-network-notification-close" + /> + + } + /> + ) : null, + editedNetwork?.editCompleted ? ( + + + + {editedNetwork.newNetwork + ? t('newNetworkAdded', [editedNetwork.nickname]) + : t('newNetworkEdited', [editedNetwork.nickname])} + + clearEditedNetwork()} + className="home__new-network-notification-close" + /> + + } + /> + ) : null, + newTokensImported ? ( + + + + + {t('newTokensImportedTitle')} - clearNewNetworkAdded()} - className="home__new-network-notification-close" - /> - - } - /> - ) : null} - {editedNetwork?.editCompleted ? ( - - - - {editedNetwork.newNetwork - ? t('newNetworkAdded', [editedNetwork.nickname]) - : t('newNetworkEdited', [editedNetwork.nickname])} + + {t('newTokensImportedMessage', [newTokensImported])} - clearEditedNetwork()} - className="home__new-network-notification-close" - /> - - } - /> - ) : null} - {newTokensImported ? ( - - - - - {t('newTokensImportedTitle')} - - - {t('newTokensImportedMessage', [newTokensImported])} - - - - setNewTokensImported('')} - className="home__new-tokens-imported-notification-close" - /> + + setNewTokensImported('')} + className="home__new-tokens-imported-notification-close" + /> + + } + /> + ) : null, + newTokensImportedError ? ( + + + + {t('importTokensError')} + + + + } + /> + ) : null, + shouldShowWeb3ShimUsageNotification ? ( + + global.platform.openTab({ url: ZENDESK_URLS.LEGACY_WEB3 }) + } + > + {t('here')} + , + ])} + ignoreText={t('dismiss')} + onIgnore={(disable) => { + setWeb3ShimUsageAlertDismissed(originOfCurrentTab); + if (disable) { + disableWeb3ShimUsageAlert(); } - /> - ) : null} - {newTokensImportedError ? ( - - - - {t('importTokensError')} - - - + }} + checkboxText={t('dontShowThisAgain')} + checkboxTooltipText={t('canToggleInSettings')} + /> + ) : null, + ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) + shouldShowSeedPhraseReminder ? ( + { + const backUpSRPRoute = `${ONBOARDING_SECURE_YOUR_WALLET_ROUTE}/?isFromReminder=true`; + if (isPopup) { + global.platform.openExtensionInBrowser(backUpSRPRoute); + } else { + history.push(backUpSRPRoute); } - /> - ) : null} - {shouldShowWeb3ShimUsageNotification ? ( - - global.platform.openTab({ url: ZENDESK_URLS.LEGACY_WEB3 }) - } - > - {t('here')} - , - ])} - ignoreText={t('dismiss')} - onIgnore={(disable) => { - setWeb3ShimUsageAlertDismissed(originOfCurrentTab); - if (disable) { - disableWeb3ShimUsageAlert(); + }} + infoText={t('backupApprovalInfo')} + /> + ) : null, + ///: END:ONLY_INCLUDE_IF + infuraBlocked && this.state.canShowBlockageNotification ? ( + + global.platform.openTab({ url: ZENDESK_URLS.INFURA_BLOCKAGE }) } - }} - checkboxText={t('dontShowThisAgain')} - checkboxTooltipText={t('canToggleInSettings')} - key="home-web3ShimUsageNotification" - /> - ) : null} - { - ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) - shouldShowSeedPhraseReminder ? ( - { - const backUpSRPRoute = `${ONBOARDING_SECURE_YOUR_WALLET_ROUTE}/?isFromReminder=true`; - if (isPopup) { - global.platform.openExtensionInBrowser(backUpSRPRoute); - } else { - history.push(backUpSRPRoute); - } - }} - infoText={t('backupApprovalInfo')} - key="home-backupApprovalNotice" - /> - ) : null - ///: END:ONLY_INCLUDE_IF - } - {infuraBlocked && this.state.canShowBlockageNotification ? ( - - global.platform.openTab({ url: ZENDESK_URLS.INFURA_BLOCKAGE }) - } - > - {t('here')} - , - ])} - ignoreText={t('dismiss')} - onIgnore={() => { - this.setState({ - canShowBlockageNotification: false, - }); - }} - key="home-infuraBlockedNotification" - /> - ) : null} - {showOutdatedBrowserWarning ? ( - - ) : null} - - ); + > + {t('here')} + , + ])} + ignoreText={t('dismiss')} + onIgnore={() => { + this.setState({ + canShowBlockageNotification: false, + }); + }} + /> + ) : null, + showOutdatedBrowserWarning ? ( + + ) : null, + ].filter(Boolean); + + return items.length ? ( + {items} + ) : null; } renderOnboardingPopover = () => { From fb3f6ada6da9a1aa1bf087057d65c823419772ad Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 7 Mar 2025 19:03:18 +0100 Subject: [PATCH 15/17] fix: fix hideZeroBalance setting for non evm asset list (#30816) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** PR to respect the hideZeroBalance setting in the asset list for non-evm tokens. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30816?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/30623 ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** https://github.com/user-attachments/assets/3c051162-8a75-4c02-b8d2-5bea7318cd49 ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../app/assets/token-list/token-list.tsx | 2 +- ui/components/app/assets/types.ts | 14 +- .../assets/util/calculateTokenFiatAmount.ts | 5 +- ui/selectors/assets.test.ts | 124 ++++++++++++++++++ ui/selectors/assets.ts | 52 +++++--- 5 files changed, 173 insertions(+), 24 deletions(-) diff --git a/ui/components/app/assets/token-list/token-list.tsx b/ui/components/app/assets/token-list/token-list.tsx index b869b9c87a38..976db7ca2e13 100644 --- a/ui/components/app/assets/token-list/token-list.tsx +++ b/ui/components/app/assets/token-list/token-list.tsx @@ -48,7 +48,7 @@ function TokenList({ onTokenClick }: TokenListProps) { const sortedFilteredTokens = useMemo(() => { const balances = isEvm ? evmBalances : multichainAssets; - const filteredAssets: TokenWithFiatAmount[] = filterAssets(balances, [ + const filteredAssets = filterAssets(balances as TokenWithFiatAmount[], [ { key: 'chainId', opts: isEvm ? networkFilter : { [currentNetwork.chainId]: true }, diff --git a/ui/components/app/assets/types.ts b/ui/components/app/assets/types.ts index 1ba36bf289a2..6eab815345c3 100644 --- a/ui/components/app/assets/types.ts +++ b/ui/components/app/assets/types.ts @@ -1,4 +1,4 @@ -import { Hex } from '@metamask/utils'; +import { CaipAssetType, CaipChainId, Hex } from '@metamask/utils'; // Common mixin for primary and secondary display values export type TokenDisplayValues = { @@ -22,8 +22,18 @@ export type BaseToken = { isNative?: boolean; }; +// type created for non-evm tokens +export type NonEvmBaseToken = { + address: CaipAssetType; + symbol: string; + image: string; + decimals: number; + chainId: CaipChainId; + isNative?: boolean; +}; + // Token type with optional aggregators -export type Token = BaseToken & { +export type Token = (BaseToken | NonEvmBaseToken) & { aggregators?: string[]; }; diff --git a/ui/components/app/assets/util/calculateTokenFiatAmount.ts b/ui/components/app/assets/util/calculateTokenFiatAmount.ts index 5917665e82cd..b31e8dc47ddc 100644 --- a/ui/components/app/assets/util/calculateTokenFiatAmount.ts +++ b/ui/components/app/assets/util/calculateTokenFiatAmount.ts @@ -23,8 +23,9 @@ export function calculateTokenFiatAmount({ const { address, isNative, symbol } = token; // Market and conversion rate data - const baseCurrency = marketData[chainId]?.[address]?.currency; - const tokenMarketPrice = Number(marketData[chainId]?.[address]?.price) || 0; + const baseCurrency = marketData[chainId as Hex]?.[address as Hex]?.currency; + const tokenMarketPrice = + Number(marketData[chainId as Hex]?.[address as Hex]?.price) || 0; const tokenExchangeRate = currencyRates[baseCurrency]?.conversionRate || 0; const parsedBalance = parseFloat(String(balance)); diff --git a/ui/selectors/assets.test.ts b/ui/selectors/assets.test.ts index cf6a9b799717..aa8e758b858b 100644 --- a/ui/selectors/assets.test.ts +++ b/ui/selectors/assets.test.ts @@ -4,6 +4,7 @@ import { AssetsState, getAccountAssets, getAssetsMetadata, + getMultiChainAssets, } from './assets'; const mockRatesState = { @@ -73,3 +74,126 @@ describe('getAssetsRates', () => { expect(() => getAssetsRates(invalidState)).toThrow(); }); }); + +describe('getMultiChainAssets', () => { + const mockAccountId = '5132883f-598e-482c-a02b-84eeaa352f5b'; + const mockMultichainBalances = { + [mockAccountId]: { + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501': { + amount: '0.051724127', + unit: 'SOL', + }, + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v': + { + amount: '0', + unit: 'USDC', + }, + }, + }; + + const mockAccountAssets = { + [mockAccountId]: [ + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + ], + }; + it('should return assets with zero balance with hideZeroBalanceTokens set to false', () => { + const mockState = { + metamask: { + ...mockAssetsState.metamask, + ...mockRatesState.metamask, + accountsAssets: mockAccountAssets, + preferences: { + hideZeroBalanceTokens: false, + }, + balances: mockMultichainBalances, + }, + }; + const result = getMultiChainAssets(mockState, { + address: '0xAddress', + id: mockAccountId, + }); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + title: 'Token 1', + address: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', + symbol: 'TKN1', + image: 'https://example.com/token-1.png', + decimals: 9, + chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + isNative: true, + primary: '0.051724127', + secondary: 0, + }), + expect.objectContaining({ + title: 'USDC', + address: + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + symbol: 'USDC', + image: undefined, + decimals: 0, + chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + isNative: false, + primary: '0', + secondary: 0, + }), + ]), + ); + }); + it('should not return assets with zero balance with hideZeroBalanceTokens set to true', () => { + const mockState = { + metamask: { + ...mockAssetsState.metamask, + ...mockRatesState.metamask, + accountsAssets: mockAccountAssets, + preferences: { + hideZeroBalanceTokens: true, + }, + balances: mockMultichainBalances, + }, + }; + const result = getMultiChainAssets(mockState, { + address: '0xAddress', + id: mockAccountId, + }); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + title: 'Token 1', + address: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', + symbol: 'TKN1', + image: 'https://example.com/token-1.png', + decimals: 9, + chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + isNative: true, + primary: '0.051724127', + secondary: 0, + }), + ]), + ); + }); + + it('returns the same data if state does not change', () => { + const mockState = { + metamask: { + ...mockAssetsState.metamask, + ...mockRatesState.metamask, + accountsAssets: mockAccountAssets, + preferences: { + hideZeroBalanceTokens: false, + }, + balances: mockMultichainBalances, + }, + }; + const result1 = getMultiChainAssets(mockState, { + address: '0xAddress', + id: mockAccountId, + }); + const result2 = getMultiChainAssets(mockState, { + address: '0xAddress', + id: mockAccountId, + }); + expect(result1 === result2).toBe(true); + }); +}); diff --git a/ui/selectors/assets.ts b/ui/selectors/assets.ts index 66f2acf53c15..350fbef3886c 100644 --- a/ui/selectors/assets.ts +++ b/ui/selectors/assets.ts @@ -4,7 +4,12 @@ import { } from '@metamask/assets-controllers'; import { BigNumber } from 'bignumber.js'; import { CaipAssetId } from '@metamask/keyring-api'; -import { Hex, parseCaipAssetType } from '@metamask/utils'; +import { + CaipAssetType, + CaipChainId, + Hex, + parseCaipAssetType, +} from '@metamask/utils'; import { createDeepEqualSelector } from '../../shared/modules/selectors/util'; import { getTokenBalances } from '../ducks/metamask/metamask'; import { TEST_CHAINS } from '../../shared/constants/network'; @@ -105,7 +110,7 @@ export const getTokenBalancesEvm = createDeepEqualSelector( calculateTokenBalance({ isNative, chainId, - address, + address: address as Hex, decimals, nativeBalances, selectedAccountTokenBalancesAcrossChains, @@ -135,9 +140,10 @@ export const getTokenBalancesEvm = createDeepEqualSelector( ) { tokensWithBalance.push({ ...token, + address: token.address as CaipAssetType, balance, tokenFiatAmount, - chainId, + chainId: chainId as CaipChainId, string: String(balance), primary: '', secondary: 0, @@ -157,16 +163,21 @@ export const getMultiChainAssets = createDeepEqualSelector( getAccountAssets, getAssetsMetadata, getAssetsRates, + getPreferences, ( selectedAccountAddress, multichainBalances, accountAssets, assetsMetadata, assetRates, + preferences, ) => { + const { hideZeroBalanceTokens } = preferences; const assetIds = accountAssets?.[selectedAccountAddress.id] || []; const balances = multichainBalances?.[selectedAccountAddress.id]; - return assetIds.map((assetId: CaipAssetId) => { + + const allAssets: TokenWithFiatAmount[] = []; + assetIds.forEach((assetId: CaipAssetId) => { const { chainId, assetNamespace } = parseCaipAssetType(assetId); const isNative = assetNamespace === 'slip44'; const balance = balances?.[assetId] || { amount: '0', unit: '' }; @@ -182,22 +193,25 @@ export const getMultiChainAssets = createDeepEqualSelector( const metadata = assetsMetadata[assetId] || assetMetadataFallback; const decimals = metadata.units[0]?.decimals || 0; - - return { - title: metadata.name, - address: assetId, - symbol: metadata.symbol, - image: metadata.iconUrl, - decimals, - chainId, - isNative, - primary: balance.amount, - secondary: balanceInFiat.toNumber(), - string: '', - tokenFiatAmount: balanceInFiat, // for now we are keeping this is to satisfy sort, this should be fiat amount - isStakeable: false, - }; + if (!hideZeroBalanceTokens || balance.amount !== '0' || isNative) { + allAssets.push({ + title: metadata.name, + address: assetId, + symbol: metadata.symbol, + image: metadata.iconUrl, + decimals, + chainId, + isNative, + primary: balance.amount, + secondary: balanceInFiat.toNumber(), + string: '', + tokenFiatAmount: balanceInFiat.toNumber(), // for now we are keeping this is to satisfy sort, this should be fiat amount + isStakeable: false, + }); + } }); + + return allAssets; }, ); From 553541143a2ae06ee1b3862bef2a2681a09d075f Mon Sep 17 00:00:00 2001 From: Amine Harty Date: Fri, 7 Mar 2025 20:29:40 +0100 Subject: [PATCH 16/17] feat: Add MegaETH Testnet as a default test network (#30871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Add MegaETH Testnet to default testnet networks ## **Related issues** Fixes: ## **Manual testing steps** - Click on show test networks - You will see Sepolia / Linea Sepolia and MegaETH Testnet - Click on MegaETH Testnet - Send a transaction - Check the transaction result in the explorer ## **Screenshots/Recordings** ### **Before** Screenshot 2025-03-07 at 18 17 28 ### **After** Screenshot 2025-03-07 at 18 16 48 ## **Pre-merge author checklist** - [X] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [X] I've clearly explained what problem this PR is solving and how it is solved. - [ ] I've linked related issues - [X] I've included manual testing steps - [X] I've included screenshots/recordings if applicable - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. - [X] I’ve properly set the pull request status: - [X ] In case it's not yet "ready for review", I've set it to "draft". - [] In case it's "ready for review", I've changed it from "draft" to "non-draft". ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- app/images/MegaETH-logo-testnet.svg | 44 +++++++++++++++++++++++++++++ app/scripts/metamask-controller.js | 24 +++++++++++++++- shared/constants/network.ts | 21 ++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 app/images/MegaETH-logo-testnet.svg diff --git a/app/images/MegaETH-logo-testnet.svg b/app/images/MegaETH-logo-testnet.svg new file mode 100644 index 000000000000..430f2e1365bd --- /dev/null +++ b/app/images/MegaETH-logo-testnet.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 585a20e0619d..2864ba800f8b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -177,6 +177,9 @@ import { NETWORK_TYPES, NetworkStatus, MAINNET_DISPLAY_NAME, + MEGAETH_TESTNET_DISPLAY_NAME, + TEST_NETWORK_TICKER_MAP, + MEGAETH_TESTNET_IMAGE_URL, } from '../../shared/constants/network'; import { getAllowedSmartTransactionsChainIds } from '../../shared/constants/smartTransactions'; @@ -575,10 +578,29 @@ export default class MetamaskController extends EventEmitter { networks[CHAIN_IDS.MAINNET].name = MAINNET_DISPLAY_NAME; delete networks[CHAIN_IDS.GOERLI]; delete networks[CHAIN_IDS.LINEA_GOERLI]; + // Add MegaETH Testnet as a default network + networks[CHAIN_IDS.MEGAETH_TESTNET] = { + chainId: CHAIN_IDS.MEGAETH_TESTNET, + name: MEGAETH_TESTNET_DISPLAY_NAME, + nativeCurrency: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.MEGAETH_TESTNET], + blockExplorerUrls: ['https://www.megaexplorer.xyz'], + defaultRpcEndpointIndex: 0, + rpcEndpoints: [ + { + networkClientId: 'megaeth-testnet', + url: 'https://carrot.megaeth.com/rpc', + type: 'custom', + }, + ], + imageUrl: MEGAETH_TESTNET_IMAGE_URL, + }; Object.values(networks).forEach((network) => { const id = network.rpcEndpoints[0].networkClientId; - network.blockExplorerUrls = [BlockExplorerUrl[id]]; + if (id !== 'megaeth-testnet') { + // Skip for our custom network + network.blockExplorerUrls = [BlockExplorerUrl[id]]; + } network.defaultBlockExplorerUrlIndex = 0; }); diff --git a/shared/constants/network.ts b/shared/constants/network.ts index 8f017f612407..6fcea0d62e3c 100644 --- a/shared/constants/network.ts +++ b/shared/constants/network.ts @@ -87,6 +87,7 @@ export const NETWORK_TYPES = { LINEA_GOERLI: 'linea-goerli', LINEA_SEPOLIA: 'linea-sepolia', LINEA_MAINNET: 'linea-mainnet', + MEGAETH_TESTNET: 'megaeth-testnet', } as const; export type NetworkTypes = (typeof NETWORK_TYPES)[keyof typeof NETWORK_TYPES]; @@ -178,6 +179,7 @@ export const CHAIN_IDS = { INK: '0xdef1', MODE_SEPOLIA: '0x397', MODE: '0x868b', + MEGAETH_TESTNET: '0x18c6', } as const; export const CHAINLIST_CHAIN_IDS_MAP = { @@ -295,6 +297,7 @@ export const SCROLL_SEPOLIA_DISPLAY_NAME = 'Scroll Sepolia'; export const OP_BNB_DISPLAY_NAME = 'opBNB'; export const BERACHAIN_DISPLAY_NAME = 'Berachain Artio'; export const METACHAIN_ONE_DISPLAY_NAME = 'Metachain One Mainnet'; +export const MEGAETH_TESTNET_DISPLAY_NAME = 'MegaETH Testnet'; export const LISK_DISPLAY_NAME = 'Lisk'; export const LISK_SEPOLIA_DISPLAY_NAME = 'Lisk Sepolia'; export const INK_SEPOLIA_DISPLAY_NAME = 'Ink Sepolia'; @@ -328,6 +331,7 @@ export const LINEA_MAINNET_RPC_URL = getRpcUrl({ network: NETWORK_TYPES.LINEA_MAINNET, }); export const LOCALHOST_RPC_URL = 'http://localhost:8545'; +export const MEGAETH_TESTNET_RPC_URL = 'https://carrot.megaeth.com/rpc'; /** * An object containing the token symbols for various tokens that are either @@ -523,6 +527,7 @@ export const SONEIUM_IMAGE_URL = './images/soneium.svg'; export const MODE_SEPOLIA_IMAGE_URL = './images/mode-sepolia.svg'; export const MODE_IMAGE_URL = './images/mode.svg'; export const UNICHAIN_IMAGE_URL = './images/unichain.svg'; +export const MEGAETH_TESTNET_IMAGE_URL = './images/MegaETH-logo-testnet.svg'; export const INFURA_PROVIDER_TYPES = [ NETWORK_TYPES.MAINNET, @@ -535,6 +540,7 @@ export const TEST_CHAINS: Hex[] = [ CHAIN_IDS.SEPOLIA, CHAIN_IDS.LINEA_SEPOLIA, CHAIN_IDS.LOCALHOST, + CHAIN_IDS.MEGAETH_TESTNET, ]; export const MAINNET_CHAINS = [ @@ -559,6 +565,7 @@ export const TEST_NETWORK_TICKER_MAP: { }`, [NETWORK_TYPES.LINEA_GOERLI]: `Linea${CURRENCY_SYMBOLS.ETH}`, [NETWORK_TYPES.LINEA_SEPOLIA]: `Linea${CURRENCY_SYMBOLS.ETH}`, + [NETWORK_TYPES.MEGAETH_TESTNET]: CURRENCY_SYMBOLS.ETH, }; /** @@ -588,6 +595,11 @@ export const BUILT_IN_NETWORKS = { [NETWORK_TYPES.LOCALHOST]: { chainId: CHAIN_IDS.LOCALHOST, }, + [NETWORK_TYPES.MEGAETH_TESTNET]: { + chainId: CHAIN_IDS.MEGAETH_TESTNET, + ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.MEGAETH_TESTNET], + blockExplorerUrl: 'https://www.megaexplorer.xyz', + }, } as const; export const BUILT_IN_INFURA_NETWORKS = pick( @@ -613,6 +625,7 @@ export const NETWORK_TO_NAME_MAP = { [NETWORK_TYPES.LINEA_MAINNET]: LINEA_MAINNET_DISPLAY_NAME, [NETWORK_TYPES.LOCALHOST]: LOCALHOST_DISPLAY_NAME, [NETWORK_TYPES.SEPOLIA]: SEPOLIA_DISPLAY_NAME, + [NETWORK_TYPES.MEGAETH_TESTNET]: MEGAETH_TESTNET_DISPLAY_NAME, [CHAIN_IDS.ARBITRUM]: ARBITRUM_DISPLAY_NAME, [CHAIN_IDS.AVALANCHE]: AVALANCHE_DISPLAY_NAME, @@ -635,6 +648,7 @@ export const NETWORK_TO_NAME_MAP = { [CHAIN_IDS.METACHAIN_ONE]: METACHAIN_ONE_DISPLAY_NAME, [CHAIN_IDS.LISK]: LISK_DISPLAY_NAME, [CHAIN_IDS.LISK_SEPOLIA]: LISK_SEPOLIA_DISPLAY_NAME, + [CHAIN_IDS.MEGAETH_TESTNET]: MEGAETH_TESTNET_DISPLAY_NAME, } as const; export const CHAIN_ID_TO_CURRENCY_SYMBOL_MAP = { @@ -787,6 +801,7 @@ export const CHAIN_ID_TO_TYPE_MAP = { [CHAIN_IDS.LINEA_SEPOLIA]: NETWORK_TYPES.LINEA_SEPOLIA, [CHAIN_IDS.LINEA_MAINNET]: NETWORK_TYPES.LINEA_MAINNET, [CHAIN_IDS.LOCALHOST]: NETWORK_TYPES.LOCALHOST, + [CHAIN_IDS.MEGAETH_TESTNET]: NETWORK_TYPES.MEGAETH_TESTNET, } as const; export const CHAIN_ID_TO_RPC_URL_MAP = { @@ -797,6 +812,7 @@ export const CHAIN_ID_TO_RPC_URL_MAP = { [CHAIN_IDS.MAINNET]: MAINNET_RPC_URL, [CHAIN_IDS.LINEA_MAINNET]: LINEA_MAINNET_RPC_URL, [CHAIN_IDS.LOCALHOST]: LOCALHOST_RPC_URL, + [CHAIN_IDS.MEGAETH_TESTNET]: MEGAETH_TESTNET_RPC_URL, } as const; export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP: Record = { @@ -815,6 +831,7 @@ export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP: Record = { [CHAIN_IDS.CELO]: CELO_TOKEN_IMAGE_URL, [CHAIN_IDS.GNOSIS]: GNOSIS_TOKEN_IMAGE_URL, [CHAIN_IDS.ZKSYNC_ERA]: ZK_SYNC_ERA_TOKEN_IMAGE_URL, + [CHAIN_IDS.MEGAETH_TESTNET]: MEGAETH_TESTNET_IMAGE_URL, [CHAIN_IDS.NEAR]: NEAR_IMAGE_URL, [CHAIN_IDS.NEAR_TESTNET]: NEAR_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.ACALA_NETWORK]: ACALA_TOKEN_IMAGE_URL, @@ -898,6 +915,7 @@ export const CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP = { [CHAIN_IDS.LINEA_SEPOLIA]: NETWORK_TYPES.LINEA_SEPOLIA, [CHAIN_IDS.MAINNET]: NETWORK_NAMES.HOMESTEAD, [CHAIN_IDS.LINEA_MAINNET]: NETWORK_TYPES.LINEA_MAINNET, + [CHAIN_IDS.MEGAETH_TESTNET]: NETWORK_TYPES.MEGAETH_TESTNET, } as const; export const CHAIN_ID_TOKEN_IMAGE_MAP = { @@ -922,6 +940,7 @@ export const CHAIN_ID_TOKEN_IMAGE_MAP = { [CHAIN_IDS.NEAR_TESTNET]: NEAR_IMAGE_URL, [CHAIN_IDS.MOONRIVER]: MOONRIVER_TOKEN_IMAGE_URL, [CHAIN_IDS.MOONBEAM]: MOONBEAM_TOKEN_IMAGE_URL, + [CHAIN_IDS.MEGAETH_TESTNET]: MEGAETH_TESTNET_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.IOTEX_MAINNET]: IOTEX_TOKEN_IMAGE_URL, [CHAIN_IDS.B3]: B3_IMAGE_URL, [CHAIN_IDS.B3_TESTNET]: B3_IMAGE_URL, @@ -1254,6 +1273,7 @@ export const TEST_NETWORKS = [ SEPOLIA_DISPLAY_NAME, LINEA_GOERLI_DISPLAY_NAME, LINEA_SEPOLIA_DISPLAY_NAME, + MEGAETH_TESTNET_DISPLAY_NAME, ]; export const TEST_NETWORK_IDS = [ @@ -1262,4 +1282,5 @@ export const TEST_NETWORK_IDS = [ CHAIN_IDS.LINEA_GOERLI, CHAIN_IDS.LINEA_SEPOLIA, CHAIN_IDS.ARBITRUM_SEPOLIA, + CHAIN_IDS.MEGAETH_TESTNET, ]; From 907dbd106208bfd008c7c9fc6c3e26d086c16e78 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 7 Mar 2025 15:39:17 -0600 Subject: [PATCH 17/17] fix: Perf: Prevent MultichainMetaFoxLogo from multiple renders (#30286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** The `MultichainMetaFoxLogo` component rerenders because we aren't using `useCallback` for the `onClick`. This continues to happen even after logged in. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30286?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Start the extension with `ENABLE_WHY_DID_YOU_RENDER=1 yarn start` 2. Don't see rerenders on the `MultichainMetaFoxLogo` ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../app-header/multichain-meta-fox-logo.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/components/multichain/app-header/multichain-meta-fox-logo.js b/ui/components/multichain/app-header/multichain-meta-fox-logo.js index 9cca210bc2a5..cc3518486ad0 100644 --- a/ui/components/multichain/app-header/multichain-meta-fox-logo.js +++ b/ui/components/multichain/app-header/multichain-meta-fox-logo.js @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useCallback } from 'react'; + import { useHistory } from 'react-router-dom'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { useTheme } from '../../../hooks/useTheme'; @@ -16,6 +17,10 @@ export const MultichainMetaFoxLogo = () => { const history = useHistory(); const theme = useTheme(); + const onClick = useCallback(async () => { + history.push(DEFAULT_ROUTE); + }, [history]); + return ( { data-testid="app-header-logo" justifyContent={JustifyContent.center} > - history.push(DEFAULT_ROUTE)} - theme={theme} - /> + ); };