diff --git a/.github/workflows/lint-build-test.yml b/.github/workflows/lint-build-test.yml index 48dd7f9490e..c0db97f902f 100644 --- a/.github/workflows/lint-build-test.yml +++ b/.github/workflows/lint-build-test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x, 18.x, 20.x] + node-version: [18.x, 20.x] outputs: child-workspace-package-names: ${{ steps.workspace-package-names.outputs.child-workspace-package-names }} steps: @@ -105,7 +105,7 @@ jobs: needs: prepare strategy: matrix: - node-version: [16.x, 18.x, 20.x] + node-version: [18.x, 20.x] package-name: ${{ fromJson(needs.prepare.outputs.child-workspace-package-names) }} steps: - uses: actions/checkout@v3 diff --git a/.nvmrc b/.nvmrc index 6f7f377bf51..b009dfb9d9f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16 +lts/* diff --git a/constraints.pro b/constraints.pro index 985205b5a53..84cc63f1b55 100644 --- a/constraints.pro +++ b/constraints.pro @@ -408,8 +408,8 @@ gen_enforced_dependency(WorkspaceCwd, DependencyIdent, CorrectPeerDependencyRang atom_concat('^', CurrentDependencyVersion, CorrectPeerDependencyRange) ). -% All packages must specify a minimum Node version of 16. -gen_enforced_field(WorkspaceCwd, 'engines.node', '>=16.0.0'). +% All packages must specify a minimum Node version of 18. +gen_enforced_field(WorkspaceCwd, 'engines.node', '^18.18 || >=20'). % All published packages are public. gen_enforced_field(WorkspaceCwd, 'publishConfig.access', 'public') :- diff --git a/docs/contributing.md b/docs/contributing.md index 788ec1cf19a..88e9c1db715 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -2,8 +2,8 @@ ## Getting started -- Install [Node.js](https://nodejs.org) version 16. - - If you're using [NVM](https://github.com/creationix/nvm#installation) (recommended), `nvm use` will ensure that the right version is installed. +- Install the current LTS version of [Node.js](https://nodejs.org) + - If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm install` will install the latest version and running `nvm use` will automatically choose the right node version for you. - Install [Yarn v3](https://yarnpkg.com/getting-started/install). - Run `yarn install` to install dependencies and run any required post-install scripts. - Run `yarn simple-git-hooks` to add a [Git hook](https://github.com/toplenboren/simple-git-hooks#what-is-a-git-hook) to your local development environment which will ensure that all files pass linting before you push a branch. diff --git a/package.json b/package.json index 52539ab94c6..506f407facd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/core-monorepo", - "version": "157.0.0", + "version": "159.0.0", "private": true, "description": "Monorepo for packages shared between MetaMask clients", "repository": { @@ -56,8 +56,8 @@ "@metamask/eslint-config-nodejs": "^12.1.0", "@metamask/eslint-config-typescript": "^12.1.0", "@metamask/eth-block-tracker": "^9.0.2", - "@metamask/eth-json-rpc-provider": "^3.0.2", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/eth-json-rpc-provider": "^4.0.0", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/utils": "^8.3.0", "@types/jest": "^27.4.1", "@types/node": "^16.18.54", @@ -90,7 +90,7 @@ }, "packageManager": "yarn@3.3.0", "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "lavamoat": { "allowScripts": { diff --git a/packages/accounts-controller/CHANGELOG.md b/packages/accounts-controller/CHANGELOG.md index 2c8f9dcca2d..2ec126b7d7d 100644 --- a/packages/accounts-controller/CHANGELOG.md +++ b/packages/accounts-controller/CHANGELOG.md @@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [16.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump peer dependency `@metamask/keyring-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [15.0.0] + +### Added + +- Add `getNextAvailableAccountName` method and `AccountsController:getNextAvailableAccountName` controller action ([#4326](https://github.com/MetaMask/core/pull/4326)) +- Add `listMultichainAccounts` method for getting accounts on a specific chain or the default chain ([#4330](https://github.com/MetaMask/core/pull/4330)) +- Add `getSelectedMultichainAccount` method and `AccountsController:getSelectedMultichainAccount` controller action for getting the selected account on a specific chain or the default chain ([#4330](https://github.com/MetaMask/core/pull/4330)) + +### Changed + +- **BREAKING:** Bump peer dependency `@metamask/snaps-controllers` to `^8.1.1` ([#4262](https://github.com/MetaMask/core/pull/4262)) +- **BREAKING:** Bump peer dependency `@metamask/keyring-controller` to `^16.1.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** `listAccounts` now filters the list of accounts in state to EVM accounts ([#4330](https://github.com/MetaMask/core/pull/4330)) +- **BREAKING:** `getSelectedAccount` now throws if the selected account is not an EVM account ([#4330](https://github.com/MetaMask/core/pull/4330)) +- Bump `@metamask/eth-snap-keyring` to `^4.1.1` ([#4262](https://github.com/MetaMask/core/pull/4262)) +- Bump `@metamask/keyring-api` to `^6.1.1` ([#4262](https://github.com/MetaMask/core/pull/4262)) +- Bump `@metamask/snaps-sdk` to `^4.2.0` ([#4262](https://github.com/MetaMask/core/pull/4262)) +- Bump `@metamask/snaps-utils` to `^7.4.0` ([#4262](https://github.com/MetaMask/core/pull/4262)) + +### Fixed + +- Fix "Type instantiation is excessively deep and possibly infinite" TypeScript error ([#4331](https://github.com/MetaMask/core/pull/4331)) + ## [14.0.0] ### Changed @@ -171,7 +202,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#1637](https://github.com/MetaMask/core/pull/1637)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@14.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@16.0.0...HEAD +[16.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@15.0.0...@metamask/accounts-controller@16.0.0 +[15.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@14.0.0...@metamask/accounts-controller@15.0.0 [14.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@13.0.0...@metamask/accounts-controller@14.0.0 [13.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@12.0.1...@metamask/accounts-controller@13.0.0 [12.0.1]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@12.0.0...@metamask/accounts-controller@12.0.1 diff --git a/packages/accounts-controller/jest.config.js b/packages/accounts-controller/jest.config.js index ca084133399..d6e04ca78ab 100644 --- a/packages/accounts-controller/jest.config.js +++ b/packages/accounts-controller/jest.config.js @@ -14,6 +14,8 @@ module.exports = merge(baseConfig, { // The display name when running multiple projects displayName, + coveragePathIgnorePatterns: ['./src/tests'], + // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index 3c59326eb2e..040fec02a24 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/accounts-controller", - "version": "14.0.0", + "version": "16.0.0", "description": "Manages internal accounts", "keywords": [ "MetaMask", @@ -42,9 +42,9 @@ }, "dependencies": { "@ethereumjs/util": "^8.1.0", - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/eth-snap-keyring": "^4.1.1", - "@metamask/keyring-api": "^6.1.1", + "@metamask/keyring-api": "^6.4.0", "@metamask/snaps-sdk": "^4.2.0", "@metamask/snaps-utils": "^7.4.0", "@metamask/utils": "^8.3.0", @@ -55,7 +55,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^16.0.0", + "@metamask/keyring-controller": "^17.0.0", "@metamask/snaps-controllers": "^8.1.1", "@types/jest": "^27.4.1", "@types/readable-stream": "^2.3.0", @@ -66,11 +66,11 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/keyring-controller": "^16.0.0", + "@metamask/keyring-controller": "^17.0.0", "@metamask/snaps-controllers": "^8.1.1" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/accounts-controller/src/AccountsController.test.ts b/packages/accounts-controller/src/AccountsController.test.ts index 270274973ee..930a569cd4a 100644 --- a/packages/accounts-controller/src/AccountsController.test.ts +++ b/packages/accounts-controller/src/AccountsController.test.ts @@ -1,9 +1,18 @@ import { ControllerMessenger } from '@metamask/base-controller'; -import type { InternalAccount } from '@metamask/keyring-api'; -import { EthAccountType, EthMethod } from '@metamask/keyring-api'; +import type { + InternalAccount, + InternalAccountType, +} from '@metamask/keyring-api'; +import { + BtcAccountType, + BtcMethod, + EthAccountType, + EthMethod, +} from '@metamask/keyring-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import type { SnapControllerState } from '@metamask/snaps-controllers'; import { SnapStatus } from '@metamask/snaps-utils'; +import type { CaipChainId } from '@metamask/utils'; import * as uuid from 'uuid'; import type { V4Options } from 'uuid'; @@ -15,6 +24,7 @@ import type { AllowedEvents, } from './AccountsController'; import { AccountsController } from './AccountsController'; +import { createMockInternalAccount } from './tests/mocks'; import { getUUIDOptionsFromAddressOfNormalAccount, keyringTypeToName, @@ -35,7 +45,7 @@ const mockGetKeyringForAccount = jest.fn(); const mockGetKeyringByType = jest.fn(); const mockGetAccounts = jest.fn(); -const EOA_METHODS = [ +const ETH_EOA_METHODS = [ EthMethod.PersonalSign, EthMethod.Sign, EthMethod.SignTransaction, @@ -44,11 +54,17 @@ const EOA_METHODS = [ EthMethod.SignTypedDataV4, ] as const; +const ETH_ERC_4337_METHODS = [ + EthMethod.PatchUserOperation, + EthMethod.PrepareUserOperation, + EthMethod.SignUserOperation, +] as const; + const mockAccount: InternalAccount = { id: 'mock-id', address: '0x123', options: {}, - methods: [...EOA_METHODS], + methods: [...ETH_EOA_METHODS], type: EthAccountType.Eoa, metadata: { name: 'Account 1', @@ -62,7 +78,7 @@ const mockAccount2: InternalAccount = { id: 'mock-id2', address: '0x1234', options: {}, - methods: [...EOA_METHODS], + methods: [...ETH_EOA_METHODS], type: EthAccountType.Eoa, metadata: { name: 'Account 2', @@ -76,7 +92,7 @@ const mockAccount3: InternalAccount = { id: 'mock-id3', address: '0x3333', options: {}, - methods: [...EOA_METHODS], + methods: [...ETH_EOA_METHODS], type: EthAccountType.Eoa, metadata: { name: '', @@ -95,7 +111,7 @@ const mockAccount4: InternalAccount = { id: 'mock-id4', address: '0x4444', options: {}, - methods: [...EOA_METHODS], + methods: [...ETH_EOA_METHODS], type: EthAccountType.Eoa, metadata: { name: 'Custom Name', @@ -145,6 +161,9 @@ class MockNormalAccountUUID { * @param props.keyringType - The type of the keyring associated with the account. * @param props.snapId - The id of the snap. * @param props.snapEnabled - The status of the snap + * @param props.type - Account Type to create + * @param props.importTime - The import time of the account. + * @param props.lastSelected - The last selected time of the account. * @returns The `InternalAccount` object created from the normal account properties. */ function createExpectedInternalAccount({ @@ -154,6 +173,9 @@ function createExpectedInternalAccount({ keyringType, snapId, snapEnabled = true, + type = EthAccountType.Eoa, + importTime, + lastSelected, }: { id: string; name: string; @@ -161,20 +183,32 @@ function createExpectedInternalAccount({ keyringType: string; snapId?: string; snapEnabled?: boolean; + type?: InternalAccountType; + importTime?: number; + lastSelected?: number; }): InternalAccount { - const account: InternalAccount = { + const accountTypeToMethods = { + [`${EthAccountType.Eoa}`]: [...Object.values(ETH_EOA_METHODS)], + [`${EthAccountType.Erc4337}`]: [...Object.values(ETH_ERC_4337_METHODS)], + [`${BtcAccountType.P2wpkh}`]: [...Object.values(BtcMethod)], + }; + + const methods = + accountTypeToMethods[type as unknown as keyof typeof accountTypeToMethods]; + + const account = { id, address, options: {}, - methods: [...EOA_METHODS], - type: EthAccountType.Eoa, + methods, + type, metadata: { name, keyring: { type: keyringType }, - importTime: expect.any(Number), - lastSelected: expect.any(Number), + importTime: importTime || expect.any(Number), + lastSelected: lastSelected || expect.any(Number), }, - }; + } as InternalAccount; if (snapId) { account.metadata.snap = { @@ -259,7 +293,13 @@ function setupAccountsController({ AccountsControllerActions | AllowedActions, AccountsControllerEvents | AllowedEvents >; -}): AccountsController { +}): { + accountsController: AccountsController; + messenger: ControllerMessenger< + AccountsControllerActions | AllowedActions, + AccountsControllerEvents | AllowedEvents + >; +} { const accountsControllerMessenger = buildAccountsControllerMessenger(messenger); @@ -267,7 +307,7 @@ function setupAccountsController({ messenger: accountsControllerMessenger, state: { ...defaultState, ...initialState }, }); - return accountsController; + return { accountsController, messenger }; } describe('AccountsController', () => { @@ -276,7 +316,7 @@ describe('AccountsController', () => { }); describe('onSnapStateChange', () => { - it('should be used enable an account if the snap is enabled and not blocked', async () => { + it('be used enable an account if the Snap is enabled and not blocked', async () => { const messenger = buildMessenger(); const mockSnapAccount = createExpectedInternalAccount({ id: 'mock-id', @@ -298,7 +338,7 @@ describe('AccountsController', () => { // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any as SnapControllerState; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -319,7 +359,7 @@ describe('AccountsController', () => { expect(updatedAccount.metadata.snap?.enabled).toBe(true); }); - it('should be used disable an account if the snap is disabled', async () => { + it('be used disable an account if the Snap is disabled', async () => { const messenger = buildMessenger(); const mockSnapAccount = createExpectedInternalAccount({ id: 'mock-id', @@ -340,7 +380,7 @@ describe('AccountsController', () => { // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any as SnapControllerState; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -361,7 +401,7 @@ describe('AccountsController', () => { expect(updatedAccount.metadata.snap?.enabled).toBe(false); }); - it('should be used disable an account if the snap is blocked', async () => { + it('be used disable an account if the Snap is blocked', async () => { const messenger = buildMessenger(); const mockSnapAccount = createExpectedInternalAccount({ id: 'mock-id', @@ -382,7 +422,7 @@ describe('AccountsController', () => { // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any as SnapControllerState; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -408,9 +448,9 @@ describe('AccountsController', () => { afterEach(() => { jest.clearAllMocks(); }); - it('should not update state when only keyring is unlocked without any keyrings', async () => { + it('not update state when only keyring is unlocked without any keyrings', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -431,7 +471,7 @@ describe('AccountsController', () => { expect(accounts).toStrictEqual([]); }); - it('should only update if the keyring is unlocked and when there are keyrings', async () => { + it('only update if the keyring is unlocked and when there are keyrings', async () => { const messenger = buildMessenger(); const mockNewKeyringState = { @@ -443,7 +483,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -465,7 +505,7 @@ describe('AccountsController', () => { }); describe('adding accounts', () => { - it('should add new accounts', async () => { + it('add new accounts', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') // call to check if its a new account @@ -481,7 +521,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -508,7 +548,7 @@ describe('AccountsController', () => { ]); }); - it('should add snap accounts', async () => { + it('add Snap accounts', async () => { mockUUID.mockReturnValueOnce('mock-id'); // call to check if its a new account const messenger = buildMessenger(); @@ -539,7 +579,7 @@ describe('AccountsController', () => { ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -575,7 +615,7 @@ describe('AccountsController', () => { ]); }); - it('should handle the event when a snap deleted the account before the it was added', async () => { + it('handle the event when a Snap deleted the account before the it was added', async () => { mockUUID.mockReturnValueOnce('mock-id'); // call to check if its a new account const messenger = buildMessenger(); messenger.registerActionHandler( @@ -605,7 +645,7 @@ describe('AccountsController', () => { ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -632,7 +672,7 @@ describe('AccountsController', () => { ]); }); - it('should increment the default account number when adding an account', async () => { + it('increment the default account number when adding an account', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') // call to check if its a new account @@ -653,7 +693,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -688,7 +728,7 @@ describe('AccountsController', () => { ]); }); - it('should use the next number after the total number of accounts of a keyring when adding an account, if the index is lower', async () => { + it('use the next number after the total number of accounts of a keyring when adding an account, if the index is lower', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') // call to check if its a new account @@ -701,6 +741,8 @@ describe('AccountsController', () => { name: 'Custom Name', address: mockAccount2.address, keyringType: KeyringTypes.hd, + importTime: 1955565967656, + lastSelected: 1955565967656, }); const mockNewKeyringState = { @@ -716,7 +758,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -749,7 +791,7 @@ describe('AccountsController', () => { ]); }); - it('should handle when the account to set as selectedAccount is undefined', async () => { + it('handle when the account to set as selectedAccount is undefined', async () => { mockUUID.mockReturnValueOnce('mock-id'); // call to check if its a new account const messenger = buildMessenger(); @@ -777,7 +819,7 @@ describe('AccountsController', () => { ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -800,7 +842,7 @@ describe('AccountsController', () => { }); describe('deleting account', () => { - it('should delete accounts if its gone from the keyring state', async () => { + it('delete accounts if its gone from the keyring state', async () => { const messenger = buildMessenger(); mockUUID.mockReturnValueOnce('mock-id2'); @@ -813,7 +855,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -840,7 +882,7 @@ describe('AccountsController', () => { ); }); - it('should delete accounts and set the most recent lastSelected account', async () => { + it('delete accounts and set the most recent lastSelected account', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') @@ -857,7 +899,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -896,7 +938,7 @@ describe('AccountsController', () => { ); }); - it('should delete accounts and set the most recent lastSelected account when there are accounts that have never been selected', async () => { + it('delete accounts and set the most recent lastSelected account when there are accounts that have never been selected', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') @@ -920,7 +962,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -959,7 +1001,7 @@ describe('AccountsController', () => { ); }); - it('should delete the account and select the account with the most recent lastSelected', async () => { + it('delete the account and select the account with the most recent lastSelected', async () => { const messenger = buildMessenger(); mockUUID.mockReturnValueOnce('mock-id').mockReturnValueOnce('mock-id2'); @@ -991,7 +1033,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1023,16 +1065,16 @@ describe('AccountsController', () => { const accounts = accountsController.listAccounts(); expect(accounts).toStrictEqual([ - setLastSelectedAsAny(mockAccountWithoutLastSelected), + mockAccountWithoutLastSelected, mockAccount2WithoutLastSelected, ]); expect(accountsController.getSelectedAccount()).toStrictEqual( - setLastSelectedAsAny(mockAccountWithoutLastSelected), + mockAccountWithoutLastSelected, ); }); }); - it('should handle keyring reinitialization', async () => { + it('handle keyring reinitialization', async () => { const messenger = buildMessenger(); const mockInitialAccount = createExpectedInternalAccount({ id: 'mock-id', @@ -1059,7 +1101,7 @@ describe('AccountsController', () => { }, ], }; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1084,6 +1126,90 @@ describe('AccountsController', () => { expect(selectedAccount).toStrictEqual(expectedAccount); expect(accounts).toStrictEqual([expectedAccount]); }); + + it.each([ + { + lastSelectedForAccount1: 1111, + lastSelectedForAccount2: 9999, + expectedSelectedId: 'mock-id2', + }, + { + lastSelectedForAccount1: undefined, + lastSelectedForAccount2: 9999, + expectedSelectedId: 'mock-id2', + }, + { + lastSelectedForAccount1: 1111, + lastSelectedForAccount2: undefined, + expectedSelectedId: 'mock-id', + }, + { + lastSelectedForAccount1: 1111, + lastSelectedForAccount2: 0, + expectedSelectedId: 'mock-id', + }, + ])( + 'handle keyring reinitialization with multiple accounts. Account 1 lastSelected $lastSelectedForAccount1, Account 2 lastSelected $lastSelectedForAccount2. Expected selected account: $expectedSelectedId', + async ({ + lastSelectedForAccount1, + lastSelectedForAccount2, + expectedSelectedId, + }) => { + const messenger = buildMessenger(); + const mockExistingAccount1 = createExpectedInternalAccount({ + id: 'mock-id', + name: 'Account 1', + address: '0x123', + keyringType: KeyringTypes.hd, + }); + mockExistingAccount1.metadata.lastSelected = lastSelectedForAccount1; + const mockExistingAccount2 = createExpectedInternalAccount({ + id: 'mock-id2', + name: 'Account 2', + address: '0x456', + keyringType: KeyringTypes.hd, + }); + mockExistingAccount2.metadata.lastSelected = lastSelectedForAccount2; + + mockUUID + .mockReturnValueOnce('mock-id') // call to check if its a new account + .mockReturnValueOnce('mock-id2'); // call to check if its a new account + + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockExistingAccount1.id]: mockExistingAccount1, + [mockExistingAccount2.id]: mockExistingAccount2, + }, + selectedAccount: 'unknown', + }, + }, + messenger, + }); + const mockNewKeyringState = { + isUnlocked: true, + keyrings: [ + { + type: KeyringTypes.hd, + accounts: [ + mockExistingAccount1.address, + mockExistingAccount2.address, + ], + }, + ], + }; + messenger.publish( + 'KeyringController:stateChange', + mockNewKeyringState, + [], + ); + + const selectedAccount = accountsController.getSelectedAccount(); + + expect(selectedAccount.id).toStrictEqual(expectedSelectedId); + }, + ); }); describe('updateAccounts', () => { @@ -1134,7 +1260,7 @@ describe('AccountsController', () => { jest.clearAllMocks(); }); - it('should update accounts with normal accounts', async () => { + it('update accounts with normal accounts', async () => { mockUUID.mockReturnValueOnce('mock-id').mockReturnValueOnce('mock-id2'); const messenger = buildMessenger(); messenger.registerActionHandler( @@ -1157,7 +1283,7 @@ describe('AccountsController', () => { ]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1186,7 +1312,7 @@ describe('AccountsController', () => { expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); }); - it('should update accounts with snap accounts when snap keyring is defined and has accounts', async () => { + it('update accounts with Snap accounts when snap keyring is defined and has accounts', async () => { const messenger = buildMessenger(); messenger.registerActionHandler( 'KeyringController:getAccounts', @@ -1203,7 +1329,7 @@ describe('AccountsController', () => { ]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1242,7 +1368,7 @@ describe('AccountsController', () => { ).toStrictEqual(expectedAccounts); }); - it('should return an empty array if the snap keyring is not defined', async () => { + it('return an empty array if the Snap keyring is not defined', async () => { const messenger = buildMessenger(); messenger.registerActionHandler( 'KeyringController:getAccounts', @@ -1254,7 +1380,7 @@ describe('AccountsController', () => { mockGetKeyringByType.mockReturnValueOnce([undefined]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1271,7 +1397,7 @@ describe('AccountsController', () => { expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); }); - it('should set the account with the correct index', async () => { + it('set the account with the correct index', async () => { mockUUID.mockReturnValueOnce('mock-id').mockReturnValueOnce('mock-id2'); const messenger = buildMessenger(); messenger.registerActionHandler( @@ -1294,7 +1420,7 @@ describe('AccountsController', () => { ]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1320,7 +1446,7 @@ describe('AccountsController', () => { expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); }); - it('should filter snap accounts from normalAccounts', async () => { + it('filter Snap accounts from normalAccounts', async () => { mockUUID.mockReturnValueOnce('mock-id'); const messenger = buildMessenger(); messenger.registerActionHandler( @@ -1345,7 +1471,7 @@ describe('AccountsController', () => { .mockResolvedValueOnce({ type: KeyringTypes.snap }), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1375,7 +1501,7 @@ describe('AccountsController', () => { expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); }); - it('should filter snap accounts from normalAccounts even if the snap account is listed before normal accounts', async () => { + it('filter Snap accounts from normalAccounts even if the snap account is listed before normal accounts', async () => { mockUUID.mockReturnValue('mock-id'); const messenger = buildMessenger(); messenger.registerActionHandler( @@ -1400,7 +1526,7 @@ describe('AccountsController', () => { .mockResolvedValueOnce({ type: KeyringTypes.hd }), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1462,7 +1588,7 @@ describe('AccountsController', () => { ]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1488,7 +1614,7 @@ describe('AccountsController', () => { ).toStrictEqual(expectedAccounts); }); - it('should throw an error if the keyring type is unknown', async () => { + it('throw an error if the keyring type is unknown', async () => { mockUUID.mockReturnValue('mock-id'); const messenger = buildMessenger(); @@ -1511,7 +1637,7 @@ describe('AccountsController', () => { ]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1528,8 +1654,8 @@ describe('AccountsController', () => { }); describe('loadBackup', () => { - it('should load a backup', async () => { - const accountsController = setupAccountsController({ + it('load a backup', async () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: {}, @@ -1557,8 +1683,8 @@ describe('AccountsController', () => { }); }); - it('should not load backup if the data is undefined', () => { - const accountsController = setupAccountsController({ + it('not load backup if the data is undefined', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1582,8 +1708,8 @@ describe('AccountsController', () => { }); describe('getAccount', () => { - it('should return an account by ID', () => { - const accountsController = setupAccountsController({ + it('return an account by ID', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1598,8 +1724,8 @@ describe('AccountsController', () => { setLastSelectedAsAny(mockAccount as InternalAccount), ); }); - it('should return undefined for an unknown account ID', () => { - const accountsController = setupAccountsController({ + it('return undefined for an unknown account ID', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1614,32 +1740,260 @@ describe('AccountsController', () => { }); }); + describe('getSelectedAccount', () => { + const mockNonEvmAccount = createExpectedInternalAccount({ + id: 'mock-non-evm', + name: 'non-evm', + address: 'bc1qzqc2aqlw8nwa0a05ehjkk7dgt8308ac7kzw9a6', + keyringType: KeyringTypes.snap, + type: BtcAccountType.P2wpkh, + }); + + const mockOlderEvmAccount = createExpectedInternalAccount({ + id: 'mock-id-1', + name: 'mock account 1', + address: 'mock-address-1', + keyringType: KeyringTypes.hd, + lastSelected: 11111, + }); + const mockNewerEvmAccount = createExpectedInternalAccount({ + id: 'mock-id-2', + name: 'mock account 2', + address: 'mock-address-2', + keyringType: KeyringTypes.hd, + lastSelected: 22222, + }); + + it.each([ + { + lastSelectedAccount: mockNewerEvmAccount, + expected: mockNewerEvmAccount, + }, + { + lastSelectedAccount: mockOlderEvmAccount, + expected: mockOlderEvmAccount, + }, + { + lastSelectedAccount: mockNonEvmAccount, + expected: mockNewerEvmAccount, + }, + ])( + 'last selected account type is $lastSelectedAccount.type should return the selectedAccount with id $expected.id', + ({ lastSelectedAccount, expected }) => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockOlderEvmAccount.id]: mockOlderEvmAccount, + [mockNewerEvmAccount.id]: mockNewerEvmAccount, + [mockNonEvmAccount.id]: mockNonEvmAccount, + }, + selectedAccount: lastSelectedAccount.id, + }, + }, + }); + + expect(accountsController.getSelectedAccount()).toStrictEqual(expected); + }, + ); + + it("throw error if there aren't any EVM accounts", () => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockNonEvmAccount.id]: mockNonEvmAccount, + }, + selectedAccount: mockNonEvmAccount.id, + }, + }, + }); + + expect(() => accountsController.getSelectedAccount()).toThrow( + 'No EVM accounts', + ); + }); + }); + + describe('getSelectedMultichainAccount', () => { + const mockNonEvmAccount = createExpectedInternalAccount({ + id: 'mock-non-evm', + name: 'non-evm', + address: 'bc1qzqc2aqlw8nwa0a05ehjkk7dgt8308ac7kzw9a6', + keyringType: KeyringTypes.snap, + type: BtcAccountType.P2wpkh, + }); + + const mockOlderEvmAccount = createExpectedInternalAccount({ + id: 'mock-id-1', + name: 'mock account 1', + address: 'mock-address-1', + keyringType: KeyringTypes.hd, + lastSelected: 11111, + }); + const mockNewerEvmAccount = createExpectedInternalAccount({ + id: 'mock-id-2', + name: 'mock account 2', + address: 'mock-address-2', + keyringType: KeyringTypes.hd, + lastSelected: 22222, + }); + + it.each([ + { + chainId: undefined, + selectedAccount: mockNewerEvmAccount, + expected: mockNewerEvmAccount, + }, + { + chainId: undefined, + selectedAccount: mockNonEvmAccount, + expected: mockNonEvmAccount, + }, + { + chainId: 'eip155:1', + selectedAccount: mockNonEvmAccount, + expected: mockNewerEvmAccount, + }, + { + chainId: 'bip122:000000000019d6689c085ae165831e93', + selectedAccount: mockNonEvmAccount, + expected: mockNonEvmAccount, + }, + ])( + "chainId $chainId with selectedAccount '$selectedAccount.id' should return $expected.id", + ({ chainId, selectedAccount, expected }) => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockOlderEvmAccount.id]: mockOlderEvmAccount, + [mockNewerEvmAccount.id]: mockNewerEvmAccount, + [mockNonEvmAccount.id]: mockNonEvmAccount, + }, + selectedAccount: selectedAccount.id, + }, + }, + }); + + expect( + accountsController.getSelectedMultichainAccount( + chainId as CaipChainId, + ), + ).toStrictEqual(expected); + }, + ); + + // Testing error cases + it.each([['eip155.'], ['bip122'], ['bip122:...']])( + 'invalid chainId %s will throw', + (chainId) => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockOlderEvmAccount.id]: mockOlderEvmAccount, + [mockNewerEvmAccount.id]: mockNewerEvmAccount, + [mockNonEvmAccount.id]: mockNonEvmAccount, + }, + selectedAccount: mockNonEvmAccount.id, + }, + }, + }); + + expect(() => + accountsController.getSelectedMultichainAccount( + chainId as CaipChainId, + ), + ).toThrow(`Invalid CAIP-2 chain ID: ${chainId}`); + }, + ); + }); + describe('listAccounts', () => { - it('should return a list of accounts', () => { - const accountsController = setupAccountsController({ + it('returns a list of evm accounts', () => { + const mockNonEvmAccount = createMockInternalAccount({ + id: 'mock-id-non-evm', + address: 'mock-non-evm-address', + type: BtcAccountType.P2wpkh, + keyringType: KeyringTypes.snap, + }); + + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount, [mockAccount2.id]: mockAccount2, + [mockNonEvmAccount.id]: mockNonEvmAccount, }, selectedAccount: mockAccount.id, }, }, }); - const result = accountsController.listAccounts(); - - expect(result).toStrictEqual([ - setLastSelectedAsAny(mockAccount as InternalAccount), - setLastSelectedAsAny(mockAccount2 as InternalAccount), + expect(accountsController.listAccounts()).toStrictEqual([ + mockAccount, + mockAccount2, ]); }); }); + describe('listMultichainAccounts', () => { + const mockNonEvmAccount = createMockInternalAccount({ + id: 'mock-id-non-evm', + address: 'mock-non-evm-address', + type: BtcAccountType.P2wpkh, + keyringType: KeyringTypes.snap, + }); + + it.each([ + [undefined, [mockAccount, mockAccount2, mockNonEvmAccount]], + ['eip155:1', [mockAccount, mockAccount2]], + ['bip122:000000000019d6689c085ae165831e93', [mockNonEvmAccount]], + ])(`%s should return %s`, (chainId, expected) => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockAccount.id]: mockAccount, + [mockAccount2.id]: mockAccount2, + [mockNonEvmAccount.id]: mockNonEvmAccount, + }, + selectedAccount: mockAccount.id, + }, + }, + }); + expect( + accountsController.listMultichainAccounts(chainId as CaipChainId), + ).toStrictEqual(expected); + }); + + it('throw if invalid CAIP-2 was passed', () => { + const { accountsController } = setupAccountsController({ + initialState: { + internalAccounts: { + accounts: { + [mockAccount.id]: mockAccount, + [mockAccount2.id]: mockAccount2, + }, + selectedAccount: mockAccount.id, + }, + }, + }); + + const invalidCaip2 = 'ethereum'; + + expect(() => + // @ts-expect-error testing invalid caip2 + accountsController.listMultichainAccounts(invalidCaip2), + ).toThrow(`Invalid CAIP-2 chain ID: ${invalidCaip2}`); + }); + }); + describe('getAccountExpect', () => { - it('should return an account by ID', () => { - const accountsController = setupAccountsController({ + it('return an account by ID', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1654,9 +2008,9 @@ describe('AccountsController', () => { ); }); - it('should throw an error for an unknown account ID', () => { + it('throw an error for an unknown account ID', () => { const accountId = 'unknown id'; - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1670,8 +2024,8 @@ describe('AccountsController', () => { ); }); - it('should handle the edge case of undefined accountId during onboarding', async () => { - const accountsController = setupAccountsController({ + it('handle the edge case of undefined accountId during onboarding', async () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1698,49 +2052,72 @@ describe('AccountsController', () => { }); }); - describe('getSelectedAccount', () => { - it('should return the selected account', () => { - const accountsController = setupAccountsController({ + describe('setSelectedAccount', () => { + it('set the selected account', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { - accounts: { [mockAccount.id]: mockAccount }, + accounts: { + [mockAccount.id]: mockAccount, + [mockAccount2.id]: mockAccount2, + }, selectedAccount: mockAccount.id, }, }, }); - const result = accountsController.getAccountExpect(mockAccount.id); - expect(result).toStrictEqual( - setLastSelectedAsAny(mockAccount as InternalAccount), - ); + accountsController.setSelectedAccount(mockAccount2.id); + + expect( + accountsController.state.internalAccounts.selectedAccount, + ).toStrictEqual(mockAccount2.id); }); - }); - describe('setSelectedAccount', () => { - it('should set the selected account', () => { - const accountsController = setupAccountsController({ + it('not emit setSelectedEvmAccountChange if the account is non-EVM', () => { + const mockNonEvmAccount = createExpectedInternalAccount({ + id: 'mock-non-evm', + name: 'non-evm', + address: 'bc1qzqc2aqlw8nwa0a05ehjkk7dgt8308ac7kzw9a6', + keyringType: KeyringTypes.snap, + type: BtcAccountType.P2wpkh, + }); + const { accountsController, messenger } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount, - [mockAccount2.id]: mockAccount2, + [mockNonEvmAccount.id]: mockNonEvmAccount, }, selectedAccount: mockAccount.id, }, }, }); - accountsController.setSelectedAccount(mockAccount2.id); + const messengerSpy = jest.spyOn(messenger, 'publish'); + + accountsController.setSelectedAccount(mockNonEvmAccount.id); expect( accountsController.state.internalAccounts.selectedAccount, - ).toStrictEqual(mockAccount2.id); + ).toStrictEqual(mockNonEvmAccount.id); + + expect(messengerSpy.mock.calls).toHaveLength(2); // state change and then selectedAccountChange + + expect(messengerSpy).not.toHaveBeenCalledWith( + 'AccountsController:selectedEvmAccountChange', + mockNonEvmAccount, + ); + + expect(messengerSpy).toHaveBeenCalledWith( + 'AccountsController:selectedAccountChange', + mockNonEvmAccount, + ); }); }); describe('setAccountName', () => { - it('should set the name of an existing account', () => { - const accountsController = setupAccountsController({ + it('set the name of an existing account', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1755,8 +2132,8 @@ describe('AccountsController', () => { ).toBe('new name'); }); - it('should throw an error if the account name already exists', () => { - const accountsController = setupAccountsController({ + it('throw an error if the account name already exists', () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1812,7 +2189,7 @@ describe('AccountsController', () => { }; }; - it('should return the next account number', async () => { + it('return the next account number', async () => { const messenger = buildMessenger(); mockUUID .mockReturnValueOnce('mock-id') // call to check if its a new account @@ -1821,7 +2198,7 @@ describe('AccountsController', () => { .mockReturnValueOnce('mock-id2') // call to add account .mockReturnValueOnce('mock-id3'); // call to add account - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1850,7 +2227,7 @@ describe('AccountsController', () => { ]); }); - it('should return the next account number even with an index gap', async () => { + it('return the next account number even with an index gap', async () => { const messenger = buildMessenger(); const mockAccountUUIDs = new MockNormalAccountUUID([ mockAccount, @@ -1860,7 +2237,7 @@ describe('AccountsController', () => { ]); mockUUID.mockImplementation(mockAccountUUIDs.mock.bind(mockAccountUUIDs)); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { @@ -1909,8 +2286,8 @@ describe('AccountsController', () => { }); describe('getAccountByAddress', () => { - it('should return an account by address', async () => { - const accountsController = setupAccountsController({ + it('return an account by address', async () => { + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1927,7 +2304,7 @@ describe('AccountsController', () => { }); it("should return undefined if there isn't an account with the address", () => { - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1951,13 +2328,12 @@ describe('AccountsController', () => { jest.spyOn(AccountsController.prototype, 'getAccountByAddress'); jest.spyOn(AccountsController.prototype, 'getSelectedAccount'); jest.spyOn(AccountsController.prototype, 'getAccount'); - jest.spyOn(AccountsController.prototype, 'getNextAvailableAccountName'); }); describe('setSelectedAccount', () => { - it('should set the selected account', async () => { + it('set the selected account', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1975,9 +2351,9 @@ describe('AccountsController', () => { }); describe('listAccounts', () => { - it('should retrieve a list of accounts', async () => { + it('retrieve a list of accounts', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -1993,9 +2369,9 @@ describe('AccountsController', () => { }); describe('setAccountName', () => { - it('should set the account name', async () => { + it('set the account name', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -2018,7 +2394,7 @@ describe('AccountsController', () => { }); describe('updateAccounts', () => { - it('should update accounts', async () => { + it('update accounts', async () => { const messenger = buildMessenger(); messenger.registerActionHandler( 'KeyringController:getAccounts', @@ -2033,7 +2409,7 @@ describe('AccountsController', () => { mockGetKeyringForAccount.mockResolvedValueOnce([]), ); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -2049,10 +2425,10 @@ describe('AccountsController', () => { }); describe('getAccountByAddress', () => { - it('should get account by address', async () => { + it('get account by address', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -2074,10 +2450,10 @@ describe('AccountsController', () => { }); describe('getSelectedAccount', () => { - it('should get account by address', async () => { + it('get account by address', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, @@ -2094,10 +2470,10 @@ describe('AccountsController', () => { }); describe('getAccount', () => { - it('should get account by id', async () => { + it('get account by id', async () => { const messenger = buildMessenger(); - const accountsController = setupAccountsController({ + const { accountsController } = setupAccountsController({ initialState: { internalAccounts: { accounts: { [mockAccount.id]: mockAccount }, diff --git a/packages/accounts-controller/src/AccountsController.ts b/packages/accounts-controller/src/AccountsController.ts index 8fec7bc3339..820ab6447f7 100644 --- a/packages/accounts-controller/src/AccountsController.ts +++ b/packages/accounts-controller/src/AccountsController.ts @@ -6,7 +6,11 @@ import type { import { BaseController } from '@metamask/base-controller'; import { SnapKeyring } from '@metamask/eth-snap-keyring'; import type { InternalAccount } from '@metamask/keyring-api'; -import { EthAccountType, EthMethod } from '@metamask/keyring-api'; +import { + EthAccountType, + EthMethod, + isEvmAccountType, +} from '@metamask/keyring-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import type { KeyringControllerState, @@ -21,7 +25,13 @@ import type { } from '@metamask/snaps-controllers'; import type { SnapId } from '@metamask/snaps-sdk'; import type { Snap } from '@metamask/snaps-utils'; -import type { Keyring, Json } from '@metamask/utils'; +import type { CaipChainId } from '@metamask/utils'; +import { + type Keyring, + type Json, + isCaipChainId, + parseCaipChainId, +} from '@metamask/utils'; import type { Draft } from 'immer'; import { @@ -70,6 +80,11 @@ export type AccountsControllerGetSelectedAccountAction = { handler: AccountsController['getSelectedAccount']; }; +export type AccountsControllerGetSelectedMultichainAccountAction = { + type: `${typeof controllerName}:getSelectedMultichainAccount`; + handler: AccountsController['getSelectedMultichainAccount']; +}; + export type AccountsControllerGetAccountByAddressAction = { type: `${typeof controllerName}:getAccountByAddress`; handler: AccountsController['getAccountByAddress']; @@ -99,7 +114,8 @@ export type AccountsControllerActions = | AccountsControllerGetAccountByAddressAction | AccountsControllerGetSelectedAccountAction | AccountsControllerGetNextAvailableAccountNameAction - | AccountsControllerGetAccountAction; + | AccountsControllerGetAccountAction + | AccountsControllerGetSelectedMultichainAccountAction; export type AccountsControllerChangeEvent = ControllerStateChangeEvent< typeof controllerName, @@ -111,11 +127,17 @@ export type AccountsControllerSelectedAccountChangeEvent = { payload: [InternalAccount]; }; +export type AccountsControllerSelectedEvmAccountChangeEvent = { + type: `${typeof controllerName}:selectedEvmAccountChange`; + payload: [InternalAccount]; +}; + export type AllowedEvents = SnapStateChange | KeyringControllerStateChangeEvent; export type AccountsControllerEvents = | AccountsControllerChangeEvent - | AccountsControllerSelectedAccountChangeEvent; + | AccountsControllerSelectedAccountChangeEvent + | AccountsControllerSelectedEvmAccountChangeEvent; export type AccountsControllerMessenger = RestrictedControllerMessenger< typeof controllerName, @@ -205,12 +227,34 @@ export class AccountsController extends BaseController< } /** - * Returns an array of all internal accounts. + * Returns an array of all evm internal accounts. * * @returns An array of InternalAccount objects. */ listAccounts(): InternalAccount[] { - return Object.values(this.state.internalAccounts.accounts); + const accounts = Object.values(this.state.internalAccounts.accounts); + return accounts.filter((account) => isEvmAccountType(account.type)); + } + + /** + * Returns an array of all internal accounts. + * + * @param chainId - The chain ID. + * @returns An array of InternalAccount objects. + */ + listMultichainAccounts(chainId?: CaipChainId): InternalAccount[] { + const accounts = Object.values(this.state.internalAccounts.accounts); + if (!chainId) { + return accounts; + } + + if (!isCaipChainId(chainId)) { + throw new Error(`Invalid CAIP-2 chain ID: ${String(chainId)}`); + } + + return accounts.filter((account) => + this.#isAccountCompatibleWithChain(account, chainId), + ); } /** @@ -248,12 +292,54 @@ export class AccountsController extends BaseController< } /** - * Returns the selected internal account. + * Returns the last selected evm account. * * @returns The selected internal account. */ getSelectedAccount(): InternalAccount { - return this.getAccountExpect(this.state.internalAccounts.selectedAccount); + const selectedAccount = this.getAccountExpect( + this.state.internalAccounts.selectedAccount, + ); + if (isEvmAccountType(selectedAccount.type)) { + return selectedAccount; + } + + const accounts = this.listAccounts(); + + if (!accounts.length) { + // ! Should never reach this. + throw new Error('No EVM accounts'); + } + + // This will never be undefined because we have already checked if accounts.length is > 0 + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this.#getLastSelectedAccount(accounts)!; + } + + /** + * __WARNING The return value may be undefined if there isn't an account for that chain id.__ + * + * Retrieves the last selected account by chain ID. + * + * @param chainId - The chain ID to filter the accounts. + * @returns The last selected account compatible with the specified chain ID or undefined. + */ + getSelectedMultichainAccount( + chainId?: CaipChainId, + ): InternalAccount | undefined { + if (!chainId) { + return this.getAccountExpect(this.state.internalAccounts.selectedAccount); + } + + if (!isCaipChainId(chainId)) { + throw new Error(`Invalid CAIP-2 chain ID: ${chainId as string}`); + } + + const accounts = Object.values(this.state.internalAccounts.accounts).filter( + (account) => this.#isAccountCompatibleWithChain(account, chainId), + ); + + return this.#getLastSelectedAccount(accounts); } /** @@ -282,6 +368,13 @@ export class AccountsController extends BaseController< currentState.internalAccounts.selectedAccount = account.id; }); + if (isEvmAccountType(account.type)) { + this.messagingSystem.publish( + 'AccountsController:selectedEvmAccountChange', + account, + ); + } + this.messagingSystem.publish( 'AccountsController:selectedAccountChange', account, @@ -707,6 +800,30 @@ export class AccountsController extends BaseController< }); } + /** + * Returns the last selected account from the given array of accounts. + * + * @param accounts - An array of InternalAccount objects. + * @returns The InternalAccount object that was last selected, or undefined if the array is empty. + */ + #getLastSelectedAccount( + accounts: InternalAccount[], + ): InternalAccount | undefined { + return accounts.reduce((prevAccount, currentAccount) => { + if ( + // When the account is added, lastSelected will be set + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + currentAccount.metadata.lastSelected! > + // When the account is added, lastSelected will be set + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + prevAccount.metadata.lastSelected! + ) { + return currentAccount; + } + return prevAccount; + }, accounts[0]); + } + /** * Returns the next account number for a given keyring type. * @param keyringType - The type of keyring. @@ -745,6 +862,22 @@ export class AccountsController extends BaseController< return `${keyringName} ${index}`; } + /** + * Checks if an account is compatible with a given chain namespace. + * @private + * @param account - The account to check compatibility for. + * @param chainId - The CAIP2 to check compatibility with. + * @returns Returns true if the account is compatible with the chain namespace, otherwise false. + */ + #isAccountCompatibleWithChain( + account: InternalAccount, + chainId: CaipChainId, + ): boolean { + // TODO: Change this logic to not use account's type + // Because we currently only use type, we can only use namespace for now. + return account.type.startsWith(parseCaipChainId(chainId).namespace); + } + /** * Handles the addition of a new account to the controller. * If the account is not a Snap Keyring account, generates an internal account for it and adds it to the controller. @@ -853,6 +986,11 @@ export class AccountsController extends BaseController< this.getSelectedAccount.bind(this), ); + this.messagingSystem.registerActionHandler( + `${controllerName}:getSelectedMultichainAccount`, + this.getSelectedMultichainAccount.bind(this), + ); + this.messagingSystem.registerActionHandler( `${controllerName}:getAccountByAddress`, this.getAccountByAddress.bind(this), diff --git a/packages/accounts-controller/src/index.ts b/packages/accounts-controller/src/index.ts index 274efa5d5b1..29505118b61 100644 --- a/packages/accounts-controller/src/index.ts +++ b/packages/accounts-controller/src/index.ts @@ -11,8 +11,10 @@ export type { AccountsControllerActions, AccountsControllerChangeEvent, AccountsControllerSelectedAccountChangeEvent, + AccountsControllerSelectedEvmAccountChangeEvent, AccountsControllerEvents, AccountsControllerMessenger, } from './AccountsController'; export { AccountsController } from './AccountsController'; export { keyringTypeToName, getUUIDFromAddressOfNormalAccount } from './utils'; +export { createMockInternalAccount } from './tests/mocks'; diff --git a/packages/accounts-controller/src/tests/mocks.test.ts b/packages/accounts-controller/src/tests/mocks.test.ts new file mode 100644 index 00000000000..972b3356a5b --- /dev/null +++ b/packages/accounts-controller/src/tests/mocks.test.ts @@ -0,0 +1,77 @@ +import { BtcAccountType, EthAccountType } from '@metamask/keyring-api'; + +import { createMockInternalAccount } from './mocks'; + +describe('createMockInternalAccount', () => { + it('create a mock internal account', () => { + const account = createMockInternalAccount(); + expect(account).toStrictEqual({ + id: expect.any(String), + address: expect.any(String), + type: expect.any(String), + options: expect.any(Object), + methods: expect.any(Array), + metadata: { + name: expect.any(String), + keyring: { type: expect.any(String) }, + importTime: expect.any(Number), + lastSelected: expect.any(Number), + snap: undefined, + }, + }); + }); + + it('create a mock internal account with custom values', () => { + const customSnap = { + id: '1', + enabled: true, + name: 'Snap 1', + }; + const account = createMockInternalAccount({ + id: '1', + address: '0x123', + type: EthAccountType.Erc4337, + name: 'Custom Account', + snap: customSnap, + }); + expect(account).toStrictEqual({ + id: '1', + address: '0x123', + type: EthAccountType.Erc4337, + options: expect.any(Object), + methods: expect.any(Array), + metadata: { + name: 'Custom Account', + keyring: { type: expect.any(String) }, + importTime: expect.any(Number), + lastSelected: expect.any(Number), + snap: customSnap, + }, + }); + }); + + it('create a non-EVM account', () => { + const account = createMockInternalAccount({ type: BtcAccountType.P2wpkh }); + expect(account).toStrictEqual({ + id: expect.any(String), + address: expect.any(String), + type: BtcAccountType.P2wpkh, + options: expect.any(Object), + methods: expect.any(Array), + metadata: { + name: expect.any(String), + keyring: { type: expect.any(String) }, + importTime: expect.any(Number), + lastSelected: expect.any(Number), + snap: undefined, + }, + }); + }); + + it('will throw if an unknown account type was passed', () => { + // @ts-expect-error testing unknown account type + expect(() => createMockInternalAccount({ type: 'unknown' })).toThrow( + 'Unknown account type: unknown', + ); + }); +}); diff --git a/packages/accounts-controller/src/tests/mocks.ts b/packages/accounts-controller/src/tests/mocks.ts new file mode 100644 index 00000000000..daebd1fbc34 --- /dev/null +++ b/packages/accounts-controller/src/tests/mocks.ts @@ -0,0 +1,78 @@ +import type { + InternalAccount, + InternalAccountType, +} from '@metamask/keyring-api'; +import { + BtcAccountType, + BtcMethod, + EthAccountType, + EthMethod, +} from '@metamask/keyring-api'; +import { KeyringTypes } from '@metamask/keyring-controller'; +import { v4 } from 'uuid'; + +export const createMockInternalAccount = ({ + id = v4(), + address = '0x2990079bcdee240329a520d2444386fc119da21a', + type = EthAccountType.Eoa, + name = 'Account 1', + keyringType = KeyringTypes.hd, + snap, + importTime = Date.now(), + lastSelected = Date.now(), +}: { + id?: string; + address?: string; + type?: InternalAccountType; + name?: string; + keyringType?: KeyringTypes; + snap?: { + id: string; + enabled: boolean; + name: string; + }; + importTime?: number; + lastSelected?: number; +} = {}): InternalAccount => { + let methods; + + switch (type) { + case EthAccountType.Eoa: + methods = [ + EthMethod.PersonalSign, + EthMethod.Sign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV1, + EthMethod.SignTypedDataV3, + EthMethod.SignTypedDataV4, + ]; + break; + case EthAccountType.Erc4337: + methods = [ + EthMethod.PatchUserOperation, + EthMethod.PrepareUserOperation, + EthMethod.SignUserOperation, + ]; + break; + case BtcAccountType.P2wpkh: + methods = [BtcMethod.SendMany]; + break; + default: + throw new Error(`Unknown account type: ${type as string}`); + } + + return { + id, + address, + options: {}, + methods, + type, + metadata: { + name, + keyring: { type: keyringType }, + importTime, + lastSelected, + snap, + }, + } as InternalAccount; +}; diff --git a/packages/address-book-controller/CHANGELOG.md b/packages/address-book-controller/CHANGELOG.md index 7d38702f94f..0ce44eb48ba 100644 --- a/packages/address-book-controller/CHANGELOG.md +++ b/packages/address-book-controller/CHANGELOG.md @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [4.0.2] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Fixed + +- Fix `delete` method to protect against prototype-polluting assignments ([#4041](https://github.com/MetaMask/core/pull/4041)) + ## [4.0.1] ### Fixed @@ -127,7 +146,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@4.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@5.0.0...HEAD +[5.0.0]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@4.0.2...@metamask/address-book-controller@5.0.0 +[4.0.2]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@4.0.1...@metamask/address-book-controller@4.0.2 [4.0.1]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@4.0.0...@metamask/address-book-controller@4.0.1 [4.0.0]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@3.1.7...@metamask/address-book-controller@4.0.0 [3.1.7]: https://github.com/MetaMask/core/compare/@metamask/address-book-controller@3.1.6...@metamask/address-book-controller@3.1.7 diff --git a/packages/address-book-controller/package.json b/packages/address-book-controller/package.json index c7960636839..262ef3af82f 100644 --- a/packages/address-book-controller/package.json +++ b/packages/address-book-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/address-book-controller", - "version": "4.0.1", + "version": "5.0.0", "description": "Manages a list of recipient addresses associated with nicknames", "keywords": [ "MetaMask", @@ -41,8 +41,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/utils": "^8.3.0" }, "devDependencies": { @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/announcement-controller/CHANGELOG.md b/packages/announcement-controller/CHANGELOG.md index 8ed50fe48a0..7f4779d9445 100644 --- a/packages/announcement-controller/CHANGELOG.md +++ b/packages/announcement-controller/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [6.1.1] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) + ## [6.1.0] ### Added @@ -129,7 +142,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@6.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@7.0.0...HEAD +[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@6.1.1...@metamask/announcement-controller@7.0.0 +[6.1.1]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@6.1.0...@metamask/announcement-controller@6.1.1 [6.1.0]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@6.0.1...@metamask/announcement-controller@6.1.0 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@6.0.0...@metamask/announcement-controller@6.0.1 [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/announcement-controller@5.0.2...@metamask/announcement-controller@6.0.0 diff --git a/packages/announcement-controller/package.json b/packages/announcement-controller/package.json index f19f2ae7f56..8f5aee8e457 100644 --- a/packages/announcement-controller/package.json +++ b/packages/announcement-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/announcement-controller", - "version": "6.1.0", + "version": "7.0.0", "description": "Manages in-app announcements", "keywords": [ "MetaMask", @@ -41,7 +41,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2" + "@metamask/base-controller": "^6.0.0" }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", @@ -54,7 +54,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/approval-controller/CHANGELOG.md b/packages/approval-controller/CHANGELOG.md index 8c8c356be15..ef5cf06d1c2 100644 --- a/packages/approval-controller/CHANGELOG.md +++ b/packages/approval-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + ## [6.0.2] ### Changed @@ -193,7 +200,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@6.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@7.0.0...HEAD +[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@6.0.2...@metamask/approval-controller@7.0.0 [6.0.2]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@6.0.1...@metamask/approval-controller@6.0.2 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@6.0.0...@metamask/approval-controller@6.0.1 [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@5.1.3...@metamask/approval-controller@6.0.0 diff --git a/packages/approval-controller/package.json b/packages/approval-controller/package.json index d97a499ca64..f8f6e61aea4 100644 --- a/packages/approval-controller/package.json +++ b/packages/approval-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/approval-controller", - "version": "6.0.2", + "version": "7.0.0", "description": "Manages requests that require user approval", "keywords": [ "MetaMask", @@ -41,7 +41,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", "nanoid": "^3.1.31" @@ -58,7 +58,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/assets-controllers/CHANGELOG.md b/packages/assets-controllers/CHANGELOG.md index 9c9332f8ec6..fad9153b821 100644 --- a/packages/assets-controllers/CHANGELOG.md +++ b/packages/assets-controllers/CHANGELOG.md @@ -7,6 +7,99 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [32.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/accounts-controller` to `^16.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^7.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/keyring-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/preferences-controller` to `^13.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/polling-controller` to `^8.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [31.0.0] + +### Added + +- **BREAKING:** The `NftDetectionController` now takes a `messenger`, which can be used for communication ([#4312](https://github.com/MetaMask/core/pull/4312)) + - This messenger must allow the following actions `ApprovalController:addRequest`, `NetworkController:getState`, `NetworkController:getNetworkClientById`, and `PreferencesController:getState`, and must allow the events `PreferencesController:stateChange` and `NetworkController:stateChange` +- Add `NftDetectionControllerMessenger` type ([#4312](https://github.com/MetaMask/core/pull/4312)) +- Add `NftControllerGetStateAction`, `NftControllerActions`, `NftControllerStateChangeEvent`, and `NftControllerEvents` types ([#4310](https://github.com/MetaMask/core/pull/4310)) +- Add `NftController:getState` and `NftController:stateChange` as an available action and event to the `NftController` messenger ([#4310](https://github.com/MetaMask/core/pull/4310)) + +### Changed + +- **BREAKING:** Change `TokensController` to inherit from `BaseController` rather than `BaseControllerV1` ([#4304](https://github.com/MetaMask/core/pull/4304)) + - The constructor now takes a single options object rather than three arguments, and all properties in `config` are now part of options. +- **BREAKING:** Rename `TokensState` type to `TokensControllerState` ([#4304](https://github.com/MetaMask/core/pull/4304)) +- **BREAKING:** Make all `TokensController` methods and properties starting with `_` private ([#4304](https://github.com/MetaMask/core/pull/4304)) +- **BREAKING:** Convert `Token` from `interface` to `type` ([#4304](https://github.com/MetaMask/core/pull/4304)) +- **BREAKING:** Replace `balanceError` property in `Token` with `hasBalanceError`; update `TokenBalancesController` so that it no longer captures the error resulting from getting the balance of an ERC-20 token ([#4304](https://github.com/MetaMask/core/pull/4304)) +- **BREAKING:** Change `NftDetectionController` to inherit from `StaticIntervalPollingController` rather than `StaticIntervalPollingControllerV1` ([#4312](https://github.com/MetaMask/core/pull/4312)) + - The constructor now takes a single options object rather than three arguments, and all properties in `config` are now part of options. +- **BREAKING:** Convert `ApiNft`, `ApiNftContract`, `ApiNftLastSale`, and `ApiNftCreator` from `interface` to `type` ([#4312](https://github.com/MetaMask/core/pull/4312)) +- **BREAKING:** Change `NftController` to inherit from `BaseController` rather than `BaseControllerV1` ([#4310](https://github.com/MetaMask/core/pull/4310)) + - The constructor now takes a single options object rather than three arguments, and all properties in `config` are now part of options. +- **BREAKING:** Convert `Nft`, `NftContract`, and `NftMetadata` from `interface` to `type` ([#4310](https://github.com/MetaMask/core/pull/4310)) +- **BREAKING:** Rename `NftState` to `NftControllerState`, and convert to `type` ([#4310](https://github.com/MetaMask/core/pull/4310)) +- **BREAKING:** Rename `getDefaultNftState` to `getDefaultNftControllerState` ([#4310](https://github.com/MetaMask/core/pull/4310)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/accounts-controller` to `^15.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^6.0.2` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/keyring-controller` to `^16.1.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/preferences-controller` to `^12.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Change `NftDetectionController` method `detectNfts` so that `userAddress` option is optional ([#4312](https://github.com/MetaMask/core/pull/4312)) + - This will default to the currently selected address as kept by PreferencesController. +- Bump `async-mutex` to `^0.5.0` ([#4335](https://github.com/MetaMask/core/pull/4335)) +- Bump `@metamask/polling-controller` to `^7.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove `config` property and `configure` method from `TokensController` ([#4304](https://github.com/MetaMask/core/pull/4304)) + - The `TokensController` now takes a single options object which can be used for configuration, and configuration is now kept internally. +- **BREAKING:** Remove `notify`, `subscribe`, and `unsubscribe` methods from `TokensController` ([#4304](https://github.com/MetaMask/core/pull/4304)) + - Use the controller messenger for subscribing to and publishing events instead. +- **BREAKING:** Remove `TokensConfig` type ([#4304](https://github.com/MetaMask/core/pull/4304)) + - These properties have been merged into the options that `TokensController` takes. +- **BREAKING:** Remove `config` property and `configure` method from `TokensController` ([#4312](https://github.com/MetaMask/core/pull/4312)) + - `TokensController` now takes a single options object which can be used for configuration, and configuration is now kept internally. +- **BREAKING:** Remove `notify`, `subscribe`, and `unsubscribe` methods from `NftDetectionController` ([#4312](https://github.com/MetaMask/core/pull/4312)) + - Use the controller messenger for subscribing to and publishing events instead. +- **BREAKING:** Remove `chainId` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - The controller will now read the `networkClientId` from the NetworkController state through the messenger when needed. +- **BREAKING:** Remove `getNetworkClientById` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - The controller will now call `NetworkController:getNetworkClientId` through the messenger object. +- **BREAKING:** Remove `onPreferencesStateChange` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - The controller will now call `PreferencesController:stateChange` through the messenger object. +- **BREAKING:** Remove `onNetworkStateChange` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - The controller will now read the `networkClientId` from the NetworkController state through the messenger when needed. +- **BREAKING:** Remove `getOpenSeaApiKey` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - This was never used. +- **BREAKING:** Remove `getNftApi` as a `NftDetectionController` constructor argument ([#4312](https://github.com/MetaMask/core/pull/4312)) + - This was never used. +- **BREAKING:** Remove `NftDetectionConfig` type ([#4312](https://github.com/MetaMask/core/pull/4312)) + - These properties have been merged into the options that `NftDetectionController` takes. +- **BREAKING:** Remove `config` property and `configure` method from `NftController` ([#4310](https://github.com/MetaMask/core/pull/4310)) + - `NftController` now takes a single options object which can be used for configuration, and configuration is now kept internally. +- **BREAKING:** Remove `notify`, `subscribe`, and `unsubscribe` methods from `NftController` ([#4310](https://github.com/MetaMask/core/pull/4310)) + - Use the controller messenger for subscribing to and publishing events instead. +- **BREAKING:** Remove `onPreferencesStateChange` as a `NftController` constructor argument ([#4310](https://github.com/MetaMask/core/pull/4310)) + - The controller will now call `PreferencesController:stateChange` through the messenger object. +- **BREAKING:** Remove `onNetworkStateChange` as a `NftController` constructor argument ([#4310](https://github.com/MetaMask/core/pull/4310)) + - The controller will now call `NetworkController:stateChange` through the messenger object. +- **BREAKING:** Remove `NftConfig` type ([#4310](https://github.com/MetaMask/core/pull/4310)) + - These properties have been merged into the options that `NftController` takes. +- **BREAKING:** Remove `config` property and `configure` method from `NftController` ([#4310](https://github.com/MetaMask/core/pull/4310)) + - `NftController` now takes a single options object which can be used for configuration, and configuration is now kept internally. +- **BREAKING:** Remove `hub` property from `NftController` ([#4310](https://github.com/MetaMask/core/pull/4310)) + - Use the controller messenger for subscribing to and publishing events instead. +- **BREAKING:** Modify `TokenListController` so that tokens fetched from the API and stored in state will no longer have `storage` and `erc20` properties ([#4235](https://github.com/MetaMask/core/pull/4235)) + - These properties were never officially supported, but they were present in state anyway. + ## [30.0.0] ### Added @@ -796,7 +889,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@30.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@32.0.0...HEAD +[32.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@31.0.0...@metamask/assets-controllers@32.0.0 +[31.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@30.0.0...@metamask/assets-controllers@31.0.0 [30.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@29.0.0...@metamask/assets-controllers@30.0.0 [29.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@28.0.0...@metamask/assets-controllers@29.0.0 [28.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@27.2.0...@metamask/assets-controllers@28.0.0 diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index 378a8caba2e..4536f6db481 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/assets-controllers", - "version": "30.0.0", + "version": "32.0.0", "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)", "keywords": [ "MetaMask", @@ -47,17 +47,17 @@ "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", "@metamask/abi-utils": "^2.0.2", - "@metamask/accounts-controller": "^14.0.0", - "@metamask/approval-controller": "^6.0.2", - "@metamask/base-controller": "^5.0.2", + "@metamask/accounts-controller": "^16.0.0", + "@metamask/approval-controller": "^7.0.0", + "@metamask/base-controller": "^6.0.0", "@metamask/contract-metadata": "^2.4.0", - "@metamask/controller-utils": "^10.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-query": "^4.0.0", - "@metamask/keyring-controller": "^16.0.0", + "@metamask/keyring-controller": "^17.0.0", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/network-controller": "^18.1.2", - "@metamask/polling-controller": "^6.0.2", - "@metamask/preferences-controller": "^11.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/polling-controller": "^8.0.0", + "@metamask/preferences-controller": "^13.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", "@types/bn.js": "^5.1.5", @@ -73,7 +73,7 @@ "devDependencies": { "@metamask/auto-changelog": "^3.4.4", "@metamask/ethjs-provider-http": "^0.3.0", - "@metamask/keyring-api": "^6.1.1", + "@metamask/keyring-api": "^6.4.0", "@types/jest": "^27.4.1", "@types/lodash": "^4.14.191", "@types/node": "^16.18.54", @@ -88,14 +88,14 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/accounts-controller": "^14.0.0", - "@metamask/approval-controller": "^6.0.0", - "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.1.2", - "@metamask/preferences-controller": "^11.0.0" + "@metamask/accounts-controller": "^16.0.0", + "@metamask/approval-controller": "^7.0.0", + "@metamask/keyring-controller": "^17.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/preferences-controller": "^13.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/assets-controllers/src/AccountTrackerController.ts b/packages/assets-controllers/src/AccountTrackerController.ts index 3596790358b..3020b41c7fa 100644 --- a/packages/assets-controllers/src/AccountTrackerController.ts +++ b/packages/assets-controllers/src/AccountTrackerController.ts @@ -5,10 +5,10 @@ import type { Provider } from '@metamask/eth-query'; import type { NetworkClientId, NetworkController, - NetworkState, } from '@metamask/network-controller'; import { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller'; import type { PreferencesState } from '@metamask/preferences-controller'; +import type { Hex } from '@metamask/utils'; import { assert } from '@metamask/utils'; import { Mutex } from 'async-mutex'; import { cloneDeep } from 'lodash'; @@ -120,7 +120,7 @@ export class AccountTrackerController extends StaticIntervalPollingControllerV1< private readonly getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled']; - private readonly getCurrentChainId: () => NetworkState['providerConfig']['chainId']; + private readonly getCurrentChainId: () => Hex; private readonly getNetworkClientById: NetworkController['getNetworkClientById']; @@ -152,7 +152,7 @@ export class AccountTrackerController extends StaticIntervalPollingControllerV1< getIdentities: () => PreferencesState['identities']; getSelectedAddress: () => PreferencesState['selectedAddress']; getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled']; - getCurrentChainId: () => NetworkState['providerConfig']['chainId']; + getCurrentChainId: () => Hex; getNetworkClientById: NetworkController['getNetworkClientById']; }, config?: Partial, @@ -285,9 +285,8 @@ export class AccountTrackerController extends StaticIntervalPollingControllerV1< [chainId]: accountsForChain, }, }); - } catch (err) { + } finally { releaseLock(); - throw err; } }; diff --git a/packages/assets-controllers/src/AssetsContractController.test.ts b/packages/assets-controllers/src/AssetsContractController.test.ts index 1ac2b3b0fc4..8600501e0ef 100644 --- a/packages/assets-controllers/src/AssetsContractController.test.ts +++ b/packages/assets-controllers/src/AssetsContractController.test.ts @@ -1,7 +1,9 @@ +import { BigNumber } from '@ethersproject/bignumber'; import { ControllerMessenger } from '@metamask/base-controller'; import { BUILT_IN_NETWORKS, ChainId, + InfuraNetworkType, IPFS_DEFAULT_GATEWAY_URL, NetworkType, } from '@metamask/controller-utils'; @@ -9,6 +11,7 @@ import HttpProvider from '@metamask/ethjs-provider-http'; import type { NetworkClientId, NetworkControllerMessenger, + Provider, } from '@metamask/network-controller'; import { NetworkController, @@ -18,8 +21,10 @@ import { getDefaultPreferencesState, type PreferencesState, } from '@metamask/preferences-controller'; +import assert from 'assert'; import { mockNetwork } from '../../../tests/mock-network'; +import { buildInfuraNetworkClientConfiguration } from '../../network-controller/tests/helpers'; import { AssetsContractController, MISSING_PROVIDER_ERROR, @@ -41,16 +46,31 @@ const TEST_ACCOUNT_PUBLIC_ADDRESS = * Creates the assets contract controller along with the dependencies necessary * to use it effectively in tests. * + * @param args - The arguments to this function. + * @param args.options - AssetsContractController options. + * @param args.useNetworkControllerProvider - Whether to use the initial + * provider that the network controller creates or to create a new one. + * @param args.infuraProjectId - The Infura project ID to use when initializing + * the network controller. * @returns the objects. */ -async function setupAssetContractControllers() { +async function setupAssetContractControllers({ + options, + useNetworkControllerProvider, + infuraProjectId = '341eacb578dd44a1a049cbc5f6fd4035', +}: { + options?: Partial[0]>; + useNetworkControllerProvider?: boolean; + infuraProjectId?: string; +} = {}) { const networkClientConfiguration = { type: NetworkClientType.Infura, network: 'mainnet', - infuraProjectId: '341eacb578dd44a1a049cbc5f6fd4035', + infuraProjectId, chainId: BUILT_IN_NETWORKS.mainnet.chainId, ticker: BUILT_IN_NETWORKS.mainnet.ticker, } as const; + let provider: Provider; const messenger: NetworkControllerMessenger = new ControllerMessenger().getRestricted({ @@ -58,15 +78,31 @@ async function setupAssetContractControllers() { allowedActions: [], allowedEvents: [], }); - const network = new NetworkController({ - infuraProjectId: networkClientConfiguration.infuraProjectId, + const networkController = new NetworkController({ + infuraProjectId, messenger, trackMetaMetricsEvent: jest.fn(), }); + if (useNetworkControllerProvider) { + await networkController.initializeProvider(); + const selectedNetworkClient = networkController.getSelectedNetworkClient(); + assert(selectedNetworkClient, 'No network is selected'); + provider = selectedNetworkClient.provider; + } else { + provider = new HttpProvider( + `https://mainnet.infura.io/v3/${infuraProjectId}`, + ); + } - const provider = new HttpProvider( - `https://mainnet.infura.io/v3/${networkClientConfiguration.infuraProjectId}`, - ); + const getNetworkClientById = useNetworkControllerProvider + ? networkController.getNetworkClientById.bind(networkController) + : (networkClientId: NetworkClientId) => + ({ + ...networkController.getNetworkClientById(networkClientId), + provider, + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); const preferencesStateChangeListeners: ((state: PreferencesState) => void)[] = []; @@ -77,21 +113,17 @@ async function setupAssetContractControllers() { }, onNetworkDidChange: (listener) => messenger.subscribe('NetworkController:networkDidChange', listener), - getNetworkClientById: (networkClientId: NetworkClientId) => - ({ - ...network.getNetworkClientById(networkClientId), - provider, - // TODO: Replace `any` with type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any), + getNetworkClientById, + ...options, }); return { messenger, - network, + network: networkController, assetsContract, provider, networkClientConfiguration, + infuraProjectId, triggerPreferencesStateChange: (state: PreferencesState) => { for (const listener of preferencesStateChangeListeners) { listener(state); @@ -874,6 +906,103 @@ describe('AssetsContractController', () => { messenger.clearEventSubscriptions('NetworkController:networkDidChange'); }); + it('should track and use the currently selected chain ID and provider when getting balances in a single call', async () => { + const infuraProjectId = 'some-infura-project-id'; + mockNetwork({ + networkClientConfiguration: buildInfuraNetworkClientConfiguration( + InfuraNetworkType.mainnet, + { infuraProjectId }, + ), + mocks: [ + { + request: { + method: 'eth_blockNumber', + params: [], + }, + response: { + result: '0x3b3301', + }, + }, + { + request: { + method: 'eth_call', + params: [ + { + to: '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39', + data: '0xf0002ea900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000000000000000000100000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359', + }, + '0x3b3301', + ], + }, + response: { + result: + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000733ed8ef4c4a0155d09', + }, + }, + ], + }); + mockNetwork({ + networkClientConfiguration: buildInfuraNetworkClientConfiguration( + InfuraNetworkType['linea-mainnet'], + { infuraProjectId }, + ), + mocks: [ + { + request: { + method: 'eth_blockNumber', + params: [], + }, + response: { + result: '0x3b3301', + }, + }, + { + request: { + method: 'eth_call', + params: [ + { + to: '0xf62e6a41561b3650a69bb03199c735e3e3328c0d', + data: '0xf0002ea900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000000000000000000100000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359', + }, + '0x3b3301', + ], + }, + response: { + result: + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000a0155d09733ed8ef4c4', + }, + }, + ], + }); + const { assetsContract, network, provider } = + await setupAssetContractControllers({ + options: { + chainId: ChainId.mainnet, + }, + useNetworkControllerProvider: true, + infuraProjectId, + }); + assetsContract.configure({ provider }); + + const balancesOnMainnet = await assetsContract.getBalancesInSingleCall( + ERC20_SAI_ADDRESS, + [ERC20_SAI_ADDRESS], + ); + expect(balancesOnMainnet).toStrictEqual({ + [ERC20_SAI_ADDRESS]: BigNumber.from('0x0733ed8ef4c4a0155d09'), + }); + + await network.setActiveNetwork(InfuraNetworkType['linea-mainnet']); + + const balancesOnLineaMainnet = await assetsContract.getBalancesInSingleCall( + ERC20_SAI_ADDRESS, + [ERC20_SAI_ADDRESS], + ); + expect(balancesOnLineaMainnet).toStrictEqual({ + [ERC20_SAI_ADDRESS]: BigNumber.from('0xa0155d09733ed8ef4c4'), + }); + }); + it('should not have balance in a single call after switching to network without token detection support', async () => { const { assetsContract, diff --git a/packages/assets-controllers/src/AssetsContractController.ts b/packages/assets-controllers/src/AssetsContractController.ts index b9dd83602a6..06e72dce348 100644 --- a/packages/assets-controllers/src/AssetsContractController.ts +++ b/packages/assets-controllers/src/AssetsContractController.ts @@ -154,10 +154,15 @@ export class AssetsContractController extends BaseControllerV1< this.configure({ ipfsGateway }); }); - onNetworkDidChange((networkState) => { - if (this.config.chainId !== networkState.providerConfig.chainId) { + onNetworkDidChange(({ selectedNetworkClientId }) => { + const selectedNetworkClient = getNetworkClientById( + selectedNetworkClientId, + ); + const { chainId } = selectedNetworkClient.configuration; + + if (this.config.chainId !== chainId) { this.configure({ - chainId: networkState.providerConfig.chainId, + chainId: selectedNetworkClient.configuration.chainId, }); } }); diff --git a/packages/assets-controllers/src/TokenListController.test.ts b/packages/assets-controllers/src/TokenListController.test.ts index f52b91a0c73..3b7a6bc2c6f 100644 --- a/packages/assets-controllers/src/TokenListController.test.ts +++ b/packages/assets-controllers/src/TokenListController.test.ts @@ -2,28 +2,30 @@ import { ControllerMessenger } from '@metamask/base-controller'; import { ChainId, NetworkType, - NetworksTicker, convertHexToDecimal, toHex, + InfuraNetworkType, } from '@metamask/controller-utils'; -import type { - NetworkControllerGetNetworkClientByIdAction, - NetworkControllerStateChangeEvent, - NetworkState, - ProviderConfig, -} from '@metamask/network-controller'; -import { NetworkStatus } from '@metamask/network-controller'; +import type { NetworkState } from '@metamask/network-controller'; import type { Hex } from '@metamask/utils'; import nock from 'nock'; import * as sinon from 'sinon'; import { advanceTime } from '../../../tests/helpers'; +import type { + ExtractAvailableAction, + ExtractAvailableEvent, +} from '../../base-controller/tests/helpers'; +import { + buildCustomNetworkClientConfiguration, + buildInfuraNetworkClientConfiguration, + buildMockGetNetworkClientById, +} from '../../network-controller/tests/helpers'; import * as tokenService from './token-service'; import type { - TokenListStateChange, - GetTokenListState, TokenListMap, TokenListState, + TokenListControllerMessenger, } from './TokenListController'; import { TokenListController } from './TokenListController'; @@ -493,8 +495,8 @@ const expiredCacheExistingState: TokenListState = { }; type MainControllerMessenger = ControllerMessenger< - GetTokenListState | NetworkControllerGetNetworkClientByIdAction, - TokenListStateChange | NetworkControllerStateChangeEvent + ExtractAvailableAction, + ExtractAvailableEvent >; const getControllerMessenger = (): MainControllerMessenger => { @@ -513,31 +515,6 @@ const getRestrictedMessenger = ( return messenger; }; -/** - * Builds an object that satisfies the NetworkState shape using the given - * provider config. This can be used to return a complete value for the - * `NetworkController:stateChange` event. - * - * @param providerConfig - The provider config to use. - * @returns A complete state object for NetworkController. - */ -function buildNetworkControllerStateWithProviderConfig( - providerConfig: ProviderConfig, -): NetworkState { - const selectedNetworkClientId = providerConfig.type || 'uuid-1'; - return { - selectedNetworkClientId, - providerConfig, - networksMetadata: { - [selectedNetworkClientId]: { - EIPS: {}, - status: NetworkStatus.Available, - }, - }, - networkConfigurations: {}, - }; -} - describe('TokenListController', () => { afterEach(() => { jest.restoreAllMocks(); @@ -653,8 +630,17 @@ describe('TokenListController', () => { .get(getTokensPath(ChainId.mainnet)) .reply(200, sampleMainnetTokenList) .persist(); - + const selectedNetworkClientId = 'selectedNetworkClientId'; const controllerMessenger = getControllerMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById({ + [selectedNetworkClientId]: buildCustomNetworkClientConfiguration({ + chainId: toHex(1337), + }), + }); + controllerMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const messenger = getRestrictedMessenger(controllerMessenger); let onNetworkStateChangeCallback!: (state: NetworkState) => void; const controller = new TokenListController({ @@ -669,13 +655,13 @@ describe('TokenListController', () => { expect(controller.state.tokenList).toStrictEqual( sampleSingleChainState.tokenList, ); - onNetworkStateChangeCallback( - buildNetworkControllerStateWithProviderConfig({ - chainId: ChainId.goerli, - type: NetworkType.goerli, - ticker: NetworksTicker.goerli, - }), - ); + onNetworkStateChangeCallback({ + selectedNetworkClientId, + networkConfigurations: {}, + networksMetadata: {}, + // @ts-expect-error This property isn't used and will get removed later. + providerConfig: {}, + }); await new Promise((resolve) => setTimeout(() => resolve(), 500)); expect(controller.state.tokenList).toStrictEqual({}); @@ -971,8 +957,20 @@ describe('TokenListController', () => { .get(getTokensPath(toHex(56))) .reply(200, sampleBinanceTokenList) .persist(); - + const selectedCustomNetworkClientId = 'selectedCustomNetworkClientId'; const controllerMessenger = getControllerMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById({ + [InfuraNetworkType.goerli]: buildInfuraNetworkClientConfiguration( + InfuraNetworkType.goerli, + ), + [selectedCustomNetworkClientId]: buildCustomNetworkClientConfiguration({ + chainId: toHex(56), + }), + }); + controllerMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const messenger = getRestrictedMessenger(controllerMessenger); const controller = new TokenListController({ chainId: ChainId.mainnet, @@ -995,11 +993,13 @@ describe('TokenListController', () => { controllerMessenger.publish( 'NetworkController:stateChange', - buildNetworkControllerStateWithProviderConfig({ - type: NetworkType.goerli, - chainId: ChainId.goerli, - ticker: NetworksTicker.goerli, - }), + { + selectedNetworkClientId: InfuraNetworkType.goerli, + networkConfigurations: {}, + networksMetadata: {}, + // @ts-expect-error This property isn't used and will get removed later. + providerConfig: {}, + }, [], ); @@ -1014,12 +1014,13 @@ describe('TokenListController', () => { controllerMessenger.publish( 'NetworkController:stateChange', - buildNetworkControllerStateWithProviderConfig({ - type: NetworkType.rpc, - chainId: toHex(56), - rpcUrl: 'http://localhost:8545', - ticker: 'TEST', - }), + { + selectedNetworkClientId: selectedCustomNetworkClientId, + networkConfigurations: {}, + networksMetadata: {}, + // @ts-expect-error This property isn't used and will get removed later. + providerConfig: {}, + }, [], ); @@ -1069,7 +1070,20 @@ describe('TokenListController', () => { .reply(200, sampleBinanceTokenList) .persist(); + const selectedCustomNetworkClientId = 'selectedCustomNetworkClientId'; const controllerMessenger = getControllerMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById({ + [InfuraNetworkType.mainnet]: buildInfuraNetworkClientConfiguration( + InfuraNetworkType.mainnet, + ), + [selectedCustomNetworkClientId]: buildCustomNetworkClientConfiguration({ + chainId: toHex(56), + }), + }); + controllerMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const messenger = getRestrictedMessenger(controllerMessenger); const controller = new TokenListController({ chainId: ChainId.goerli, @@ -1080,11 +1094,13 @@ describe('TokenListController', () => { await controller.start(); controllerMessenger.publish( 'NetworkController:stateChange', - buildNetworkControllerStateWithProviderConfig({ - type: NetworkType.mainnet, - chainId: ChainId.mainnet, - ticker: NetworksTicker.mainnet, - }), + { + selectedNetworkClientId: InfuraNetworkType.mainnet, + networkConfigurations: {}, + networksMetadata: {}, + // @ts-expect-error This property isn't used and will get removed later. + providerConfig: {}, + }, [], ); @@ -1128,12 +1144,13 @@ describe('TokenListController', () => { controllerMessenger.publish( 'NetworkController:stateChange', - buildNetworkControllerStateWithProviderConfig({ - type: NetworkType.rpc, - chainId: toHex(56), - rpcUrl: 'http://localhost:8545', - ticker: 'TEST', - }), + { + selectedNetworkClientId: selectedCustomNetworkClientId, + networkConfigurations: {}, + networksMetadata: {}, + // @ts-expect-error This property isn't used and will get removed later. + providerConfig: {}, + }, [], ); }); @@ -1343,5 +1360,5 @@ describe('TokenListController', () => { function getTokensPath(chainId: Hex) { return `/tokens/${convertHexToDecimal( chainId, - )}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`; + )}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`; } diff --git a/packages/assets-controllers/src/TokenListController.ts b/packages/assets-controllers/src/TokenListController.ts index c83c1753e29..ce88c4b5436 100644 --- a/packages/assets-controllers/src/TokenListController.ts +++ b/packages/assets-controllers/src/TokenListController.ts @@ -175,10 +175,16 @@ export class TokenListController extends StaticIntervalPollingController< * @param networkControllerState - The updated network controller state. */ async #onNetworkControllerStateChange(networkControllerState: NetworkState) { - if (this.chainId !== networkControllerState.providerConfig.chainId) { + const selectedNetworkClient = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + networkControllerState.selectedNetworkClientId, + ); + const { chainId } = selectedNetworkClient.configuration; + + if (this.chainId !== chainId) { this.abortController.abort(); this.abortController = new AbortController(); - this.chainId = networkControllerState.providerConfig.chainId; + this.chainId = chainId; if (this.state.preventPollingOnNetworkRestart) { this.clearingTokenListData(); } else { diff --git a/packages/assets-controllers/src/TokensController.test.ts b/packages/assets-controllers/src/TokensController.test.ts index 311ec8c23e3..970310d99b2 100644 --- a/packages/assets-controllers/src/TokensController.test.ts +++ b/packages/assets-controllers/src/TokensController.test.ts @@ -11,14 +11,11 @@ import { ChainId, ORIGIN_METAMASK, convertHexToDecimal, - NetworkType, - toHex, - NetworksTicker, + InfuraNetworkType, } from '@metamask/controller-utils'; import type { NetworkClientConfiguration, NetworkClientId, - ProviderConfig, } from '@metamask/network-controller'; import { defaultState as defaultNetworkState } from '@metamask/network-controller'; import type { PreferencesState } from '@metamask/preferences-controller'; @@ -61,17 +58,6 @@ const uuidV1Mock = jest.mocked(uuidV1); const ERC20StandardMock = jest.mocked(ERC20Standard); const ERC1155StandardMock = jest.mocked(ERC1155Standard); -const SEPOLIA = { - chainId: toHex(11155111), - type: NetworkType.sepolia, - ticker: NetworksTicker.sepolia, -}; -const GOERLI = { - chainId: toHex(5), - type: NetworkType.goerli, - ticker: NetworksTicker.goerli, -}; - describe('TokensController', () => { beforeEach(() => { uuidV1Mock.mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'); @@ -321,17 +307,17 @@ describe('TokensController', () => { it('should add token by network', async () => { await withController(async ({ controller, changeNetwork }) => { - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x01', symbol: 'bar', decimals: 2, }); - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); expect(controller.state.tokens).toHaveLength(0); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); expect(controller.state.tokens[0]).toStrictEqual({ address: '0x01', decimals: 2, @@ -472,13 +458,13 @@ describe('TokensController', () => { ContractMock.mockReturnValue( buildMockEthersERC721Contract({ supportsInterface: false }), ); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x02', symbol: 'baz', decimals: 2, }); - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); await controller.addToken({ address: '0x01', symbol: 'bar', @@ -488,7 +474,7 @@ describe('TokensController', () => { controller.ignoreTokens(['0x01']); expect(controller.state.tokens).toHaveLength(0); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); expect(controller.state.tokens[0]).toStrictEqual({ address: '0x02', decimals: 2, @@ -544,7 +530,7 @@ describe('TokensController', () => { ...getDefaultPreferencesState(), selectedAddress, }); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x01', symbol: 'bar', @@ -591,7 +577,7 @@ describe('TokensController', () => { ...getDefaultPreferencesState(), selectedAddress, }); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x01', symbol: 'bar', @@ -629,7 +615,7 @@ describe('TokensController', () => { ...getDefaultPreferencesState(), selectedAddress: selectedAddress1, }); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x01', symbol: 'bar', @@ -641,7 +627,7 @@ describe('TokensController', () => { expect(controller.state.tokens).toHaveLength(0); expect(controller.state.ignoredTokens).toStrictEqual(['0x01']); - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); expect(controller.state.ignoredTokens).toHaveLength(0); await controller.addToken({ @@ -903,7 +889,7 @@ describe('TokensController', () => { symbol: 'LINK', decimals: 18, }); - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); await expect(addTokenPromise).rejects.toThrow( 'TokensController Error: Switched networks while adding token', @@ -992,9 +978,12 @@ describe('TokensController', () => { ); // The currently configured chain + address - const CONFIGURED_CHAIN = SEPOLIA; + const CONFIGURED_CHAIN = ChainId.sepolia; + const CONFIGURED_NETWORK_CLIENT_ID = InfuraNetworkType.sepolia; const CONFIGURED_ADDRESS = '0xConfiguredAddress'; - changeNetwork(CONFIGURED_CHAIN); + changeNetwork({ + selectedNetworkClientId: CONFIGURED_NETWORK_CLIENT_ID, + }); triggerPreferencesStateChange({ ...getDefaultPreferencesState(), selectedAddress: CONFIGURED_ADDRESS, @@ -1046,12 +1035,12 @@ describe('TokensController', () => { // Expect tokens under the correct chain + account expect(controller.state.allTokens).toStrictEqual({ - [CONFIGURED_CHAIN.chainId]: { + [CONFIGURED_CHAIN]: { [CONFIGURED_ADDRESS]: [addedTokenConfiguredAccount], }, }); expect(controller.state.allDetectedTokens).toStrictEqual({ - [CONFIGURED_CHAIN.chainId]: { + [CONFIGURED_CHAIN]: { [CONFIGURED_ADDRESS]: [detectedTokenConfiguredAccount], }, [OTHER_CHAIN]: { @@ -1939,7 +1928,7 @@ describe('TokensController', () => { buildMockEthersERC721Contract({ supportsInterface: false }), ); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); await controller.addToken({ address: '0x01', symbol: 'A', @@ -1952,7 +1941,7 @@ describe('TokensController', () => { }); const initialTokensFirst = controller.state.tokens; - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); await controller.addToken({ address: '0x03', symbol: 'C', @@ -2009,10 +1998,10 @@ describe('TokensController', () => { }, ]); - changeNetwork(SEPOLIA); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.sepolia }); expect(initialTokensFirst).toStrictEqual(controller.state.tokens); - changeNetwork(GOERLI); + changeNetwork({ selectedNetworkClientId: InfuraNetworkType.goerli }); expect(initialTokensSecond).toStrictEqual(controller.state.tokens); }); }); @@ -2179,7 +2168,9 @@ type WithControllerCallback = ({ triggerPreferencesStateChange, }: { controller: TokensController; - changeNetwork: (providerConfig: ProviderConfig) => void; + changeNetwork: (networkControllerState: { + selectedNetworkClientId: NetworkClientId; + }) => void; messenger: UnrestrictedMessenger; approvalController: ApprovalController; triggerPreferencesStateChange: (state: PreferencesState) => void; @@ -2259,10 +2250,14 @@ async function withController( messenger.publish('PreferencesController:stateChange', state, []); }; - const changeNetwork = (providerConfig: ProviderConfig) => { + const changeNetwork = ({ + selectedNetworkClientId, + }: { + selectedNetworkClientId: NetworkClientId; + }) => { messenger.publish('NetworkController:networkDidChange', { ...defaultNetworkState, - providerConfig, + selectedNetworkClientId, }); }; diff --git a/packages/assets-controllers/src/TokensController.ts b/packages/assets-controllers/src/TokensController.ts index 07e960def96..ce7cb493deb 100644 --- a/packages/assets-controllers/src/TokensController.ts +++ b/packages/assets-controllers/src/TokensController.ts @@ -260,11 +260,16 @@ export class TokensController extends BaseController< * Handles the event when the network changes. * * @param networkState - The changed network state. - * @param networkState.providerConfig - RPC URL and network name provider settings of the currently connected network + * @param networkState.selectedNetworkClientId - The ID of the currently + * selected network client. */ - #onNetworkDidChange({ providerConfig }: NetworkState) { + #onNetworkDidChange({ selectedNetworkClientId }: NetworkState) { + const selectedNetworkClient = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + selectedNetworkClientId, + ); const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state; - const { chainId } = providerConfig; + const { chainId } = selectedNetworkClient.configuration; this.#abortController.abort(); this.#abortController = new AbortController(); this.#chainId = chainId; diff --git a/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts b/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts index 7660277bc38..74d52436a4c 100644 --- a/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts +++ b/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts @@ -479,6 +479,59 @@ describe('CodefiTokenPricesServiceV2', () => { }); }); + it('should correctly handle null market data for a token address', async () => { + nock('https://price.api.cx.metamask.io') + .get('/v2/chains/1/spot-prices') + .query({ + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', + vsCurrency: 'ETH', + includeMarketData: 'true', + }) + .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + }, + '0xaaa': null, // Simulating API returning null for market data + '0xbbb': { + price: 33689.98134554716, + currency: 'ETH', + }, + '0xccc': { + price: 148.1344197578456, + currency: 'ETH', + }, + }); + + const result = await new CodefiTokenPricesServiceV2().fetchTokenPrices({ + chainId: '0x1', + tokenAddresses: ['0xAAA', '0xBBB', '0xCCC'], + currency: 'ETH', + }); + + expect(result).toStrictEqual({ + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + value: 14, + currency: 'ETH', + price: 14, + }, + '0xBBB': { + tokenAddress: '0xBBB', + value: 33689.98134554716, + currency: 'ETH', + price: 33689.98134554716, + }, + '0xCCC': { + tokenAddress: '0xCCC', + value: 148.1344197578456, + currency: 'ETH', + price: 148.1344197578456, + }, + }); + }); + it('throws if the request fails consistently', async () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') diff --git a/packages/assets-controllers/src/token-prices-service/codefi-v2.ts b/packages/assets-controllers/src/token-prices-service/codefi-v2.ts index 0ffcaaa1f35..973a98a62ab 100644 --- a/packages/assets-controllers/src/token-prices-service/codefi-v2.ts +++ b/packages/assets-controllers/src/token-prices-service/codefi-v2.ts @@ -455,7 +455,7 @@ export class CodefiTokenPricesServiceV2 const marketData = addressCryptoDataMap[lowercasedTokenAddress]; - if (marketData === undefined) { + if (!marketData) { return obj; } diff --git a/packages/assets-controllers/src/token-service.test.ts b/packages/assets-controllers/src/token-service.test.ts index 21908dd428b..26ff3aa8fb0 100644 --- a/packages/assets-controllers/src/token-service.test.ts +++ b/packages/assets-controllers/src/token-service.test.ts @@ -243,7 +243,7 @@ describe('Token service', () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get( - `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) .reply(200, sampleTokenList) .persist(); @@ -260,7 +260,7 @@ describe('Token service', () => { nock(TOKEN_END_POINT_API) .get( - `/tokens/${lineaChainId}?occurrenceFloor=1&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${lineaChainId}?occurrenceFloor=1&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) .reply(200, sampleTokenListLinea) .persist(); @@ -274,7 +274,7 @@ describe('Token service', () => { const abortController = new AbortController(); nock(TOKEN_END_POINT_API) .get( - `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) // well beyond time it will take to abort .delay(ONE_SECOND_IN_MILLISECONDS) @@ -294,7 +294,7 @@ describe('Token service', () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get( - `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) .replyWithError('Example network error') .persist(); @@ -308,7 +308,7 @@ describe('Token service', () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get( - `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) .reply(500) .persist(); @@ -322,7 +322,7 @@ describe('Token service', () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get( - `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`, + `/tokens/${sampleDecimalChainId}?occurrenceFloor=3&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`, ) // well beyond timeout .delay(ONE_SECOND_IN_MILLISECONDS) diff --git a/packages/assets-controllers/src/token-service.ts b/packages/assets-controllers/src/token-service.ts index becedb82004..dd3bc1f915c 100644 --- a/packages/assets-controllers/src/token-service.ts +++ b/packages/assets-controllers/src/token-service.ts @@ -21,7 +21,7 @@ function getTokensURL(chainId: Hex) { const occurrenceFloor = chainId === ChainId['linea-mainnet'] ? 1 : 3; return `${TOKEN_END_POINT_API}/tokens/${convertHexToDecimal( chainId, - )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false`; + )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeDuplicateSymbolAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`; } /** diff --git a/packages/base-controller/CHANGELOG.md b/packages/base-controller/CHANGELOG.md index 47b9600fea6..801dc144f6f 100644 --- a/packages/base-controller/CHANGELOG.md +++ b/packages/base-controller/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) + ## [5.0.2] ### Changed @@ -207,7 +213,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-controller@5.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-controller@6.0.0...HEAD +[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@5.0.2...@metamask/base-controller@6.0.0 [5.0.2]: https://github.com/MetaMask/core/compare/@metamask/base-controller@5.0.1...@metamask/base-controller@5.0.2 [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/base-controller@5.0.0...@metamask/base-controller@5.0.1 [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@4.1.1...@metamask/base-controller@5.0.0 diff --git a/packages/base-controller/package.json b/packages/base-controller/package.json index 22d1647183a..8cb96411341 100644 --- a/packages/base-controller/package.json +++ b/packages/base-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/base-controller", - "version": "5.0.2", + "version": "6.0.0", "description": "Provides scaffolding for controllers as well a communication system for all controllers", "keywords": [ "MetaMask", @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/build-utils/CHANGELOG.md b/packages/build-utils/CHANGELOG.md index 5f51c311baa..29790897802 100644 --- a/packages/build-utils/CHANGELOG.md +++ b/packages/build-utils/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + ## [2.0.1] ### Fixed @@ -38,7 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#3577](https://github.com/MetaMask/core/pull/3577) [#3588](https://github.com/MetaMask/core/pull/3588)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/build-utils@2.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.0...HEAD +[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/build-utils@2.0.1...@metamask/build-utils@3.0.0 [2.0.1]: https://github.com/MetaMask/core/compare/@metamask/build-utils@2.0.0...@metamask/build-utils@2.0.1 [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/build-utils@1.0.2...@metamask/build-utils@2.0.0 [1.0.2]: https://github.com/MetaMask/core/compare/@metamask/build-utils@1.0.1...@metamask/build-utils@1.0.2 diff --git a/packages/build-utils/package.json b/packages/build-utils/package.json index 4c5e55f27d5..29b7eec38e7 100644 --- a/packages/build-utils/package.json +++ b/packages/build-utils/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/build-utils", - "version": "2.0.1", + "version": "3.0.0", "description": "Utilities for building MetaMask applications", "keywords": [ "MetaMask", @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/chain-controller/package.json b/packages/chain-controller/package.json index 115469530ec..f023fb1c987 100644 --- a/packages/chain-controller/package.json +++ b/packages/chain-controller/package.json @@ -41,9 +41,9 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/chain-api": "^0.0.1", - "@metamask/keyring-api": "^6.1.1", + "@metamask/keyring-api": "^6.4.0", "@metamask/snaps-controllers": "^8.1.1", "@metamask/snaps-sdk": "^4.2.0", "@metamask/snaps-utils": "^7.4.0", @@ -62,7 +62,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/composable-controller/CHANGELOG.md b/packages/composable-controller/CHANGELOG.md index ee846caee9a..a074b1488b5 100644 --- a/packages/composable-controller/CHANGELOG.md +++ b/packages/composable-controller/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [6.0.2] + ### Added - Adds and exports new types: ([#3952](https://github.com/MetaMask/core/pull/3952)) @@ -18,6 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** The `ComposableController` class is now a generic class that expects one generic argument `ComposableControllerState` ([#3952](https://github.com/MetaMask/core/pull/3952)). - **BREAKING:** For the `ComposableController` class to be typed correctly, any of its child controllers that extend `BaseControllerV1` must have an overridden `name` property that is defined using the `as const` assertion. +- **BREAKING:** The types `ComposableControllerStateChangeEvent`, `ComposableControllerEvents`, `ComposableControllerMessenger` are now generic types that expect one generic argument `ComposableControllerState` ([#3952](https://github.com/MetaMask/core/pull/3952)). +- Bump `@metamask/json-rpc-engine` to `^8.0.2` ([#4234](https://github.com/MetaMask/core/pull/4234)) +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) ## [6.0.1] @@ -134,7 +147,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@6.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@7.0.0...HEAD +[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@6.0.2...@metamask/composable-controller@7.0.0 +[6.0.2]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@6.0.1...@metamask/composable-controller@6.0.2 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@6.0.0...@metamask/composable-controller@6.0.1 [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@5.0.1...@metamask/composable-controller@6.0.0 [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/composable-controller@5.0.0...@metamask/composable-controller@5.0.1 diff --git a/packages/composable-controller/package.json b/packages/composable-controller/package.json index 6425c98e6e7..9865ba373af 100644 --- a/packages/composable-controller/package.json +++ b/packages/composable-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/composable-controller", - "version": "6.0.1", + "version": "7.0.0", "description": "Consolidates the state from multiple controllers into one", "keywords": [ "MetaMask", @@ -41,11 +41,11 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2" + "@metamask/base-controller": "^6.0.0" }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/json-rpc-engine": "^9.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", @@ -57,7 +57,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/controller-utils/CHANGELOG.md b/packages/controller-utils/CHANGELOG.md index 8b33dcfa948..fbbca40d6b5 100644 --- a/packages/controller-utils/CHANGELOG.md +++ b/packages/controller-utils/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [11.0.0] + +### Added + +- Add `NFT_API_VERSION` and `NFT_API_TIMEOUT` constants ([#4312](https://github.com/MetaMask/core/pull/4312)) + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) + +### Removed + +- **BREAKING:** Remove `EthSign` from `ApprovalType` ([#4319](https://github.com/MetaMask/core/pull/4319)) + - This represented an `eth_sign` approval, but support for that RPC method is being removed, so this is no longer needed. + ## [10.0.0] ### Changed @@ -333,7 +348,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@10.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@11.0.0...HEAD +[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@10.0.0...@metamask/controller-utils@11.0.0 [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@9.1.0...@metamask/controller-utils@10.0.0 [9.1.0]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@9.0.2...@metamask/controller-utils@9.1.0 [9.0.2]: https://github.com/MetaMask/core/compare/@metamask/controller-utils@9.0.1...@metamask/controller-utils@9.0.2 diff --git a/packages/controller-utils/package.json b/packages/controller-utils/package.json index f6fa0635b20..893a4bd1f33 100644 --- a/packages/controller-utils/package.json +++ b/packages/controller-utils/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/controller-utils", - "version": "10.0.0", + "version": "11.0.0", "description": "Data and convenience functions shared by multiple packages", "keywords": [ "MetaMask", @@ -63,7 +63,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/ens-controller/CHANGELOG.md b/packages/ens-controller/CHANGELOG.md index d7b0e67a3b4..89f1a1bfabb 100644 --- a/packages/ens-controller/CHANGELOG.md +++ b/packages/ens-controller/CHANGELOG.md @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [12.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [11.0.0] + +### Changed + +- **BREAKING:** Bump peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Fixed + +- Fix `delete` method to protect against prototype-polluting assignments ([#4041](https://github.com/MetaMask/core/pull/4041) + ## [10.0.1] ### Fixed @@ -174,7 +195,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@10.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@12.0.0...HEAD +[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@11.0.0...@metamask/ens-controller@12.0.0 +[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@10.0.1...@metamask/ens-controller@11.0.0 [10.0.1]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@10.0.0...@metamask/ens-controller@10.0.1 [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@9.0.0...@metamask/ens-controller@10.0.0 [9.0.0]: https://github.com/MetaMask/core/compare/@metamask/ens-controller@8.0.0...@metamask/ens-controller@9.0.0 diff --git a/packages/ens-controller/package.json b/packages/ens-controller/package.json index f816ba74add..1bc1316b786 100644 --- a/packages/ens-controller/package.json +++ b/packages/ens-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/ens-controller", - "version": "10.0.1", + "version": "12.0.0", "description": "Maps ENS names to their resolved addresses by chain id", "keywords": [ "MetaMask", @@ -42,14 +42,14 @@ }, "dependencies": { "@ethersproject/providers": "^5.7.0", - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/utils": "^8.3.0", "punycode": "^2.1.1" }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/network-controller": "^18.1.2", + "@metamask/network-controller": "^19.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", @@ -59,10 +59,10 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.1.2" + "@metamask/network-controller": "^19.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/ens-controller/src/EnsController.test.ts b/packages/ens-controller/src/EnsController.test.ts index 9a49dfe2caf..622d370e479 100644 --- a/packages/ens-controller/src/EnsController.test.ts +++ b/packages/ens-controller/src/EnsController.test.ts @@ -1,14 +1,25 @@ import * as providersModule from '@ethersproject/providers'; import { ControllerMessenger } from '@metamask/base-controller'; import { - NetworkType, - NetworksTicker, toChecksumHexAddress, toHex, + InfuraNetworkType, } from '@metamask/controller-utils'; +import { defaultState as defaultNetworkState } from '@metamask/network-controller'; +import type { + ExtractAvailableAction, + ExtractAvailableEvent, +} from '../../base-controller/tests/helpers'; +import { + buildMockGetNetworkClientById, + buildCustomNetworkClientConfiguration, +} from '../../network-controller/tests/helpers'; import { EnsController, DEFAULT_ENS_NETWORK_MAP } from './EnsController'; -import type { EnsControllerState } from './EnsController'; +import type { + EnsControllerState, + EnsControllerMessenger, +} from './EnsController'; const defaultState: EnsControllerState = { ensEntries: {}, @@ -36,6 +47,11 @@ jest.mock('@ethersproject/providers', () => { }; }); +type RootMessenger = ControllerMessenger< + ExtractAvailableAction, + ExtractAvailableEvent +>; + const ZERO_X_ERROR_ADDRESS = '0x'; const address1 = '0x32Be343B94f860124dC4fEe278FDCBD38C102D88'; @@ -51,14 +67,28 @@ const address3Checksum = toChecksumHexAddress(address3); const name = 'EnsController'; /** - * Constructs a restricted controller messenger. + * Constructs the root messenger. + * + * @returns A restricted controller messenger. + */ +function getRootMessenger(): RootMessenger { + return new ControllerMessenger(); +} + +/** + * Constructs the messenger restricted to EnsController actions and events. * + * @param rootMessenger - The root messenger to base the restricted messenger + * off of. * @returns A restricted controller messenger. */ -function getMessenger() { - return new ControllerMessenger().getRestricted({ +function getRestrictedMessenger(rootMessenger: RootMessenger) { + return rootMessenger.getRestricted< + 'EnsController', + 'NetworkController:getNetworkClientById' + >({ name, - allowedActions: [], + allowedActions: ['NetworkController:getNetworkClientById'], allowedEvents: [], }); } @@ -74,17 +104,19 @@ function getProvider() { describe('EnsController', () => { it('should set default state', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.state).toStrictEqual(defaultState); }); it('should return registry address for `.`', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.get('0x1', '.')).toStrictEqual({ ensName: '.', @@ -94,17 +126,19 @@ describe('EnsController', () => { }); it('should not return registry address for unrecognized chains', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.get('0x666', '.')).toBeNull(); }); it('should add a new ENS entry and return true', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.state.ensEntries['0x1'][name1]).toStrictEqual({ @@ -115,9 +149,10 @@ describe('EnsController', () => { }); it('should clear ensResolutionsByAddress state propery when resetState is called', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, state: { ensResolutionsByAddress: { [address1Checksum]: 'peaksignal.eth', @@ -135,9 +170,15 @@ describe('EnsController', () => { }); it('should clear ensResolutionsByAddress state propery on networkDidChange', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, state: { ensResolutionsByAddress: { [address1Checksum]: 'peaksignal.eth', @@ -146,11 +187,8 @@ describe('EnsController', () => { provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -159,9 +197,10 @@ describe('EnsController', () => { }); it('should add a new ENS entry with null address and return true', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, null)).toBe(true); expect(controller.state.ensEntries['0x1'][name1]).toStrictEqual({ @@ -172,9 +211,10 @@ describe('EnsController', () => { }); it('should update an ENS entry and return true', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name1, address2)).toBe(true); @@ -186,9 +226,10 @@ describe('EnsController', () => { }); it('should update an ENS entry with null address and return true', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name1, null)).toBe(true); @@ -200,9 +241,10 @@ describe('EnsController', () => { }); it('should not update an ENS entry if the address is the same (valid address) and return false', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name1, address1)).toBe(false); @@ -214,9 +256,10 @@ describe('EnsController', () => { }); it('should not update an ENS entry if the address is the same (null) and return false', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, null)).toBe(true); expect(controller.set('0x1', name1, null)).toBe(false); @@ -228,9 +271,10 @@ describe('EnsController', () => { }); it('should add multiple ENS entries and update without side effects', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name2, address2)).toBe(true); @@ -254,9 +298,10 @@ describe('EnsController', () => { }); it('should get ENS default registry by chainId when asking for `.`', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.get('0x1', name1)).toStrictEqual({ @@ -267,9 +312,10 @@ describe('EnsController', () => { }); it('should get ENS entry by chainId and ensName', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.get('0x1', name1)).toStrictEqual({ @@ -280,27 +326,30 @@ describe('EnsController', () => { }); it('should return null when getting nonexistent name', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.get('0x1', name2)).toBeNull(); }); it('should return null when getting nonexistent chainId', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.get(toHex(2), name1)).toBeNull(); }); it('should throw on attempt to set invalid ENS entry: chainId', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(() => { // @ts-expect-error Intentionally invalid chain ID @@ -312,9 +361,10 @@ describe('EnsController', () => { }); it('should throw on attempt to set invalid ENS entry: ENS name', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(() => { controller.set('0x1', 'foo.eth', address1); @@ -323,9 +373,10 @@ describe('EnsController', () => { }); it('should throw on attempt to set invalid ENS entry: address', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(() => { controller.set('0x1', name1, 'foo'); @@ -336,9 +387,10 @@ describe('EnsController', () => { }); it('should remove an ENS entry and return true', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.delete('0x1', name1)).toBe(true); @@ -346,9 +398,10 @@ describe('EnsController', () => { }); it('should remove chain entries completely when all entries are removed', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.delete('0x1', '.')).toBe(true); @@ -360,9 +413,10 @@ describe('EnsController', () => { }); it('should return false if an ENS entry was NOT deleted due to unsafe input', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); // @ts-expect-error Suppressing error to test runtime behavior expect(controller.delete('__proto__', 'bar')).toBe(false); @@ -370,9 +424,10 @@ describe('EnsController', () => { }); it('should return false if an ENS entry was NOT deleted', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); controller.set('0x1', name1, address1); expect(controller.delete('0x1', 'bar')).toBe(false); @@ -385,9 +440,10 @@ describe('EnsController', () => { }); it('should add multiple ENS entries and remove without side effects', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name2, address2)).toBe(true); @@ -406,9 +462,10 @@ describe('EnsController', () => { }); it('should clear all ENS entries', () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const controller = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(controller.set('0x1', name1, address1)).toBe(true); expect(controller.set('0x1', name2, address2)).toBe(true); @@ -422,25 +479,29 @@ describe('EnsController', () => { describe('reverseResolveName', () => { it('should return undefined when eth provider is not defined', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, }); expect(await ens.reverseResolveAddress(address1)).toBeUndefined(); }); it('should return undefined when network is loading', async function () { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -448,17 +509,24 @@ describe('EnsController', () => { }); it('should return undefined when network is not ens supported', async function () { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); + const getNetworkClientById = buildMockGetNetworkClientById({ + 'AAAA-AAAA-AAAA-AAAA': buildCustomNetworkClientConfiguration({ + chainId: '0x9999999', + }), + }); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: toHex(0), - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: 'AAAA-AAAA-AAAA-AAAA', }); }, }); @@ -466,7 +534,13 @@ describe('EnsController', () => { }); it('should only resolve an ENS name once', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest.spyOn(ethProvider, 'resolveName').mockResolvedValue(address1); jest @@ -475,15 +549,12 @@ describe('EnsController', () => { jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -493,20 +564,23 @@ describe('EnsController', () => { }); it('should fail if lookupAddress through an error', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest.spyOn(ethProvider, 'lookupAddress').mockRejectedValue('error'); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -515,20 +589,23 @@ describe('EnsController', () => { }); it('should fail if lookupAddress returns a null value', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest.spyOn(ethProvider, 'lookupAddress').mockResolvedValue(null); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -537,7 +614,13 @@ describe('EnsController', () => { }); it('should fail if resolveName through an error', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest .spyOn(ethProvider, 'lookupAddress') @@ -545,15 +628,12 @@ describe('EnsController', () => { jest.spyOn(ethProvider, 'resolveName').mockRejectedValue('error'); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -562,7 +642,13 @@ describe('EnsController', () => { }); it('should fail if resolveName returns a null value', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest.spyOn(ethProvider, 'resolveName').mockResolvedValue(null); jest @@ -570,15 +656,12 @@ describe('EnsController', () => { .mockResolvedValue('peaksignal.eth'); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -587,7 +670,13 @@ describe('EnsController', () => { }); it('should fail if registred address is zero x error address', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest .spyOn(ethProvider, 'resolveName') @@ -597,15 +686,12 @@ describe('EnsController', () => { .mockResolvedValue('peaksignal.eth'); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); @@ -614,7 +700,13 @@ describe('EnsController', () => { }); it('should fail if the name is registered to a different address than the reverse resolved', async () => { - const messenger = getMessenger(); + const rootMessenger = getRootMessenger(); + const getNetworkClientById = buildMockGetNetworkClientById(); + rootMessenger.registerActionHandler( + 'NetworkController:getNetworkClientById', + getNetworkClientById, + ); + const ensControllerMessenger = getRestrictedMessenger(rootMessenger); const ethProvider = new providersModule.Web3Provider(getProvider()); jest.spyOn(ethProvider, 'resolveName').mockResolvedValue(address2); @@ -623,15 +715,12 @@ describe('EnsController', () => { .mockResolvedValue('peaksignal.eth'); jest.spyOn(providersModule, 'Web3Provider').mockReturnValue(ethProvider); const ens = new EnsController({ - messenger, + messenger: ensControllerMessenger, provider: getProvider(), onNetworkDidChange: (listener) => { listener({ - providerConfig: { - chainId: '0x1', - type: NetworkType.mainnet, - ticker: NetworksTicker.mainnet, - }, + ...defaultNetworkState, + selectedNetworkClientId: InfuraNetworkType.mainnet, }); }, }); diff --git a/packages/ens-controller/src/EnsController.ts b/packages/ens-controller/src/EnsController.ts index 898c1697c9a..7398d81018b 100644 --- a/packages/ens-controller/src/EnsController.ts +++ b/packages/ens-controller/src/EnsController.ts @@ -15,7 +15,10 @@ import { convertHexToDecimal, toHex, } from '@metamask/controller-utils'; -import type { NetworkState } from '@metamask/network-controller'; +import type { + NetworkControllerGetNetworkClientByIdAction, + NetworkState, +} from '@metamask/network-controller'; import type { Hex } from '@metamask/utils'; import { createProjectLogger } from '@metamask/utils'; import { toASCII } from 'punycode/'; @@ -69,11 +72,13 @@ export type EnsControllerState = { ensResolutionsByAddress: { [key: string]: string }; }; +type AllowedActions = NetworkControllerGetNetworkClientByIdAction; + export type EnsControllerMessenger = RestrictedControllerMessenger< typeof name, + AllowedActions, never, - never, - never, + AllowedActions['type'], never >; @@ -123,7 +128,7 @@ export class EnsController extends BaseController< state?: Partial; provider?: ExternalProvider | JsonRpcFetchFunc; onNetworkDidChange?: ( - listener: (networkState: Pick) => void, + listener: (networkState: NetworkState) => void, ) => void; }) { super({ @@ -149,9 +154,14 @@ export class EnsController extends BaseController< }); if (provider && onNetworkDidChange) { - onNetworkDidChange((networkState) => { + onNetworkDidChange(({ selectedNetworkClientId }) => { this.resetState(); - const currentChainId = networkState.providerConfig.chainId; + const selectedNetworkClient = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + selectedNetworkClientId, + ); + const currentChainId = selectedNetworkClient.configuration.chainId; + if (this.#getChainEnsSupport(currentChainId)) { this.#ethProvider = new Web3Provider(provider, { chainId: convertHexToDecimal(currentChainId), diff --git a/packages/eth-json-rpc-provider/CHANGELOG.md b/packages/eth-json-rpc-provider/CHANGELOG.md index 85cd484db9e..1e0e3ad584e 100644 --- a/packages/eth-json-rpc-provider/CHANGELOG.md +++ b/packages/eth-json-rpc-provider/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + ## [3.0.2] ### Changed @@ -100,7 +107,8 @@ Release `v2.0.0` is identical to `v1.0.1` aside from Node.js version requirement - Initial release, including `providerFromEngine` and `providerFromMiddleware`. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@3.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@4.0.0...HEAD +[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@3.0.2...@metamask/eth-json-rpc-provider@4.0.0 [3.0.2]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@3.0.1...@metamask/eth-json-rpc-provider@3.0.2 [3.0.1]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@3.0.0...@metamask/eth-json-rpc-provider@3.0.1 [3.0.0]: https://github.com/MetaMask/core/compare/@metamask/eth-json-rpc-provider@2.3.2...@metamask/eth-json-rpc-provider@3.0.0 diff --git a/packages/eth-json-rpc-provider/package.json b/packages/eth-json-rpc-provider/package.json index 7702dfdd3cf..8f70b981914 100644 --- a/packages/eth-json-rpc-provider/package.json +++ b/packages/eth-json-rpc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/eth-json-rpc-provider", - "version": "3.0.2", + "version": "4.0.0", "description": "Create an Ethereum provider using a JSON-RPC engine or middleware", "keywords": [ "MetaMask", @@ -46,7 +46,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/safe-event-emitter": "^3.0.0", "@metamask/utils": "^8.3.0" }, @@ -62,7 +62,7 @@ }, "packageManager": "yarn@3.3.0", "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/gas-fee-controller/CHANGELOG.md b/packages/gas-fee-controller/CHANGELOG.md index dfd93c08b52..19e0ef69e73 100644 --- a/packages/gas-fee-controller/CHANGELOG.md +++ b/packages/gas-fee-controller/CHANGELOG.md @@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [17.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/polling-controller` to `^8.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [16.0.0] + +### Changed + +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/polling-controller` to `^7.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [15.1.2] ### Fixed @@ -275,7 +293,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@15.1.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@17.0.0...HEAD +[17.0.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@16.0.0...@metamask/gas-fee-controller@17.0.0 +[16.0.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@15.1.2...@metamask/gas-fee-controller@16.0.0 [15.1.2]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@15.1.1...@metamask/gas-fee-controller@15.1.2 [15.1.1]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@15.1.0...@metamask/gas-fee-controller@15.1.1 [15.1.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@15.0.0...@metamask/gas-fee-controller@15.1.0 diff --git a/packages/gas-fee-controller/package.json b/packages/gas-fee-controller/package.json index c346c340381..61c1093a9dc 100644 --- a/packages/gas-fee-controller/package.json +++ b/packages/gas-fee-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/gas-fee-controller", - "version": "15.1.2", + "version": "17.0.0", "description": "Periodically calculates gas fee estimates based on various gas limits as well as other data displayed on transaction confirm screens", "keywords": [ "MetaMask", @@ -41,12 +41,12 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-query": "^4.0.0", "@metamask/ethjs-unit": "^0.3.0", - "@metamask/network-controller": "^18.1.2", - "@metamask/polling-controller": "^6.0.2", + "@metamask/network-controller": "^19.0.0", + "@metamask/polling-controller": "^8.0.0", "@metamask/utils": "^8.3.0", "@types/bn.js": "^5.1.5", "@types/uuid": "^8.3.0", @@ -67,10 +67,10 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.1.2" + "@metamask/network-controller": "^19.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/gas-fee-controller/src/GasFeeController.test.ts b/packages/gas-fee-controller/src/GasFeeController.test.ts index e1c0fa4cca3..7987a6adc98 100644 --- a/packages/gas-fee-controller/src/GasFeeController.test.ts +++ b/packages/gas-fee-controller/src/GasFeeController.test.ts @@ -2,7 +2,6 @@ import { ControllerMessenger } from '@metamask/base-controller'; import { ChainId, convertHexToDecimal, - NetworkType, toHex, } from '@metamask/controller-utils'; import EthQuery from '@metamask/eth-query'; @@ -64,10 +63,12 @@ const setupNetworkController = async ({ unrestrictedMessenger, state, clock, + initializeProvider = true, }: { unrestrictedMessenger: MainControllerMessenger; state: Partial; clock: sinon.SinonFakeTimers; + initializeProvider?: boolean; }) => { const restrictedMessenger = unrestrictedMessenger.getRestricted({ name: 'NetworkController', @@ -81,12 +82,15 @@ const setupNetworkController = async ({ infuraProjectId: '123', trackMetaMetricsEvent: jest.fn(), }); - // Call this without awaiting to simulate what the extension or mobile app - // might do - networkController.initializeProvider(); - // Ensure that the request for eth_getBlockByNumber made by the PollingBlockTracker - // inside the NetworkController goes through - await clock.nextAsync(); + + if (initializeProvider) { + // Call this without awaiting to simulate what the extension or mobile app + // might do + networkController.initializeProvider(); + // Ensure that the request for eth_getBlockByNumber made by the PollingBlockTracker + // inside the NetworkController goes through + await clock.nextAsync(); + } return networkController; }; @@ -228,6 +232,8 @@ describe('GasFeeController', () => { * @param options.interval - The polling interval. * @param options.state - The initial GasFeeController state * @param options.infuraAPIKey - The Infura API key. + * @param options.initializeNetworkProvider - Whether to instruct the + * NetworkController to initialize its provider. */ async function setupGasFeeController({ getIsEIP1559Compatible = jest.fn().mockResolvedValue(true), @@ -241,6 +247,7 @@ describe('GasFeeController', () => { networkControllerState = {}, state, interval, + initializeNetworkProvider = true, }: { getChainId?: jest.Mock; onNetworkDidChange?: jest.Mock; @@ -251,12 +258,14 @@ describe('GasFeeController', () => { state?: GasFeeState; interval?: number; infuraAPIKey?: string; + initializeNetworkProvider?: boolean; } = {}) { const controllerMessenger = getControllerMessenger(); networkController = await setupNetworkController({ unrestrictedMessenger: controllerMessenger, state: networkControllerState, clock, + initializeProvider: initializeNetworkProvider, }); const messenger = getRestrictedMessenger(controllerMessenger); gasFeeController = new GasFeeController({ @@ -323,14 +332,24 @@ describe('GasFeeController', () => { .fn() .mockReturnValue(true), networkControllerState: { - providerConfig: { - type: NetworkType.rpc, - chainId: toHex(1337), - rpcUrl: 'http://some/url', - ticker: 'TEST', + networkConfigurations: { + 'AAAA-BBBB-CCCC-DDDD': { + id: 'AAAA-BBBB-CCCC-DDDD', + chainId: toHex(1337), + rpcUrl: 'http://some/url', + ticker: 'TEST', + }, }, + selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }, clientId: '99999', + // Currently initializing the provider overwrites the + // `selectedNetworkClientId` we specify above based on whatever + // `providerConfig` is. So we prevent the provider from being + // initialized to make this test pass. Once `providerConfig` is + // removed, then we don't need this anymore and + // `selectedNetworkClientId` should no longer be overwritten. + initializeNetworkProvider: false, }); await gasFeeController.getGasFeeEstimatesAndStartPolling(undefined); @@ -377,14 +396,24 @@ describe('GasFeeController', () => { .fn() .mockReturnValue(true), networkControllerState: { - providerConfig: { - type: NetworkType.rpc, - chainId: toHex(1337), - rpcUrl: 'http://some/url', - ticker: 'TEST', + networkConfigurations: { + 'AAAA-BBBB-CCCC-DDDD': { + id: 'AAAA-BBBB-CCCC-DDDD', + chainId: toHex(1337), + rpcUrl: 'http://some/url', + ticker: 'TEST', + }, }, + selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }, clientId: '99999', + // Currently initializing the provider overwrites the + // `selectedNetworkClientId` we specify above based on whatever + // `providerConfig` is. So we prevent the provider from being + // initialized to make this test pass. Once `providerConfig` is + // removed, then we don't need this anymore and + // `selectedNetworkClientId` should no longer be overwritten. + initializeNetworkProvider: false, }); await gasFeeController.getGasFeeEstimatesAndStartPolling( @@ -716,14 +745,24 @@ describe('GasFeeController', () => { await setupGasFeeController({ ...defaultConstructorOptions, networkControllerState: { - providerConfig: { - type: NetworkType.rpc, - chainId: toHex(1337), - rpcUrl: 'http://some/url', - ticker: 'TEST', + networkConfigurations: { + 'AAAA-BBBB-CCCC-DDDD': { + id: 'AAAA-BBBB-CCCC-DDDD', + chainId: toHex(1337), + rpcUrl: 'http://some/url', + ticker: 'TEST', + }, }, + selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }, clientId: '99999', + // Currently initializing the provider overwrites the + // `selectedNetworkClientId` we specify above based on whatever + // `providerConfig` is. So we prevent the provider from being + // initialized to make this test pass. Once `providerConfig` is + // removed, then we don't need this anymore and + // `selectedNetworkClientId` should no longer be overwritten. + initializeNetworkProvider: false, }); await gasFeeController.fetchGasFeeEstimates(); @@ -860,14 +899,24 @@ describe('GasFeeController', () => { await setupGasFeeController({ ...defaultConstructorOptions, networkControllerState: { - providerConfig: { - type: NetworkType.rpc, - chainId: toHex(1337), - rpcUrl: 'http://some/url', - ticker: 'TEST', + networkConfigurations: { + 'AAAA-BBBB-CCCC-DDDD': { + id: 'AAAA-BBBB-CCCC-DDDD', + chainId: toHex(1337), + rpcUrl: 'http://some/url', + ticker: 'TEST', + }, }, + selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }, clientId: '99999', + // Currently initializing the provider overwrites the + // `selectedNetworkClientId` we specify above based on whatever + // `providerConfig` is. So we prevent the provider from being + // initialized to make this test pass. Once `providerConfig` is + // removed, then we don't need this anymore and + // `selectedNetworkClientId` should no longer be overwritten. + initializeNetworkProvider: false, }); await gasFeeController.fetchGasFeeEstimates(); diff --git a/packages/gas-fee-controller/src/GasFeeController.ts b/packages/gas-fee-controller/src/GasFeeController.ts index 43da8894d48..0dce8d33446 100644 --- a/packages/gas-fee-controller/src/GasFeeController.ts +++ b/packages/gas-fee-controller/src/GasFeeController.ts @@ -363,9 +363,13 @@ export class GasFeeController extends StaticIntervalPollingController< await this.#onNetworkControllerDidChange(networkControllerState); }); } else { - this.currentChainId = this.messagingSystem.call( + const { selectedNetworkClientId } = this.messagingSystem.call( 'NetworkController:getState', - ).providerConfig.chainId; + ); + this.currentChainId = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + selectedNetworkClientId, + ).configuration.chainId; this.messagingSystem.subscribe( 'NetworkController:networkDidChange', async (networkControllerState) => { @@ -586,8 +590,13 @@ export class GasFeeController extends StaticIntervalPollingController< ); } - async #onNetworkControllerDidChange(networkControllerState: NetworkState) { - const newChainId = networkControllerState.providerConfig.chainId; + async #onNetworkControllerDidChange({ + selectedNetworkClientId, + }: NetworkState) { + const newChainId = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + selectedNetworkClientId, + ).configuration.chainId; if (newChainId !== this.currentChainId) { this.ethQuery = new EthQuery(this.#getProvider()); diff --git a/packages/json-rpc-engine/CHANGELOG.md b/packages/json-rpc-engine/CHANGELOG.md index 5a60611ac3d..f160e2264a3 100644 --- a/packages/json-rpc-engine/CHANGELOG.md +++ b/packages/json-rpc-engine/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [9.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) + ## [8.0.2] ### Changed @@ -156,7 +162,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 This change may affect consumers that depend on the eager execution of middleware _during_ request processing, _outside of_ middleware functions and request handlers. - In general, it is a bad practice to work with state that depends on middleware execution, while the middleware are executing. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@8.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@9.0.0...HEAD +[9.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@8.0.2...@metamask/json-rpc-engine@9.0.0 [8.0.2]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@8.0.1...@metamask/json-rpc-engine@8.0.2 [8.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@8.0.0...@metamask/json-rpc-engine@8.0.1 [8.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-engine@7.3.3...@metamask/json-rpc-engine@8.0.0 diff --git a/packages/json-rpc-engine/package.json b/packages/json-rpc-engine/package.json index 642a6496042..f306669f9a5 100644 --- a/packages/json-rpc-engine/package.json +++ b/packages/json-rpc-engine/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/json-rpc-engine", - "version": "8.0.2", + "version": "9.0.0", "description": "A tool for processing JSON-RPC messages", "keywords": [ "MetaMask", @@ -67,7 +67,7 @@ }, "packageManager": "yarn@3.3.0", "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/json-rpc-middleware-stream/CHANGELOG.md b/packages/json-rpc-middleware-stream/CHANGELOG.md index 23f4e566e55..c72854d0141 100644 --- a/packages/json-rpc-middleware-stream/CHANGELOG.md +++ b/packages/json-rpc-middleware-stream/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [7.0.2] + +### Changed + +- Bump `@metamask/json-rpc-engine` to `^8.0.2` ([#4234](https://github.com/MetaMask/core/pull/4234)) + ## [7.0.1] ### Fixed @@ -116,7 +129,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - TypeScript typings ([#11](https://github.com/MetaMask/json-rpc-middleware-stream/pull/11)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@7.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@8.0.0...HEAD +[8.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@7.0.2...@metamask/json-rpc-middleware-stream@8.0.0 +[7.0.2]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@7.0.1...@metamask/json-rpc-middleware-stream@7.0.2 [7.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@7.0.0...@metamask/json-rpc-middleware-stream@7.0.1 [7.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@6.0.2...@metamask/json-rpc-middleware-stream@7.0.0 [6.0.2]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@6.0.1...@metamask/json-rpc-middleware-stream@6.0.2 diff --git a/packages/json-rpc-middleware-stream/package.json b/packages/json-rpc-middleware-stream/package.json index d93179aed7a..88d92353c62 100644 --- a/packages/json-rpc-middleware-stream/package.json +++ b/packages/json-rpc-middleware-stream/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/json-rpc-middleware-stream", - "version": "7.0.1", + "version": "8.0.0", "description": "A small toolset for streaming JSON-RPC data and matching requests and responses", "keywords": [ "MetaMask", @@ -41,7 +41,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/safe-event-emitter": "^3.0.0", "@metamask/utils": "^8.3.0", "readable-stream": "^3.6.2" @@ -61,7 +61,7 @@ "webextension-polyfill-ts": "^0.26.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/keyring-controller/CHANGELOG.md b/packages/keyring-controller/CHANGELOG.md index 3ed83289cb7..7d7dd3d8fe2 100644 --- a/packages/keyring-controller/CHANGELOG.md +++ b/packages/keyring-controller/CHANGELOG.md @@ -7,10 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [17.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/message-manager` to `^10.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [16.1.0] + ### Added -- Added `changePassword` method ([#4279](https://github.com/MetaMask/core/pull/4279)) - - This method can be used to change the password used to encrypt the vault +- Add `changePassword` method ([#4279](https://github.com/MetaMask/core/pull/4279)) + - This method can be used to change the password used to encrypt the vault. +- Add support for non-EVM account addresses to most methods ([#4282](https://github.com/MetaMask/core/pull/4282)) + - Previously, all addresses were assumed to be Ethereum addresses and normalized, but now only Ethereum addresses are treated as such. + - Relax type of `account` argument on `removeAccount` from `Hex` to `string` + +### Changed + +- Bump `@metamask/keyring-api` to `^6.1.1` ([#4262](https://github.com/MetaMask/core/pull/4262)) +- Bump `@keystonehq/metamask-airgapped-keyring` to `^0.14.1` ([#4277](https://github.com/MetaMask/core/pull/4277)) +- Bump `async-mutex` to `^0.5.0` ([#4335](https://github.com/MetaMask/core/pull/4335)) +- Bump `@metamask/message-manager` to `^9.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Fixed + +- Fix QR keyrings so that they are not initialized with invalid state ([#4256](https://github.com/MetaMask/core/pull/4256)) ## [16.0.0] @@ -445,7 +469,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@16.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@17.0.0...HEAD +[17.0.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@16.1.0...@metamask/keyring-controller@17.0.0 +[16.1.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@16.0.0...@metamask/keyring-controller@16.1.0 [16.0.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@15.0.0...@metamask/keyring-controller@16.0.0 [15.0.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@14.0.1...@metamask/keyring-controller@15.0.0 [14.0.1]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@14.0.0...@metamask/keyring-controller@14.0.1 diff --git a/packages/keyring-controller/package.json b/packages/keyring-controller/package.json index a8d5ed6c9e4..68520c71b60 100644 --- a/packages/keyring-controller/package.json +++ b/packages/keyring-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/keyring-controller", - "version": "16.0.0", + "version": "17.0.0", "description": "Stores identities seen in the wallet and manages interactions such as signing", "keywords": [ "MetaMask", @@ -43,13 +43,13 @@ "dependencies": { "@ethereumjs/util": "^8.1.0", "@keystonehq/metamask-airgapped-keyring": "^0.14.1", - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/browser-passworder": "^4.3.0", "@metamask/eth-hd-keyring": "^7.0.1", "@metamask/eth-sig-util": "^7.0.1", "@metamask/eth-simple-keyring": "^6.0.1", - "@metamask/keyring-api": "^6.1.1", - "@metamask/message-manager": "^8.0.2", + "@metamask/keyring-api": "^6.4.0", + "@metamask/message-manager": "^10.0.0", "@metamask/utils": "^8.3.0", "async-mutex": "^0.5.0", "ethereumjs-wallet": "^1.0.1", @@ -74,7 +74,7 @@ "uuid": "^8.3.2" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/keyring-controller/src/KeyringController.test.ts b/packages/keyring-controller/src/KeyringController.test.ts index 018c1365392..48b1130f61b 100644 --- a/packages/keyring-controller/src/KeyringController.test.ts +++ b/packages/keyring-controller/src/KeyringController.test.ts @@ -11,6 +11,7 @@ import { SignTypedDataVersion, encrypt, } from '@metamask/eth-sig-util'; +import SimpleKeyring from '@metamask/eth-simple-keyring/dist/simple-keyring'; import type { EthKeyring } from '@metamask/keyring-api'; import { wordlist } from '@metamask/scure-bip39/dist/wordlists/english'; import type { KeyringClass } from '@metamask/utils'; @@ -100,6 +101,32 @@ describe('KeyringController', () => { }), ).toThrow(KeyringControllerError.UnsupportedEncryptionKeyExport); }); + + it('allows overwriting the built-in Simple keyring builder', async () => { + const mockSimpleKeyringBuilder = + // @ts-expect-error The simple keyring doesn't yet conform to the KeyringClass type + buildKeyringBuilderWithSpy(SimpleKeyring); + await withController( + { keyringBuilders: [mockSimpleKeyringBuilder] }, + async ({ controller }) => { + await controller.addNewKeyring(KeyringTypes.simple); + + expect(mockSimpleKeyringBuilder).toHaveBeenCalledTimes(1); + }, + ); + }); + + it('allows overwriting the built-in HD keyring builder', async () => { + const mockHdKeyringBuilder = buildKeyringBuilderWithSpy(HDKeyring); + await withController( + { keyringBuilders: [mockHdKeyringBuilder] }, + async () => { + // This is called as part of initializing the controller + // because the first keyring is assumed to always be an HD keyring + expect(mockHdKeyringBuilder).toHaveBeenCalledTimes(1); + }, + ); + }); }); describe('addNewAccount', () => { @@ -3538,3 +3565,21 @@ async function withController( messenger, }); } + +/** + * Construct a keyring builder with a spy. + * + * @param KeyringConstructor - The constructor to use for building the keyring. + * @returns A keyring builder that uses `jest.fn()` to spy on invocations. + */ +function buildKeyringBuilderWithSpy(KeyringConstructor: KeyringClass): { + (): EthKeyring; + type: string; +} { + const keyringBuilderWithSpy: { (): EthKeyring; type?: string } = jest + .fn() + .mockImplementation((...args) => new KeyringConstructor(...args)); + keyringBuilderWithSpy.type = KeyringConstructor.type; + // Not sure why TypeScript isn't smart enough to infer that `type` is set here. + return keyringBuilderWithSpy as { (): EthKeyring; type: string }; +} diff --git a/packages/keyring-controller/src/KeyringController.ts b/packages/keyring-controller/src/KeyringController.ts index 1d657295adf..4979f4f7e05 100644 --- a/packages/keyring-controller/src/KeyringController.ts +++ b/packages/keyring-controller/src/KeyringController.ts @@ -611,7 +611,7 @@ export class KeyringController extends BaseController< }); this.#keyringBuilders = keyringBuilders - ? defaultKeyringBuilders.concat(keyringBuilders) + ? keyringBuilders.concat(defaultKeyringBuilders) : defaultKeyringBuilders; this.#encryptor = encryptor; diff --git a/packages/logging-controller/CHANGELOG.md b/packages/logging-controller/CHANGELOG.md index be46c8c4756..006f42b4e09 100644 --- a/packages/logging-controller/CHANGELOG.md +++ b/packages/logging-controller/CHANGELOG.md @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [4.0.0] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove `EthSign` from `SigningMethod` ([#4319](https://github.com/MetaMask/core/pull/4319)) + ## [3.0.1] ### Fixed @@ -87,7 +106,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial Release - Add logging controller ([#1089](https://github.com/MetaMask/core.git/pull/1089)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@3.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@5.0.0...HEAD +[5.0.0]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@4.0.0...@metamask/logging-controller@5.0.0 +[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@3.0.1...@metamask/logging-controller@4.0.0 [3.0.1]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@3.0.0...@metamask/logging-controller@3.0.1 [3.0.0]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@2.0.3...@metamask/logging-controller@3.0.0 [2.0.3]: https://github.com/MetaMask/core/compare/@metamask/logging-controller@2.0.2...@metamask/logging-controller@2.0.3 diff --git a/packages/logging-controller/package.json b/packages/logging-controller/package.json index b5248c2e34f..5abe098c4f9 100644 --- a/packages/logging-controller/package.json +++ b/packages/logging-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/logging-controller", - "version": "3.0.1", + "version": "5.0.0", "description": "Manages logging data to assist users and support staff", "keywords": [ "MetaMask", @@ -41,8 +41,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "uuid": "^8.3.2" }, "devDependencies": { @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/message-manager/CHANGELOG.md b/packages/message-manager/CHANGELOG.md index 5c1c1afacd4..1cb9b3b848c 100644 --- a/packages/message-manager/CHANGELOG.md +++ b/packages/message-manager/CHANGELOG.md @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [9.0.0] + +### Changed + +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove `Message`, `MessageParams`, `MessageParamsMetamask`, and `MessageManager` ([#4319](https://github.com/MetaMask/core/pull/4319)) + - Support for `eth_sign` is being removed, so these are no longer needed. + ## [8.0.2] ### Changed @@ -236,7 +255,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/message-manager@8.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/message-manager@10.0.0...HEAD +[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/message-manager@9.0.0...@metamask/message-manager@10.0.0 +[9.0.0]: https://github.com/MetaMask/core/compare/@metamask/message-manager@8.0.2...@metamask/message-manager@9.0.0 [8.0.2]: https://github.com/MetaMask/core/compare/@metamask/message-manager@8.0.1...@metamask/message-manager@8.0.2 [8.0.1]: https://github.com/MetaMask/core/compare/@metamask/message-manager@8.0.0...@metamask/message-manager@8.0.1 [8.0.0]: https://github.com/MetaMask/core/compare/@metamask/message-manager@7.3.9...@metamask/message-manager@8.0.0 diff --git a/packages/message-manager/package.json b/packages/message-manager/package.json index 1d436c727c1..efbffd04d75 100644 --- a/packages/message-manager/package.json +++ b/packages/message-manager/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/message-manager", - "version": "8.0.2", + "version": "10.0.0", "description": "Stores and manages interactions with signing requests", "keywords": [ "MetaMask", @@ -41,8 +41,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-sig-util": "^7.0.1", "@metamask/utils": "^8.3.0", "@types/uuid": "^8.3.0", @@ -60,7 +60,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/name-controller/CHANGELOG.md b/packages/name-controller/CHANGELOG.md index ee62ff7c765..1d76978d497 100644 --- a/packages/name-controller/CHANGELOG.md +++ b/packages/name-controller/CHANGELOG.md @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [7.0.0] + +### Changed + +- **BREAKING:** Changed token API endpoint from `*.metafi.codefi.network` to `*.api.cx.metamask.io` ([#4301](https://github.com/MetaMask/core/pull/4301)) +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) +- Bump `async-mutex` to `^0.5.0` ([#4335](https://github.com/MetaMask/core/pull/4335)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Fixed + +- Fix `setName` and `updateProposedNames` methods to protect against prototype-polluting assignments ([#4041](https://github.com/MetaMask/core/pull/4041) + ## [6.0.1] ### Fixed @@ -100,7 +121,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial Release ([#1647](https://github.com/MetaMask/core/pull/1647)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/name-controller@6.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/name-controller@8.0.0...HEAD +[8.0.0]: https://github.com/MetaMask/core/compare/@metamask/name-controller@7.0.0...@metamask/name-controller@8.0.0 +[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/name-controller@6.0.1...@metamask/name-controller@7.0.0 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/name-controller@6.0.0...@metamask/name-controller@6.0.1 [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/name-controller@5.0.0...@metamask/name-controller@6.0.0 [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/name-controller@4.2.0...@metamask/name-controller@5.0.0 diff --git a/packages/name-controller/package.json b/packages/name-controller/package.json index c8acf9e8ff3..01fe50988e8 100644 --- a/packages/name-controller/package.json +++ b/packages/name-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/name-controller", - "version": "6.0.1", + "version": "8.0.0", "description": "Stores and suggests names for values such as Ethereum addresses", "keywords": [ "MetaMask", @@ -42,8 +42,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/utils": "^8.3.0", "async-mutex": "^0.5.0" }, @@ -58,7 +58,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/network-controller/CHANGELOG.md b/packages/network-controller/CHANGELOG.md index 1da5a057efc..8e76f49010c 100644 --- a/packages/network-controller/CHANGELOG.md +++ b/packages/network-controller/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [19.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/eth-json-rpc-provider` to `^4.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [18.1.3] + +### Changed + +- Bump `async-mutex` to `^0.5.0` ([#4335](https://github.com/MetaMask/core/pull/4335)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [18.1.2] ### Fixed @@ -488,7 +505,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-controller@19.0.0...HEAD +[19.0.0]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.3...@metamask/network-controller@19.0.0 +[18.1.3]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.2...@metamask/network-controller@18.1.3 [18.1.2]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.1...@metamask/network-controller@18.1.2 [18.1.1]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.0...@metamask/network-controller@18.1.1 [18.1.0]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.0.1...@metamask/network-controller@18.1.0 diff --git a/packages/network-controller/package.json b/packages/network-controller/package.json index cbbff986a54..b720f8f4b66 100644 --- a/packages/network-controller/package.json +++ b/packages/network-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/network-controller", - "version": "18.1.2", + "version": "19.0.0", "description": "Provides an interface to the currently selected network via a MetaMask-compatible provider object", "keywords": [ "MetaMask", @@ -41,14 +41,14 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-block-tracker": "^9.0.2", "@metamask/eth-json-rpc-infura": "^9.1.0", "@metamask/eth-json-rpc-middleware": "^12.1.1", - "@metamask/eth-json-rpc-provider": "^3.0.2", + "@metamask/eth-json-rpc-provider": "^4.0.0", "@metamask/eth-query": "^4.0.0", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/swappable-obj-proxy": "^2.2.0", "@metamask/utils": "^8.3.0", @@ -74,7 +74,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/network-controller/tests/helpers.ts b/packages/network-controller/tests/helpers.ts index 3a686cb9c84..c7072665ea2 100644 --- a/packages/network-controller/tests/helpers.ts +++ b/packages/network-controller/tests/helpers.ts @@ -127,10 +127,12 @@ export function buildMockGetNetworkClientById( * of an Infura network. * * @param network - The name of an Infura network. - * @returns the Infura network client configuration. + * @param overrides - Properties to merge into the configuration object. + * @returns the complete Infura network client configuration. */ export function buildInfuraNetworkClientConfiguration( network: InfuraNetworkType, + overrides: Partial = {}, ): InfuraNetworkClientConfiguration { return { type: NetworkClientType.Infura, @@ -138,6 +140,7 @@ export function buildInfuraNetworkClientConfiguration( infuraProjectId: 'test-infura-project-id', chainId: BUILT_IN_NETWORKS[network].chainId, ticker: BUILT_IN_NETWORKS[network].ticker, + ...overrides, }; } diff --git a/packages/notification-controller/CHANGELOG.md b/packages/notification-controller/CHANGELOG.md index 84a27603167..182d9021cc5 100644 --- a/packages/notification-controller/CHANGELOG.md +++ b/packages/notification-controller/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [5.0.2] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) + ## [5.0.1] ### Fixed @@ -110,7 +123,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@5.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@6.0.0...HEAD +[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@5.0.2...@metamask/notification-controller@6.0.0 +[5.0.2]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@5.0.1...@metamask/notification-controller@5.0.2 [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@5.0.0...@metamask/notification-controller@5.0.1 [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@4.0.2...@metamask/notification-controller@5.0.0 [4.0.2]: https://github.com/MetaMask/core/compare/@metamask/notification-controller@4.0.1...@metamask/notification-controller@4.0.2 diff --git a/packages/notification-controller/package.json b/packages/notification-controller/package.json index 0d8365856e7..a95c51a01b7 100644 --- a/packages/notification-controller/package.json +++ b/packages/notification-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/notification-controller", - "version": "5.0.1", + "version": "6.0.0", "description": "Manages display of notifications within MetaMask", "keywords": [ "MetaMask", @@ -41,7 +41,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/utils": "^8.3.0", "nanoid": "^3.1.31" }, @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/permission-controller/CHANGELOG.md b/packages/permission-controller/CHANGELOG.md index 146a959f9b8..c768e0c80d1 100644 --- a/packages/permission-controller/CHANGELOG.md +++ b/packages/permission-controller/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump peer dependency `@metamask/approval-controller` to `^7.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [9.1.1] + +### Changed + +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [9.1.0] ### Added @@ -226,7 +242,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@10.0.0...HEAD +[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.1.1...@metamask/permission-controller@10.0.0 +[9.1.1]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.1.0...@metamask/permission-controller@9.1.1 [9.1.0]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.0.2...@metamask/permission-controller@9.1.0 [9.0.2]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.0.1...@metamask/permission-controller@9.0.2 [9.0.1]: https://github.com/MetaMask/core/compare/@metamask/permission-controller@9.0.0...@metamask/permission-controller@9.0.1 diff --git a/packages/permission-controller/package.json b/packages/permission-controller/package.json index 4c5f91240d8..eaff8633b69 100644 --- a/packages/permission-controller/package.json +++ b/packages/permission-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/permission-controller", - "version": "9.1.0", + "version": "10.0.0", "description": "Mediates access to JSON-RPC methods, used to interact with pieces of the MetaMask stack, via middleware for json-rpc-engine", "keywords": [ "MetaMask", @@ -41,9 +41,9 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", "@types/deep-freeze-strict": "^1.1.0", @@ -52,7 +52,7 @@ "nanoid": "^3.1.31" }, "devDependencies": { - "@metamask/approval-controller": "^6.0.2", + "@metamask/approval-controller": "^7.0.0", "@metamask/auto-changelog": "^3.4.4", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", @@ -63,10 +63,10 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/approval-controller": "^6.0.0" + "@metamask/approval-controller": "^7.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/permission-log-controller/CHANGELOG.md b/packages/permission-log-controller/CHANGELOG.md index a49564a432c..ad1ff6dd12d 100644 --- a/packages/permission-log-controller/CHANGELOG.md +++ b/packages/permission-log-controller/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [2.0.2] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4234](https://github.com/MetaMask/core/pull/4234)) +- Bump `@metamask/json-rpc-engine` to `^8.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) + ## [2.0.1] ### Fixed @@ -32,7 +47,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@2.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@3.0.0...HEAD +[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@2.0.2...@metamask/permission-log-controller@3.0.0 +[2.0.2]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@2.0.1...@metamask/permission-log-controller@2.0.2 [2.0.1]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@2.0.0...@metamask/permission-log-controller@2.0.1 [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/permission-log-controller@1.0.0...@metamask/permission-log-controller@2.0.0 [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/permission-log-controller@1.0.0 diff --git a/packages/permission-log-controller/package.json b/packages/permission-log-controller/package.json index 76b31562d1e..73101114062 100644 --- a/packages/permission-log-controller/package.json +++ b/packages/permission-log-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/permission-log-controller", - "version": "2.0.1", + "version": "3.0.0", "description": "Controller with middleware for logging requests and responses to restricted and permissions-related methods", "keywords": [ "MetaMask", @@ -41,8 +41,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/base-controller": "^6.0.0", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/utils": "^8.3.0" }, "devDependencies": { @@ -59,7 +59,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/phishing-controller/CHANGELOG.md b/packages/phishing-controller/CHANGELOG.md index d3c15c4dadb..4c881275771 100644 --- a/packages/phishing-controller/CHANGELOG.md +++ b/packages/phishing-controller/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [9.0.4] + +### Changed + +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [9.0.3] ### Changed @@ -184,7 +198,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.3...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@10.0.0...HEAD +[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.4...@metamask/phishing-controller@10.0.0 +[9.0.4]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.3...@metamask/phishing-controller@9.0.4 [9.0.3]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.2...@metamask/phishing-controller@9.0.3 [9.0.2]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.1...@metamask/phishing-controller@9.0.2 [9.0.1]: https://github.com/MetaMask/core/compare/@metamask/phishing-controller@9.0.0...@metamask/phishing-controller@9.0.1 diff --git a/packages/phishing-controller/package.json b/packages/phishing-controller/package.json index 3b76b03224b..c45dab905e1 100644 --- a/packages/phishing-controller/package.json +++ b/packages/phishing-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/phishing-controller", - "version": "9.0.3", + "version": "10.0.0", "description": "Maintains a periodically updated list of approved and unapproved website origins", "keywords": [ "MetaMask", @@ -41,8 +41,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@types/punycode": "^2.1.0", "eth-phishing-detect": "^1.2.0", "punycode": "^2.1.1" @@ -60,7 +60,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/polling-controller/CHANGELOG.md b/packages/polling-controller/CHANGELOG.md index 5361880df4f..35d0580fb3e 100644 --- a/packages/polling-controller/CHANGELOG.md +++ b/packages/polling-controller/CHANGELOG.md @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [7.0.0] + +### Changed + +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Fixed + +- `StaticIntervalPollingControllerOnly`, `StaticIntervalPollingController`, and `StaticIntervalPollingControllerV1` now properly stops polling when a stop is requested while `_executePoll` has not yet resolved for the current loop ([#4230](https://github.com/MetaMask/core/pull/4230)) + ## [6.0.2] ### Changed @@ -123,7 +143,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@6.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@8.0.0...HEAD +[8.0.0]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@7.0.0...@metamask/polling-controller@8.0.0 +[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@6.0.2...@metamask/polling-controller@7.0.0 [6.0.2]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@6.0.1...@metamask/polling-controller@6.0.2 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@6.0.0...@metamask/polling-controller@6.0.1 [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/polling-controller@5.0.1...@metamask/polling-controller@6.0.0 diff --git a/packages/polling-controller/package.json b/packages/polling-controller/package.json index 8d8ab0916f6..7e312b70a01 100644 --- a/packages/polling-controller/package.json +++ b/packages/polling-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/polling-controller", - "version": "6.0.2", + "version": "8.0.0", "description": "Polling Controller is the base for controllers that polling by networkClientId", "keywords": [ "MetaMask", @@ -41,9 +41,9 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", - "@metamask/network-controller": "^18.1.2", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", + "@metamask/network-controller": "^19.0.0", "@metamask/utils": "^8.3.0", "@types/uuid": "^8.3.0", "fast-json-stable-stringify": "^2.1.0", @@ -61,10 +61,10 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.1.2" + "@metamask/network-controller": "^19.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/preferences-controller/CHANGELOG.md b/packages/preferences-controller/CHANGELOG.md index 06b1701ba4a..00f62607e9b 100644 --- a/packages/preferences-controller/CHANGELOG.md +++ b/packages/preferences-controller/CHANGELOG.md @@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [13.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump peer dependency `@metamask/keyring-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [12.0.0] + +### Added + +- Add `smartTransactionsOptInStatus` preference ([#3815](https://github.com/MetaMask/core/pull/3815)) + - Add `smartTransactionsOptInStatus` property to the `PreferencesController` state (default: `false`) + - Add `setSmartTransactionOptInStatus` method to set this property +- Add `useTransactionSimulations` preference ([#4283](https://github.com/MetaMask/core/pull/4283)) + - Add `useTransactionSimulations` property to the `PreferencesController` state (default value: `false`) + - Add `setUseTransactionSimulations` method to set this property + +### Changed + +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove state property `disabledRpcMethodPreferences` along with `setDisabledRpcMethodPreferences` method ([#4319](https://github.com/MetaMask/core/pull/4319)) + - These were for disabling the `eth_sign` RPC method, but support for this method is being removed, so this preference is no longer needed. + ## [11.0.0] ### Added @@ -219,7 +248,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@11.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@13.0.0...HEAD +[13.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@12.0.0...@metamask/preferences-controller@13.0.0 +[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@11.0.0...@metamask/preferences-controller@12.0.0 [11.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@10.0.0...@metamask/preferences-controller@11.0.0 [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@9.0.1...@metamask/preferences-controller@10.0.0 [9.0.1]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@9.0.0...@metamask/preferences-controller@9.0.1 diff --git a/packages/preferences-controller/package.json b/packages/preferences-controller/package.json index bc3c3bc87c5..d136b52d6d4 100644 --- a/packages/preferences-controller/package.json +++ b/packages/preferences-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/preferences-controller", - "version": "11.0.0", + "version": "13.0.0", "description": "Manages user-configurable settings for MetaMask", "keywords": [ "MetaMask", @@ -41,12 +41,12 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0" + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0" }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^16.0.0", + "@metamask/keyring-controller": "^17.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", @@ -57,10 +57,10 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/keyring-controller": "^16.0.0" + "@metamask/keyring-controller": "^17.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/profile-sync-controller/package.json b/packages/profile-sync-controller/package.json index 20a0289d309..3a2ea77c52b 100644 --- a/packages/profile-sync-controller/package.json +++ b/packages/profile-sync-controller/package.json @@ -59,7 +59,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/queued-request-controller/CHANGELOG.md b/packages/queued-request-controller/CHANGELOG.md index e51e9511378..d714aae7a93 100644 --- a/packages/queued-request-controller/CHANGELOG.md +++ b/packages/queued-request-controller/CHANGELOG.md @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.12.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump peer dependency `@metamask/selected-network-controller` to `^15.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [0.11.0] + +### Changed + +- **BREAKING:** Bump peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/selected-network-controller` to `^14.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [0.10.0] ### Changed @@ -181,7 +200,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.10.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.12.0...HEAD +[0.12.0]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.11.0...@metamask/queued-request-controller@0.12.0 +[0.11.0]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.10.0...@metamask/queued-request-controller@0.11.0 [0.10.0]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.9.0...@metamask/queued-request-controller@0.10.0 [0.9.0]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.8.0...@metamask/queued-request-controller@0.9.0 [0.8.0]: https://github.com/MetaMask/core/compare/@metamask/queued-request-controller@0.7.0...@metamask/queued-request-controller@0.8.0 diff --git a/packages/queued-request-controller/package.json b/packages/queued-request-controller/package.json index 4e689f6b08a..5328c9c74fd 100644 --- a/packages/queued-request-controller/package.json +++ b/packages/queued-request-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/queued-request-controller", - "version": "0.10.0", + "version": "0.12.0", "description": "Includes a controller and middleware that implements a request queue", "keywords": [ "MetaMask", @@ -41,17 +41,17 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", - "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", + "@metamask/json-rpc-engine": "^9.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/swappable-obj-proxy": "^2.2.0", "@metamask/utils": "^8.3.0" }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/network-controller": "^18.1.2", - "@metamask/selected-network-controller": "^13.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/selected-network-controller": "^15.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", @@ -65,11 +65,11 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.1.2", - "@metamask/selected-network-controller": "^13.0.0" + "@metamask/network-controller": "^19.0.0", + "@metamask/selected-network-controller": "^15.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/rate-limit-controller/CHANGELOG.md b/packages/rate-limit-controller/CHANGELOG.md index 20f1954f4a3..91da273a4d7 100644 --- a/packages/rate-limit-controller/CHANGELOG.md +++ b/packages/rate-limit-controller/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [5.0.2] + +### Changed + +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.comMetaMask/core/pull/4232)) + ## [5.0.1] ### Fixed @@ -124,7 +137,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@5.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@6.0.0...HEAD +[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@5.0.2...@metamask/rate-limit-controller@6.0.0 +[5.0.2]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@5.0.1...@metamask/rate-limit-controller@5.0.2 [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@5.0.0...@metamask/rate-limit-controller@5.0.1 [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@4.0.2...@metamask/rate-limit-controller@5.0.0 [4.0.2]: https://github.com/MetaMask/core/compare/@metamask/rate-limit-controller@4.0.1...@metamask/rate-limit-controller@4.0.2 diff --git a/packages/rate-limit-controller/package.json b/packages/rate-limit-controller/package.json index f3954e9b4b7..3d7e6976107 100644 --- a/packages/rate-limit-controller/package.json +++ b/packages/rate-limit-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/rate-limit-controller", - "version": "5.0.1", + "version": "6.0.0", "description": "Contains logic for rate-limiting API endpoints by requesting origin", "keywords": [ "MetaMask", @@ -41,7 +41,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", + "@metamask/base-controller": "^6.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0" }, @@ -56,7 +56,7 @@ "typescript": "~4.9.5" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/selected-network-controller/CHANGELOG.md b/packages/selected-network-controller/CHANGELOG.md index dd7d0a901ff..ce8f40861e4 100644 --- a/packages/selected-network-controller/CHANGELOG.md +++ b/packages/selected-network-controller/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [15.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/permission-controller` to `^10.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/json-rpc-engine` to `^9.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [14.0.0] + +### Changed + +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/permission-controller` to `^9.1.1` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [13.0.0] ### Changed @@ -206,7 +223,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial Release ([#1643](https://github.com/MetaMask/core/pull/1643)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@13.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@15.0.0...HEAD +[15.0.0]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@14.0.0...@metamask/selected-network-controller@15.0.0 +[14.0.0]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@13.0.0...@metamask/selected-network-controller@14.0.0 [13.0.0]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@12.0.1...@metamask/selected-network-controller@13.0.0 [12.0.1]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@12.0.0...@metamask/selected-network-controller@12.0.1 [12.0.0]: https://github.com/MetaMask/core/compare/@metamask/selected-network-controller@11.0.0...@metamask/selected-network-controller@12.0.0 diff --git a/packages/selected-network-controller/package.json b/packages/selected-network-controller/package.json index 8b2f273e417..2896c0cbdb1 100644 --- a/packages/selected-network-controller/package.json +++ b/packages/selected-network-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/selected-network-controller", - "version": "13.0.0", + "version": "15.0.0", "description": "Provides an interface to the currently selected networkClientId for a given domain", "keywords": [ "MetaMask", @@ -41,10 +41,10 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/base-controller": "^5.0.2", - "@metamask/json-rpc-engine": "^8.0.2", - "@metamask/network-controller": "^18.1.2", - "@metamask/permission-controller": "^9.1.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/json-rpc-engine": "^9.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/permission-controller": "^10.0.0", "@metamask/swappable-obj-proxy": "^2.2.0", "@metamask/utils": "^8.3.0" }, @@ -63,11 +63,11 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.1.2", - "@metamask/permission-controller": "^9.0.0" + "@metamask/network-controller": "^19.0.0", + "@metamask/permission-controller": "^10.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/signature-controller/CHANGELOG.md b/packages/signature-controller/CHANGELOG.md index d4f5dafc5b9..10f37cd76fd 100644 --- a/packages/signature-controller/CHANGELOG.md +++ b/packages/signature-controller/CHANGELOG.md @@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [18.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^7.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/keyring-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/logging-controller` to `^5.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/message-manager` to `^10.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [17.0.0] + +### Changed + +- **BREAKING:** Update `messages` getter to return `Record` instead of `Record` ([#4319](https://github.com/MetaMask/core/pull/4319)) +- **BREAKING** Bump `@metamask/keyring-controller` peer dependency to `^16.1.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING** Bump `@metamask/logging-controller` peer dependency to `^4.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/message-manager` to `^9.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove state properties `unapprovedMsgs` and `unapprovedMsgCount` ([#4319](https://github.com/MetaMask/core/pull/4319)) + - These properties were related to handling of the `eth_sign` RPC method, but support for that is being removed, so these are no longer needed. +- **BREAKING:** Remove `isEthSignEnabled` option from constructor ([#4319](https://github.com/MetaMask/core/pull/4319)) + - This option governed whether handling of the `eth_sign` RPC method was enabled, but support for that method is being removed, so this is no longer needed. +- **BREAKING:** Remove `newUnsignedMessage` method ([#4319](https://github.com/MetaMask/core/pull/4319)) + - This method was called when a dapp used the `eth_sign` RPC method, but support for that method is being removed, so this is no longer needed. + ## [16.0.0] ### Changed @@ -239,7 +270,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#1214](https://github.com/MetaMask/core/pull/1214)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@16.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@18.0.0...HEAD +[18.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@17.0.0...@metamask/signature-controller@18.0.0 +[17.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@16.0.0...@metamask/signature-controller@17.0.0 [16.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@15.0.0...@metamask/signature-controller@16.0.0 [15.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@14.0.1...@metamask/signature-controller@15.0.0 [14.0.1]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@14.0.0...@metamask/signature-controller@14.0.1 diff --git a/packages/signature-controller/package.json b/packages/signature-controller/package.json index 8140a6d95f8..5abe6874d7e 100644 --- a/packages/signature-controller/package.json +++ b/packages/signature-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/signature-controller", - "version": "16.0.0", + "version": "18.0.0", "description": "Processes signing requests in order to sign arbitrary and typed data", "keywords": [ "MetaMask", @@ -41,12 +41,12 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/approval-controller": "^6.0.2", - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", - "@metamask/keyring-controller": "^16.0.0", - "@metamask/logging-controller": "^3.0.1", - "@metamask/message-manager": "^8.0.2", + "@metamask/approval-controller": "^7.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", + "@metamask/keyring-controller": "^17.0.0", + "@metamask/logging-controller": "^5.0.0", + "@metamask/message-manager": "^10.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", "lodash": "^4.17.21" @@ -62,12 +62,12 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/approval-controller": "^6.0.0", - "@metamask/keyring-controller": "^16.0.0", - "@metamask/logging-controller": "^3.0.0" + "@metamask/approval-controller": "^7.0.0", + "@metamask/keyring-controller": "^17.0.0", + "@metamask/logging-controller": "^5.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 5d5a2005b89..b13981cbee5 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [32.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^7.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/gas-fee-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [31.0.0] + +### Changed + +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^6.0.2` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/gas-fee-controller` to `^16.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `async-mutex` to `^0.5.0` ([#4335](https://github.com/MetaMask/core/pull/4335)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + +### Removed + +- **BREAKING:** Remove `sign` from `TransactionType` ([#4319](https://github.com/MetaMask/core/pull/4319)) + - This represented an `eth_sign` transaction, but support for that RPC method is being removed, so this is no longer needed. + +### Fixed + +- Pass an unfrozen transaction to the `afterSign` hook so that it is able to modify the transaction ([#4343](https://github.com/MetaMask/core/pull/4343)) + ## [30.0.0] ### Fixed @@ -846,7 +876,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@30.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@32.0.0...HEAD +[32.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@31.0.0...@metamask/transaction-controller@32.0.0 +[31.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@30.0.0...@metamask/transaction-controller@31.0.0 [30.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.1.0...@metamask/transaction-controller@30.0.0 [29.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.0.2...@metamask/transaction-controller@29.1.0 [29.0.2]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.0.1...@metamask/transaction-controller@29.0.2 diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index 242e2fafb4b..3c56f28ade5 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/transaction-controller", - "version": "30.0.0", + "version": "32.0.0", "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation", "keywords": [ "MetaMask", @@ -47,13 +47,13 @@ "@ethersproject/abi": "^5.7.0", "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@metamask/approval-controller": "^6.0.2", - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/approval-controller": "^7.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-query": "^4.0.0", - "@metamask/gas-fee-controller": "^15.1.2", + "@metamask/gas-fee-controller": "^17.0.0", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/network-controller": "^18.1.2", + "@metamask/network-controller": "^19.0.0", "@metamask/nonce-tracker": "^5.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", @@ -84,12 +84,12 @@ }, "peerDependencies": { "@babel/runtime": "^7.23.9", - "@metamask/approval-controller": "^6.0.0", - "@metamask/gas-fee-controller": "^15.0.0", - "@metamask/network-controller": "^18.1.2" + "@metamask/approval-controller": "^7.0.0", + "@metamask/gas-fee-controller": "^17.0.0", + "@metamask/network-controller": "^19.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 76a8158ddfe..06010fc3148 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -3289,9 +3289,10 @@ export class TransactionController extends BaseController< return undefined; } - if (!this.afterSign(transactionMeta, signedTx)) { + const transactionMetaFromHook = cloneDeep(transactionMeta); + if (!this.afterSign(transactionMetaFromHook, signedTx)) { this.updateTransaction( - transactionMeta, + transactionMetaFromHook, 'TransactionController#signTransaction - Update after sign', ); @@ -3301,7 +3302,7 @@ export class TransactionController extends BaseController< } const transactionMetaWithRsv = { - ...this.updateTransactionMetaRSV(transactionMeta, signedTx), + ...this.updateTransactionMetaRSV(transactionMetaFromHook, signedTx), status: TransactionStatus.signed as const, }; diff --git a/packages/user-operation-controller/CHANGELOG.md b/packages/user-operation-controller/CHANGELOG.md index b3f60aee3b1..c6812db3aec 100644 --- a/packages/user-operation-controller/CHANGELOG.md +++ b/packages/user-operation-controller/CHANGELOG.md @@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [12.0.0] + +### Changed + +- **BREAKING:** Bump minimum Node version to 18.18 ([#3611](https://github.com/MetaMask/core/pull/3611)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^7.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/gas-fee-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/keyring-controller` to `^17.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^19.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/transaction-controller` to `^32.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/base-controller` to `^6.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/controller-utils` to `^11.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) +- Bump `@metamask/polling-controller` to `^8.0.0` ([#4352](https://github.com/MetaMask/core/pull/4352)) + +## [11.0.0] + +### Added + +- Add support for "swap+send" transactions ([#4298](https://github.com/MetaMask/core/pull/4298)) + - Add optional properties `destinationTokenAmount`, `sourceTokenAddress`, `sourceTokenAmount`, `sourceTokenDecimals`, and `swapAndSendRecipient` to `TransactionMeta` + - Add `swapAndSend` as a new entry in `TransactionType` enum + - When persisting this type of transaction, copy source tokens, destination tokens, and recipient from swap data, and emit `TransactionController:newSwapAndSend` controller event + +### Changed + +- **BREAKING:** Bump dependency and peer dependency `@metamask/approval-controller` to `^6.0.2` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/gas-fee-controller` to `^16.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/keyring-controller` to `^16.1.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/network-controller` to `^18.1.3` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- **BREAKING:** Bump dependency and peer dependency `@metamask/transaction-controller` to `^31.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/controller-utils` to `^10.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) +- Bump `@metamask/polling-controller` to `^7.0.0` ([#4342](https://github.com/MetaMask/core/pull/4342)) + ## [10.0.0] ### Changed @@ -130,7 +163,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial Release ([#3749](https://github.com/MetaMask/core/pull/3749)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@10.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@12.0.0...HEAD +[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@11.0.0...@metamask/user-operation-controller@12.0.0 +[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@10.0.0...@metamask/user-operation-controller@11.0.0 [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@9.0.0...@metamask/user-operation-controller@10.0.0 [9.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@8.0.1...@metamask/user-operation-controller@9.0.0 [8.0.1]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@8.0.0...@metamask/user-operation-controller@8.0.1 diff --git a/packages/user-operation-controller/package.json b/packages/user-operation-controller/package.json index a6d0ef01738..ea2e6338e4d 100644 --- a/packages/user-operation-controller/package.json +++ b/packages/user-operation-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/user-operation-controller", - "version": "10.0.0", + "version": "12.0.0", "description": "Creates user operations and manages their life cycle", "keywords": [ "MetaMask", @@ -42,16 +42,16 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/approval-controller": "^6.0.2", - "@metamask/base-controller": "^5.0.2", - "@metamask/controller-utils": "^10.0.0", + "@metamask/approval-controller": "^7.0.0", + "@metamask/base-controller": "^6.0.0", + "@metamask/controller-utils": "^11.0.0", "@metamask/eth-query": "^4.0.0", - "@metamask/gas-fee-controller": "^15.1.2", - "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.1.2", - "@metamask/polling-controller": "^6.0.2", + "@metamask/gas-fee-controller": "^17.0.0", + "@metamask/keyring-controller": "^17.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/polling-controller": "^8.0.0", "@metamask/rpc-errors": "^6.2.1", - "@metamask/transaction-controller": "^30.0.0", + "@metamask/transaction-controller": "^32.0.0", "@metamask/utils": "^8.3.0", "bn.js": "^5.2.1", "immer": "^9.0.6", @@ -70,14 +70,14 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/approval-controller": "^6.0.0", - "@metamask/gas-fee-controller": "^15.0.0", - "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.1.2", - "@metamask/transaction-controller": "^30.0.0" + "@metamask/approval-controller": "^7.0.0", + "@metamask/gas-fee-controller": "^17.0.0", + "@metamask/keyring-controller": "^17.0.0", + "@metamask/network-controller": "^19.0.0", + "@metamask/transaction-controller": "^32.0.0" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18 || >=20" }, "publishConfig": { "access": "public", diff --git a/yarn.lock b/yarn.lock index b55bc06870c..133412f86b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1609,16 +1609,16 @@ __metadata: languageName: node linkType: hard -"@metamask/accounts-controller@^14.0.0, @metamask/accounts-controller@workspace:packages/accounts-controller": +"@metamask/accounts-controller@^16.0.0, @metamask/accounts-controller@workspace:packages/accounts-controller": version: 0.0.0-use.local resolution: "@metamask/accounts-controller@workspace:packages/accounts-controller" dependencies: "@ethereumjs/util": ^8.1.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/eth-snap-keyring": ^4.1.1 - "@metamask/keyring-api": ^6.1.1 - "@metamask/keyring-controller": ^16.0.0 + "@metamask/keyring-api": ^6.4.0 + "@metamask/keyring-controller": ^17.0.0 "@metamask/snaps-controllers": ^8.1.1 "@metamask/snaps-sdk": ^4.2.0 "@metamask/snaps-utils": ^7.4.0 @@ -1635,7 +1635,7 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/keyring-controller": ^16.0.0 + "@metamask/keyring-controller": ^17.0.0 "@metamask/snaps-controllers": ^8.1.1 languageName: unknown linkType: soft @@ -1656,8 +1656,8 @@ __metadata: resolution: "@metamask/address-book-controller@workspace:packages/address-book-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -1674,7 +1674,7 @@ __metadata: resolution: "@metamask/announcement-controller@workspace:packages/announcement-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 jest: ^27.5.1 @@ -1685,12 +1685,12 @@ __metadata: languageName: unknown linkType: soft -"@metamask/approval-controller@^6.0.2, @metamask/approval-controller@workspace:packages/approval-controller": +"@metamask/approval-controller@^7.0.0, @metamask/approval-controller@workspace:packages/approval-controller": version: 0.0.0-use.local resolution: "@metamask/approval-controller@workspace:packages/approval-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -1705,6 +1705,18 @@ __metadata: languageName: unknown linkType: soft +"@metamask/approval-controller@npm:^6.0.2": + version: 6.0.2 + resolution: "@metamask/approval-controller@npm:6.0.2" + dependencies: + "@metamask/base-controller": ^5.0.2 + "@metamask/rpc-errors": ^6.2.1 + "@metamask/utils": ^8.3.0 + nanoid: ^3.1.31 + checksum: 662365ec460edc1e3839c2f9f427d44a707350ecca7fa3524d75da3652306b61fc69f7336154142b4a38657c272624232ea40bf218427ba15b11fd89c5a5ae42 + languageName: node + linkType: hard + "@metamask/assets-controllers@workspace:packages/assets-controllers": version: 0.0.0-use.local resolution: "@metamask/assets-controllers@workspace:packages/assets-controllers" @@ -1715,20 +1727,20 @@ __metadata: "@ethersproject/contracts": ^5.7.0 "@ethersproject/providers": ^5.7.0 "@metamask/abi-utils": ^2.0.2 - "@metamask/accounts-controller": ^14.0.0 - "@metamask/approval-controller": ^6.0.2 + "@metamask/accounts-controller": ^16.0.0 + "@metamask/approval-controller": ^7.0.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/contract-metadata": ^2.4.0 - "@metamask/controller-utils": ^10.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-query": ^4.0.0 "@metamask/ethjs-provider-http": ^0.3.0 - "@metamask/keyring-api": ^6.1.1 - "@metamask/keyring-controller": ^16.0.0 + "@metamask/keyring-api": ^6.4.0 + "@metamask/keyring-controller": ^17.0.0 "@metamask/metamask-eth-abis": ^3.1.1 - "@metamask/network-controller": ^18.1.2 - "@metamask/polling-controller": ^6.0.2 - "@metamask/preferences-controller": ^11.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/polling-controller": ^8.0.0 + "@metamask/preferences-controller": ^13.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 "@types/bn.js": ^5.1.5 @@ -1753,11 +1765,11 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/accounts-controller": ^14.0.0 - "@metamask/approval-controller": ^6.0.0 - "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.1.2 - "@metamask/preferences-controller": ^11.0.0 + "@metamask/accounts-controller": ^16.0.0 + "@metamask/approval-controller": ^7.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/preferences-controller": ^13.0.0 languageName: unknown linkType: soft @@ -1791,7 +1803,7 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@^5.0.2, @metamask/base-controller@workspace:packages/base-controller": +"@metamask/base-controller@^6.0.0, @metamask/base-controller@workspace:packages/base-controller": version: 0.0.0-use.local resolution: "@metamask/base-controller@workspace:packages/base-controller" dependencies: @@ -1810,6 +1822,16 @@ __metadata: languageName: unknown linkType: soft +"@metamask/base-controller@npm:^5.0.2": + version: 5.0.2 + resolution: "@metamask/base-controller@npm:5.0.2" + dependencies: + "@metamask/utils": ^8.3.0 + immer: ^9.0.6 + checksum: 22c43c3147c7da1c1b87de4d41948e275f8e0adcdb1210a55a62aa497db4fa82399750901729d9dc6285d89e68f18e5bd15095ee4d4c6cfc169035173e69a1d2 + languageName: node + linkType: hard + "@metamask/browser-passworder@npm:^4.3.0": version: 4.3.0 resolution: "@metamask/browser-passworder@npm:4.3.0" @@ -1852,9 +1874,9 @@ __metadata: resolution: "@metamask/chain-controller@workspace:packages/chain-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/chain-api": ^0.0.1 - "@metamask/keyring-api": ^6.1.1 + "@metamask/keyring-api": ^6.4.0 "@metamask/snaps-controllers": ^8.1.1 "@metamask/snaps-sdk": ^4.2.0 "@metamask/snaps-utils": ^7.4.0 @@ -1876,8 +1898,8 @@ __metadata: resolution: "@metamask/composable-controller@workspace:packages/composable-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/json-rpc-engine": ^9.0.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 immer: ^9.0.6 @@ -1897,7 +1919,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@^10.0.0, @metamask/controller-utils@workspace:packages/controller-utils": +"@metamask/controller-utils@^11.0.0, @metamask/controller-utils@workspace:packages/controller-utils": version: 0.0.0-use.local resolution: "@metamask/controller-utils@workspace:packages/controller-utils" dependencies: @@ -1922,6 +1944,23 @@ __metadata: languageName: unknown linkType: soft +"@metamask/controller-utils@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/controller-utils@npm:10.0.0" + dependencies: + "@ethereumjs/util": ^8.1.0 + "@metamask/eth-query": ^4.0.0 + "@metamask/ethjs-unit": ^0.3.0 + "@metamask/utils": ^8.3.0 + "@spruceid/siwe-parser": 2.1.0 + "@types/bn.js": ^5.1.5 + bn.js: ^5.2.1 + eth-ens-namehash: ^2.0.8 + fast-deep-equal: ^3.1.3 + checksum: da92b0c3650f2abae48742caa9162e8cb74e4f0bf9d1288072f2804d2b4f7497ae47c764a3e67321b1cb8c3a6023e26802599cd1f6c28cb3cbc73415f2da8832 + languageName: node + linkType: hard + "@metamask/core-monorepo@workspace:.": version: 0.0.0-use.local resolution: "@metamask/core-monorepo@workspace:." @@ -1936,8 +1975,8 @@ __metadata: "@metamask/eslint-config-nodejs": ^12.1.0 "@metamask/eslint-config-typescript": ^12.1.0 "@metamask/eth-block-tracker": ^9.0.2 - "@metamask/eth-json-rpc-provider": ^3.0.2 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/eth-json-rpc-provider": ^4.0.0 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 "@types/node": ^16.18.54 @@ -1998,9 +2037,9 @@ __metadata: dependencies: "@ethersproject/providers": ^5.7.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/network-controller": ^18.1.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/network-controller": ^19.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -2011,7 +2050,7 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.1.2 + "@metamask/network-controller": ^19.0.0 languageName: unknown linkType: soft @@ -2121,12 +2160,12 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-provider@^3.0.2, @metamask/eth-json-rpc-provider@workspace:packages/eth-json-rpc-provider": +"@metamask/eth-json-rpc-provider@^4.0.0, @metamask/eth-json-rpc-provider@workspace:packages/eth-json-rpc-provider": version: 0.0.0-use.local resolution: "@metamask/eth-json-rpc-provider@workspace:packages/eth-json-rpc-provider" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/safe-event-emitter": ^3.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2150,6 +2189,17 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-json-rpc-provider@npm:^3.0.2": + version: 3.0.2 + resolution: "@metamask/eth-json-rpc-provider@npm:3.0.2" + dependencies: + "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: 0321eaad6fa205a9d3ddcfaf28e63c05291614893cb2e116151185a4acbd6bb6a508d6e556b3cb8bc4d3caef4bf0a638202d9b6bdc127fbcb81715eb2660a809 + languageName: node + linkType: hard + "@metamask/eth-query@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/eth-query@npm:4.0.0" @@ -2188,12 +2238,12 @@ __metadata: linkType: hard "@metamask/eth-snap-keyring@npm:^4.1.1": - version: 4.1.1 - resolution: "@metamask/eth-snap-keyring@npm:4.1.1" + version: 4.2.1 + resolution: "@metamask/eth-snap-keyring@npm:4.2.1" dependencies: "@ethereumjs/tx": ^4.2.0 "@metamask/eth-sig-util": ^7.0.1 - "@metamask/keyring-api": ^6.1.1 + "@metamask/keyring-api": ^6.3.1 "@metamask/snaps-controllers": ^8.1.1 "@metamask/snaps-sdk": ^4.2.0 "@metamask/snaps-utils": ^7.4.0 @@ -2201,7 +2251,7 @@ __metadata: "@types/uuid": ^9.0.1 superstruct: ^1.0.3 uuid: ^9.0.0 - checksum: a5d1c1ee83988a7bb829c2eaf6b9a7035c880c4a381d2a32d91aa1a554c97740232159afac93ddbb493cadba53757be2febd844f6f00fa91f21e73a9c6e3d92d + checksum: cd4eb41c878e619ea3f270439fc32e68f1d75ce92cf0232d5a21d62b6b62b2d9f2d7085078b5d2d85eb94690fd027045de1f741fce73ae7222f67935ec63c2ac languageName: node linkType: hard @@ -2304,17 +2354,17 @@ __metadata: languageName: node linkType: hard -"@metamask/gas-fee-controller@^15.1.2, @metamask/gas-fee-controller@workspace:packages/gas-fee-controller": +"@metamask/gas-fee-controller@^17.0.0, @metamask/gas-fee-controller@workspace:packages/gas-fee-controller": version: 0.0.0-use.local resolution: "@metamask/gas-fee-controller@workspace:packages/gas-fee-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-query": ^4.0.0 "@metamask/ethjs-unit": ^0.3.0 - "@metamask/network-controller": ^18.1.2 - "@metamask/polling-controller": ^6.0.2 + "@metamask/network-controller": ^19.0.0 + "@metamask/polling-controller": ^8.0.0 "@metamask/utils": ^8.3.0 "@types/bn.js": ^5.1.5 "@types/jest": ^27.4.1 @@ -2331,11 +2381,11 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/network-controller": ^18.1.2 + "@metamask/network-controller": ^19.0.0 languageName: unknown linkType: soft -"@metamask/json-rpc-engine@^8.0.1, @metamask/json-rpc-engine@^8.0.2, @metamask/json-rpc-engine@workspace:packages/json-rpc-engine": +"@metamask/json-rpc-engine@^9.0.0, @metamask/json-rpc-engine@workspace:packages/json-rpc-engine": version: 0.0.0-use.local resolution: "@metamask/json-rpc-engine@workspace:packages/json-rpc-engine" dependencies: @@ -2365,12 +2415,35 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-middleware-stream@^7.0.1, @metamask/json-rpc-middleware-stream@workspace:packages/json-rpc-middleware-stream": +"@metamask/json-rpc-engine@npm:^8.0.1, @metamask/json-rpc-engine@npm:^8.0.2": + version: 8.0.2 + resolution: "@metamask/json-rpc-engine@npm:8.0.2" + dependencies: + "@metamask/rpc-errors": ^6.2.1 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: c240d298ad503d93922a94a62cf59f0344b6d6644a523bc8ea3c0f321bea7172b89f2747a5618e2861b2e8152ae5086b76f391a10e4566529faa50b8850c051d + languageName: node + linkType: hard + +"@metamask/json-rpc-middleware-stream@npm:^7.0.1": + version: 7.0.2 + resolution: "@metamask/json-rpc-middleware-stream@npm:7.0.2" + dependencies: + "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + readable-stream: ^3.6.2 + checksum: ff11ad3ff0ec27530efc53c4e6543661648f437dacdd58797449307e20dbc428b479cd8d1e9767797268b98d0445bd6f1986820a8c855faeef01d5c03b55323b + languageName: node + linkType: hard + +"@metamask/json-rpc-middleware-stream@workspace:packages/json-rpc-middleware-stream": version: 0.0.0-use.local resolution: "@metamask/json-rpc-middleware-stream@workspace:packages/json-rpc-middleware-stream" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/safe-event-emitter": ^3.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2388,7 +2461,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/key-tree@npm:^9.0.0, @metamask/key-tree@npm:^9.1.0": +"@metamask/key-tree@npm:^9.1.1": version: 9.1.1 resolution: "@metamask/key-tree@npm:9.1.1" dependencies: @@ -2401,23 +2474,23 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^6.1.1": - version: 6.1.1 - resolution: "@metamask/keyring-api@npm:6.1.1" +"@metamask/keyring-api@npm:^6.3.1, @metamask/keyring-api@npm:^6.4.0": + version: 6.4.0 + resolution: "@metamask/keyring-api@npm:6.4.0" dependencies: "@metamask/snaps-sdk": ^4.2.0 - "@metamask/utils": ^8.3.0 - "@types/uuid": ^9.0.1 + "@metamask/utils": ^8.4.0 + "@types/uuid": ^9.0.8 bech32: ^2.0.0 superstruct: ^1.0.3 - uuid: ^9.0.0 + uuid: ^9.0.1 peerDependencies: - "@metamask/providers": ">=15 <17" - checksum: 5a9ed008e19062c84ec8fd019ad29f9ebb7d8d8464bbe5da70ad26e6aceb57e4d98a9762e7cd9fea4ac7de0cdc08bfc0a5bf598770749aa9abdbe6d1840fb627 + "@metamask/providers": ">=15 <18" + checksum: 7845ed5fa73db3165703c2142b6062d03ca5fea329b54d28f424dee2bb393edc1f9a015e771289ef7236c31f30355bf2c52ad74bb47cf531c09c5eec66e06b00 languageName: node linkType: hard -"@metamask/keyring-controller@^16.0.0, @metamask/keyring-controller@workspace:packages/keyring-controller": +"@metamask/keyring-controller@^17.0.0, @metamask/keyring-controller@workspace:packages/keyring-controller": version: 0.0.0-use.local resolution: "@metamask/keyring-controller@workspace:packages/keyring-controller" dependencies: @@ -2428,13 +2501,13 @@ __metadata: "@keystonehq/metamask-airgapped-keyring": ^0.14.1 "@lavamoat/allow-scripts": ^3.0.4 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/browser-passworder": ^4.3.0 "@metamask/eth-hd-keyring": ^7.0.1 "@metamask/eth-sig-util": ^7.0.1 "@metamask/eth-simple-keyring": ^6.0.1 - "@metamask/keyring-api": ^6.1.1 - "@metamask/message-manager": ^8.0.2 + "@metamask/keyring-api": ^6.4.0 + "@metamask/message-manager": ^10.0.0 "@metamask/scure-bip39": ^2.1.1 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2453,13 +2526,13 @@ __metadata: languageName: unknown linkType: soft -"@metamask/logging-controller@^3.0.1, @metamask/logging-controller@workspace:packages/logging-controller": +"@metamask/logging-controller@^5.0.0, @metamask/logging-controller@workspace:packages/logging-controller": version: 0.0.0-use.local resolution: "@metamask/logging-controller@workspace:packages/logging-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 jest: ^27.5.1 @@ -2471,13 +2544,13 @@ __metadata: languageName: unknown linkType: soft -"@metamask/message-manager@^8.0.2, @metamask/message-manager@workspace:packages/message-manager": +"@metamask/message-manager@^10.0.0, @metamask/message-manager@workspace:packages/message-manager": version: 0.0.0-use.local resolution: "@metamask/message-manager@workspace:packages/message-manager" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-sig-util": ^7.0.1 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2505,8 +2578,8 @@ __metadata: resolution: "@metamask/name-controller@workspace:packages/name-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 async-mutex: ^0.5.0 @@ -2519,20 +2592,20 @@ __metadata: languageName: unknown linkType: soft -"@metamask/network-controller@^18.1.2, @metamask/network-controller@workspace:packages/network-controller": +"@metamask/network-controller@^19.0.0, @metamask/network-controller@workspace:packages/network-controller": version: 0.0.0-use.local resolution: "@metamask/network-controller@workspace:packages/network-controller" dependencies: "@json-rpc-specification/meta-schema": ^1.0.6 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-block-tracker": ^9.0.2 "@metamask/eth-json-rpc-infura": ^9.1.0 "@metamask/eth-json-rpc-middleware": ^12.1.1 - "@metamask/eth-json-rpc-provider": ^3.0.2 + "@metamask/eth-json-rpc-provider": ^4.0.0 "@metamask/eth-query": ^4.0.0 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/swappable-obj-proxy": ^2.2.0 "@metamask/utils": ^8.3.0 @@ -2572,7 +2645,7 @@ __metadata: resolution: "@metamask/notification-controller@workspace:packages/notification-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -2615,15 +2688,15 @@ __metadata: languageName: node linkType: hard -"@metamask/permission-controller@^9.0.2, @metamask/permission-controller@^9.1.0, @metamask/permission-controller@workspace:packages/permission-controller": +"@metamask/permission-controller@^10.0.0, @metamask/permission-controller@workspace:packages/permission-controller": version: 0.0.0-use.local resolution: "@metamask/permission-controller@workspace:packages/permission-controller" dependencies: - "@metamask/approval-controller": ^6.0.2 + "@metamask/approval-controller": ^7.0.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 "@types/deep-freeze-strict": ^1.1.0 @@ -2638,17 +2711,36 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/approval-controller": ^6.0.0 + "@metamask/approval-controller": ^7.0.0 languageName: unknown linkType: soft +"@metamask/permission-controller@npm:^9.0.2": + version: 9.1.1 + resolution: "@metamask/permission-controller@npm:9.1.1" + dependencies: + "@metamask/base-controller": ^5.0.2 + "@metamask/controller-utils": ^10.0.0 + "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/rpc-errors": ^6.2.1 + "@metamask/utils": ^8.3.0 + "@types/deep-freeze-strict": ^1.1.0 + deep-freeze-strict: ^1.1.1 + immer: ^9.0.6 + nanoid: ^3.1.31 + peerDependencies: + "@metamask/approval-controller": ^6.0.0 + checksum: 98a0406570bcb7604806b91c037033a1f0a65e519a5da2157b80b3a38ec4990be94c84ac4eb495760f9acf9ebac41212ec201f04f9aba92477209d45ec2da0b2 + languageName: node + linkType: hard + "@metamask/permission-log-controller@workspace:packages/permission-log-controller": version: 0.0.0-use.local resolution: "@metamask/permission-log-controller@workspace:packages/permission-log-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/json-rpc-engine": ^9.0.0 "@metamask/utils": ^8.3.0 "@types/deep-freeze-strict": ^1.1.0 "@types/jest": ^27.4.1 @@ -2663,13 +2755,26 @@ __metadata: languageName: unknown linkType: soft -"@metamask/phishing-controller@^9.0.1, @metamask/phishing-controller@workspace:packages/phishing-controller": +"@metamask/phishing-controller@npm:^9.0.1": + version: 9.0.4 + resolution: "@metamask/phishing-controller@npm:9.0.4" + dependencies: + "@metamask/base-controller": ^5.0.2 + "@metamask/controller-utils": ^10.0.0 + "@types/punycode": ^2.1.0 + eth-phishing-detect: ^1.2.0 + punycode: ^2.1.1 + checksum: 096361bcf2e95ab05578ee603a0be4b9982d65f72d156d7d43e36b4a11acb24d8e39ac266789b6584f6ab401149cdc0140468e4d9355fad4331fe6119af07287 + languageName: node + linkType: hard + +"@metamask/phishing-controller@workspace:packages/phishing-controller": version: 0.0.0-use.local resolution: "@metamask/phishing-controller@workspace:packages/phishing-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@types/jest": ^27.4.1 "@types/punycode": ^2.1.0 deepmerge: ^4.2.2 @@ -2685,14 +2790,14 @@ __metadata: languageName: unknown linkType: soft -"@metamask/polling-controller@^6.0.2, @metamask/polling-controller@workspace:packages/polling-controller": +"@metamask/polling-controller@^8.0.0, @metamask/polling-controller@workspace:packages/polling-controller": version: 0.0.0-use.local resolution: "@metamask/polling-controller@workspace:packages/polling-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/network-controller": ^18.1.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/network-controller": ^19.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 "@types/uuid": ^8.3.0 @@ -2706,11 +2811,11 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/network-controller": ^18.1.2 + "@metamask/network-controller": ^19.0.0 languageName: unknown linkType: soft -"@metamask/post-message-stream@npm:^8.0.0": +"@metamask/post-message-stream@npm:^8.1.0": version: 8.1.0 resolution: "@metamask/post-message-stream@npm:8.1.0" dependencies: @@ -2720,14 +2825,14 @@ __metadata: languageName: node linkType: hard -"@metamask/preferences-controller@^11.0.0, @metamask/preferences-controller@workspace:packages/preferences-controller": +"@metamask/preferences-controller@^13.0.0, @metamask/preferences-controller@workspace:packages/preferences-controller": version: 0.0.0-use.local resolution: "@metamask/preferences-controller@workspace:packages/preferences-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/keyring-controller": ^16.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/keyring-controller": ^17.0.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 jest: ^27.5.1 @@ -2737,7 +2842,7 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/keyring-controller": ^16.0.0 + "@metamask/keyring-controller": ^17.0.0 languageName: unknown linkType: soft @@ -2762,9 +2867,9 @@ __metadata: languageName: unknown linkType: soft -"@metamask/providers@npm:^16.1.0": - version: 16.1.0 - resolution: "@metamask/providers@npm:16.1.0" +"@metamask/providers@npm:^17.0.0": + version: 17.0.0 + resolution: "@metamask/providers@npm:17.0.0" dependencies: "@metamask/json-rpc-engine": ^8.0.1 "@metamask/json-rpc-middleware-stream": ^7.0.1 @@ -2777,8 +2882,9 @@ __metadata: fast-deep-equal: ^3.1.3 is-stream: ^2.0.0 readable-stream: ^3.6.2 - webextension-polyfill: ^0.10.0 - checksum: 85e40140f342a38112c3d7cee436751a2be4c575cc4f815ab48a73b549abc2d756bf4a10e4b983e91dbd38076601f992531edb6d8d674aebceae32ef7e299275 + peerDependencies: + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 330e369458edc68d743d87b8b2597cdacac58df01b5fc31f565ae5dacee2390ee23693fb10fa451c6146665e87475a4c8f54163407eb05fceeb698900e34f9e6 languageName: node linkType: hard @@ -2787,12 +2893,12 @@ __metadata: resolution: "@metamask/queued-request-controller@workspace:packages/queued-request-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/json-rpc-engine": ^8.0.2 - "@metamask/network-controller": ^18.1.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/json-rpc-engine": ^9.0.0 + "@metamask/network-controller": ^19.0.0 "@metamask/rpc-errors": ^6.2.1 - "@metamask/selected-network-controller": ^13.0.0 + "@metamask/selected-network-controller": ^15.0.0 "@metamask/swappable-obj-proxy": ^2.2.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2807,8 +2913,8 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.1.2 - "@metamask/selected-network-controller": ^13.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/selected-network-controller": ^15.0.0 languageName: unknown linkType: soft @@ -2817,7 +2923,7 @@ __metadata: resolution: "@metamask/rate-limit-controller@workspace:packages/rate-limit-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 + "@metamask/base-controller": ^6.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2857,15 +2963,15 @@ __metadata: languageName: node linkType: hard -"@metamask/selected-network-controller@^13.0.0, @metamask/selected-network-controller@workspace:packages/selected-network-controller": +"@metamask/selected-network-controller@^15.0.0, @metamask/selected-network-controller@workspace:packages/selected-network-controller": version: 0.0.0-use.local resolution: "@metamask/selected-network-controller@workspace:packages/selected-network-controller" dependencies: "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/json-rpc-engine": ^8.0.2 - "@metamask/network-controller": ^18.1.2 - "@metamask/permission-controller": ^9.1.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/json-rpc-engine": ^9.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/permission-controller": ^10.0.0 "@metamask/swappable-obj-proxy": ^2.2.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2880,8 +2986,8 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.1.2 - "@metamask/permission-controller": ^9.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/permission-controller": ^10.0.0 languageName: unknown linkType: soft @@ -2889,13 +2995,13 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/signature-controller@workspace:packages/signature-controller" dependencies: - "@metamask/approval-controller": ^6.0.2 + "@metamask/approval-controller": ^7.0.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 - "@metamask/keyring-controller": ^16.0.0 - "@metamask/logging-controller": ^3.0.1 - "@metamask/message-manager": ^8.0.2 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/logging-controller": ^5.0.0 + "@metamask/message-manager": ^10.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 @@ -2907,9 +3013,9 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/approval-controller": ^6.0.0 - "@metamask/keyring-controller": ^16.0.0 - "@metamask/logging-controller": ^3.0.0 + "@metamask/approval-controller": ^7.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/logging-controller": ^5.0.0 languageName: unknown linkType: soft @@ -2921,8 +3027,8 @@ __metadata: linkType: hard "@metamask/snaps-controllers@npm:^8.1.1": - version: 8.1.1 - resolution: "@metamask/snaps-controllers@npm:8.1.1" + version: 8.3.1 + resolution: "@metamask/snaps-controllers@npm:8.3.1" dependencies: "@metamask/approval-controller": ^6.0.2 "@metamask/base-controller": ^5.0.2 @@ -2931,12 +3037,12 @@ __metadata: "@metamask/object-multiplex": ^2.0.0 "@metamask/permission-controller": ^9.0.2 "@metamask/phishing-controller": ^9.0.1 - "@metamask/post-message-stream": ^8.0.0 + "@metamask/post-message-stream": ^8.1.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/snaps-registry": ^3.1.0 - "@metamask/snaps-rpc-methods": ^8.1.0 - "@metamask/snaps-sdk": ^4.1.0 - "@metamask/snaps-utils": ^7.3.0 + "@metamask/snaps-rpc-methods": ^9.1.2 + "@metamask/snaps-sdk": ^4.4.1 + "@metamask/snaps-utils": ^7.4.1 "@metamask/utils": ^8.3.0 "@xstate/fsm": ^2.0.0 browserify-zlib: ^0.2.0 @@ -2949,11 +3055,11 @@ __metadata: readable-web-to-node-stream: ^3.0.2 tar-stream: ^3.1.7 peerDependencies: - "@metamask/snaps-execution-environments": ^6.1.0 + "@metamask/snaps-execution-environments": ^6.3.0 peerDependenciesMeta: "@metamask/snaps-execution-environments": optional: true - checksum: 6b3d68a48bae8a70f1f59043de6636c2ad5b2d8e427e40c1b124fc7a35a7dccc77031987ee404a8927dd3d53b4c82782abb80e768ef1defad378dbe2fa2b4a13 + checksum: d2fccfc9a4fdea68c89755a0e93e292eafdbe28515fcf1f5ba761d4fb057ae2f1732d242f776cd089ea8dfbd0f84d9d2151778ba529fd9b5b4c7b00460a612ab languageName: node linkType: hard @@ -2969,49 +3075,49 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-rpc-methods@npm:^8.1.0": - version: 8.1.0 - resolution: "@metamask/snaps-rpc-methods@npm:8.1.0" +"@metamask/snaps-rpc-methods@npm:^9.1.2": + version: 9.1.2 + resolution: "@metamask/snaps-rpc-methods@npm:9.1.2" dependencies: - "@metamask/key-tree": ^9.0.0 + "@metamask/key-tree": ^9.1.1 "@metamask/permission-controller": ^9.0.2 "@metamask/rpc-errors": ^6.2.1 - "@metamask/snaps-sdk": ^4.1.0 - "@metamask/snaps-utils": ^7.3.0 + "@metamask/snaps-sdk": ^4.4.1 + "@metamask/snaps-utils": ^7.4.1 "@metamask/utils": ^8.3.0 "@noble/hashes": ^1.3.1 superstruct: ^1.0.3 - checksum: 343da447508c1d5a0757640bb6aa3a7b3979294574ce0600f5a011c2918eb1842ae20c93c0967cf49da622dae99af73f6b243fdfbf65046c5f638dc52d04600d + checksum: dffe041f69ae8593c080155b9338ed86997fd0e23098ccadbc80a2a17a461d3744008b30b419a49be93dbc8482c2f01f6c9fcbf844f58cebdae2439b81353d4b languageName: node linkType: hard -"@metamask/snaps-sdk@npm:^4.1.0, @metamask/snaps-sdk@npm:^4.2.0": - version: 4.2.0 - resolution: "@metamask/snaps-sdk@npm:4.2.0" +"@metamask/snaps-sdk@npm:^4.2.0, @metamask/snaps-sdk@npm:^4.4.1": + version: 4.4.1 + resolution: "@metamask/snaps-sdk@npm:4.4.1" dependencies: - "@metamask/key-tree": ^9.1.0 - "@metamask/providers": ^16.1.0 + "@metamask/key-tree": ^9.1.1 + "@metamask/providers": ^17.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 fast-xml-parser: ^4.3.4 superstruct: ^1.0.3 - checksum: f9b0e6d7600680183e69d419f5a802208fdc119c7d1226a74076f3b8b8c581850b135392c2f35c391305fc37406973afeb19d8909101580ec16b63fd2f200a8c + checksum: 29dfc36821e77d033ddc1b8f1b8924b4880aca41a25e1767741b50659990a79d3026f3975613090342e98d0cf8d876a0e003edb23ff39d2927dc6473d5c441f9 languageName: node linkType: hard -"@metamask/snaps-utils@npm:^7.3.0, @metamask/snaps-utils@npm:^7.4.0": - version: 7.4.0 - resolution: "@metamask/snaps-utils@npm:7.4.0" +"@metamask/snaps-utils@npm:^7.4.0, @metamask/snaps-utils@npm:^7.4.1": + version: 7.4.1 + resolution: "@metamask/snaps-utils@npm:7.4.1" dependencies: "@babel/core": ^7.23.2 "@babel/types": ^7.23.0 "@metamask/base-controller": ^5.0.2 - "@metamask/key-tree": ^9.1.0 + "@metamask/key-tree": ^9.1.1 "@metamask/permission-controller": ^9.0.2 "@metamask/rpc-errors": ^6.2.1 "@metamask/slip44": ^3.1.0 "@metamask/snaps-registry": ^3.1.0 - "@metamask/snaps-sdk": ^4.2.0 + "@metamask/snaps-sdk": ^4.4.1 "@metamask/utils": ^8.3.0 "@noble/hashes": ^1.3.1 "@scure/base": ^1.1.1 @@ -3025,7 +3131,7 @@ __metadata: ses: ^1.1.0 superstruct: ^1.0.3 validate-npm-package-name: ^5.0.0 - checksum: 1fb072f7262fa0f6685c85a3b44ce75805a87c13449c871e4dde0f6ac3c8cc62cc18ac51ae7eabc399165353abe6d08f3f4ee419cb1fe80518a202423b51660a + checksum: d1d6d3c769c33df88fb6e4fc852cdfe1e400b25b1cae020e729f1bfe8a094804cf901700afbbf1372cc1e95f697127b5847bf3a85b46b403ba2ae64ee5750d22 languageName: node linkType: hard @@ -3036,7 +3142,7 @@ __metadata: languageName: node linkType: hard -"@metamask/transaction-controller@^30.0.0, @metamask/transaction-controller@workspace:packages/transaction-controller": +"@metamask/transaction-controller@^32.0.0, @metamask/transaction-controller@workspace:packages/transaction-controller": version: 0.0.0-use.local resolution: "@metamask/transaction-controller@workspace:packages/transaction-controller" dependencies: @@ -3047,16 +3153,16 @@ __metadata: "@ethersproject/abi": ^5.7.0 "@ethersproject/contracts": ^5.7.0 "@ethersproject/providers": ^5.7.0 - "@metamask/approval-controller": ^6.0.2 + "@metamask/approval-controller": ^7.0.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-json-rpc-provider": ^3.0.2 "@metamask/eth-query": ^4.0.0 "@metamask/ethjs-provider-http": ^0.3.0 - "@metamask/gas-fee-controller": ^15.1.2 + "@metamask/gas-fee-controller": ^17.0.0 "@metamask/metamask-eth-abis": ^3.1.1 - "@metamask/network-controller": ^18.1.2 + "@metamask/network-controller": ^19.0.0 "@metamask/nonce-tracker": ^5.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 @@ -3080,9 +3186,9 @@ __metadata: uuid: ^8.3.2 peerDependencies: "@babel/runtime": ^7.23.9 - "@metamask/approval-controller": ^6.0.0 - "@metamask/gas-fee-controller": ^15.0.0 - "@metamask/network-controller": ^18.1.2 + "@metamask/approval-controller": ^7.0.0 + "@metamask/gas-fee-controller": ^17.0.0 + "@metamask/network-controller": ^19.0.0 languageName: unknown linkType: soft @@ -3090,17 +3196,17 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/user-operation-controller@workspace:packages/user-operation-controller" dependencies: - "@metamask/approval-controller": ^6.0.2 + "@metamask/approval-controller": ^7.0.0 "@metamask/auto-changelog": ^3.4.4 - "@metamask/base-controller": ^5.0.2 - "@metamask/controller-utils": ^10.0.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/controller-utils": ^11.0.0 "@metamask/eth-query": ^4.0.0 - "@metamask/gas-fee-controller": ^15.1.2 - "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.1.2 - "@metamask/polling-controller": ^6.0.2 + "@metamask/gas-fee-controller": ^17.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/polling-controller": ^8.0.0 "@metamask/rpc-errors": ^6.2.1 - "@metamask/transaction-controller": ^30.0.0 + "@metamask/transaction-controller": ^32.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 bn.js: ^5.2.1 @@ -3115,11 +3221,11 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/approval-controller": ^6.0.0 - "@metamask/gas-fee-controller": ^15.0.0 - "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.1.2 - "@metamask/transaction-controller": ^30.0.0 + "@metamask/approval-controller": ^7.0.0 + "@metamask/gas-fee-controller": ^17.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/network-controller": ^19.0.0 + "@metamask/transaction-controller": ^32.0.0 languageName: unknown linkType: soft @@ -3907,7 +4013,7 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^9.0.1": +"@types/uuid@npm:^9.0.1, @types/uuid@npm:^9.0.8": version: 9.0.8 resolution: "@types/uuid@npm:9.0.8" checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 @@ -11930,7 +12036,7 @@ __metadata: languageName: node linkType: hard -"webextension-polyfill@npm:>=0.10.0 <1.0, webextension-polyfill@npm:^0.10.0": +"webextension-polyfill@npm:>=0.10.0 <1.0": version: 0.10.0 resolution: "webextension-polyfill@npm:0.10.0" checksum: 4a59036bda571360c2c0b2fb03fe1dc244f233946bcf9a6766f677956c40fd14d270aaa69cdba95e4ac521014afbe4008bfa5959d0ac39f91c990eb206587f91