From 90f23baef5e52af651eec82d901b4d2d0b3b7f67 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 12:49:25 +0200 Subject: [PATCH 01/45] feat(snap-account-service): add migration logic + keyring v2 support --- packages/snap-account-service/CHANGELOG.md | 7 +- packages/snap-account-service/package.json | 1 + .../SnapAccountService-method-action-types.ts | 19 +- .../src/SnapAccountService.test.ts | 165 +++++++++++++++++- .../src/SnapAccountService.ts | 145 ++++++++++++++- yarn.lock | 1 + 6 files changed, 330 insertions(+), 8 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 44fcb39bcd..ee62ccdbce 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -18,11 +18,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `SnapAccountService` ([#8414](https://github.com/MetaMask/core/pull/8414)) -- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8725](https://github.com/MetaMask/core/pull/8725)) +- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8725](https://github.com/MetaMask/core/pull/8725)), ([#8732](https://github.com/MetaMask/core/pull/8732)) - Waits for the Snap platform to be ready and for a Snap keyring to appear in `KeyringController` state before allowing Snap account operations. - Callers must ensure `init()` has run and the Snap is currently installed, enabled, non-blocked, and declares `endowment:keyring`. - `SnapAccountService.ensureReady` now awaits the watcher, so it only resolves once both conditions hold (or rejects if the Snap keyring does not appear within the configured timeout). - `SnapAccountService.ensureReady` now throws `Unknown snap: ""` when called with a Snap ID that isn't tracked as an account-management Snap. + - `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available. - Add `config` option to `SnapAccountService` constructor with a `snapPlatformWatcher` field exposing `ensureOnboardingComplete` and `snapKeyringWaitTimeoutMs` ([#8715](https://github.com/MetaMask/core/pull/8715)) - Export `SnapAccountServiceConfig` and `SnapPlatformWatcherConfig` types. - Add `@metamask/keyring-controller` dependency ([#8715](https://github.com/MetaMask/core/pull/8715)) @@ -40,6 +41,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - This logic used to live on the clients. - The service messenger now requires the `KeyringController:unlock`, `AccountTreeController:selectedAccountGroupChange`, `AccountTreeController:accountGroup{Created,Updated,Removed}` events. - The service messenger now requires the `AccountTreeController:getSelectedAccountGroup` and `AccountTreeController:getAccountGroupObject` actions. +- Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) + - The migration is guaranteed to be run when using `ensureReady`. + - It is conccurent-free and can safely be called by multiple execution flows. + - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. ### Changed diff --git a/packages/snap-account-service/package.json b/packages/snap-account-service/package.json index 16265c0054..c55e93b9fd 100644 --- a/packages/snap-account-service/package.json +++ b/packages/snap-account-service/package.json @@ -56,6 +56,7 @@ "@metamask/account-api": "^1.0.4", "@metamask/account-tree-controller": "^7.4.0", "@metamask/eth-snap-keyring": "^22.0.1", + "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^25.5.0", "@metamask/messenger": "^1.2.0", "@metamask/snaps-controllers": "^19.0.0", diff --git a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts index 15af5c939f..fd6bccbbfe 100644 --- a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts +++ b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts @@ -20,7 +20,11 @@ export type SnapAccountServiceGetSnapsAction = { /** * Ensures everything is ready to use Snap accounts for the given Snap. * 1. Validates that `snapId` is a tracked account-management Snap. - * 2. Waits for the Snap platform to be fully started. + * 2. Runs the legacy -> v2 Snap keyring migration (cached — no-op if + * already done). + * 3. Atomically creates the v2 keyring for this Snap if it doesn't exist + * yet. + * 4. Waits for the Snap platform to be fully started. * * Safe to call concurrently — each step is idempotent or mutex-protected. * @@ -32,6 +36,18 @@ export type SnapAccountServiceEnsureReadyAction = { handler: SnapAccountService['ensureReady']; }; +/** + * Migrate the legacy Snap keyring to the new (per-snap) Snap keyring v2. + * Safe to call concurrently — the migration runs only once; all callers + * await the same promise. + * + * @returns A promise that resolves when the migration is complete. + */ +export type SnapAccountServiceMigrateAction = { + type: `SnapAccountService:migrate`; + handler: SnapAccountService['migrate']; +}; + /** * Atomically gets-or-creates the legacy (v1) Snap keyring — the keyring * associated with {@link KeyringTypes.snap}. @@ -61,5 +77,6 @@ export type SnapAccountServiceHandleKeyringSnapMessageAction = { export type SnapAccountServiceMethodActions = | SnapAccountServiceGetSnapsAction | SnapAccountServiceEnsureReadyAction + | SnapAccountServiceMigrateAction | SnapAccountServiceGetLegacySnapKeyringAction | SnapAccountServiceHandleKeyringSnapMessageAction; diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index e1569d63a0..9a64a0da24 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -1,5 +1,7 @@ import type { AccountGroupId } from '@metamask/account-api'; +import { SNAP_KEYRING_TYPE } from '@metamask/eth-snap-keyring'; import type { SnapKeyring, SnapMessage } from '@metamask/eth-snap-keyring'; +import { KeyringType } from '@metamask/keyring-api/v2'; import { KeyringControllerState, KeyringTypes, @@ -436,6 +438,7 @@ function setup({ } const MOCK_SNAP_ID = 'npm:@metamask/mock-snap' as SnapId; +const MOCK_OTHER_SNAP_ID = 'npm:@metamask/other-snap' as SnapId; describe('SnapAccountService', () => { describe('init', () => { @@ -458,6 +461,93 @@ describe('SnapAccountService', () => { }); }); + describe('migrate', () => { + it('runs the migration only once when called concurrently', async () => { + const { service, mocks } = setup(); + mocks.KeyringController.withController.mockResolvedValue(undefined); + + await Promise.all([service.migrate(), service.migrate()]); + + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); + }); + + it('is a no-op when no legacy Snap keyring is present', async () => { + const addNewKeyring = jest.fn().mockResolvedValue(undefined); + const removeKeyring = jest.fn().mockResolvedValue(undefined); + const { service, mocks } = setup(); + mocks.KeyringController.withController.mockImplementation( + async (operation) => + operation({ keyrings: [], addNewKeyring, removeKeyring }), + ); + + await service.migrate(); + + expect(addNewKeyring).not.toHaveBeenCalled(); + expect(removeKeyring).not.toHaveBeenCalled(); + }); + + it('migrates accounts from the legacy Snap keyring to per-Snap v2 keyrings and removes the legacy entry', async () => { + const addNewKeyring = jest.fn().mockResolvedValue(undefined); + const removeKeyring = jest.fn().mockResolvedValue(undefined); + const legacyKeyringId = 'legacy-keyring-id'; + const account1 = { + id: 'account-1', + address: '0x1', + metadata: { snap: { id: MOCK_SNAP_ID } }, + }; + const account2 = { + id: 'account-2', + address: '0x2', + metadata: { snap: { id: MOCK_SNAP_ID } }, + }; + const account3 = { + id: 'account-3', + address: '0x3', + metadata: { snap: { id: MOCK_OTHER_SNAP_ID } }, + }; + const orphanAccount = { + id: 'orphan', + address: '0x4', + metadata: {}, + }; + const legacyKeyring = { + type: SNAP_KEYRING_TYPE, + listAccounts: jest + .fn() + .mockReturnValue([account1, account2, account3, orphanAccount]), + }; + const { service, mocks } = setup(); + mocks.KeyringController.withController.mockImplementation( + async (operation) => + operation({ + keyrings: [ + { keyring: legacyKeyring, metadata: { id: legacyKeyringId } }, + ], + addNewKeyring, + removeKeyring, + }), + ); + + await service.migrate(); + + expect(addNewKeyring).toHaveBeenCalledTimes(2); + expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { + snapId: MOCK_SNAP_ID, + accounts: { + [account1.id]: { id: account1.id, address: account1.address }, + [account2.id]: { id: account2.id, address: account2.address }, + }, + }); + expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { + snapId: MOCK_OTHER_SNAP_ID, + accounts: { + [account3.id]: { id: account3.id, address: account3.address }, + }, + }); + expect(removeKeyring).toHaveBeenCalledWith(legacyKeyringId); + }); + }); + describe('ensureReady', () => { it('throws when the Snap is not tracked', async () => { const { service } = setup(); @@ -489,6 +579,73 @@ describe('SnapAccountService', () => { expect(await service.ensureReady(MOCK_SNAP_ID)).toBeUndefined(); }); + it('runs the migration before checking platform readiness', async () => { + const { service, mocks } = setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + }); + mocks.KeyringController.withController.mockResolvedValue(undefined); + + await service.init(); + // `migrate` is invoked once + `#createKeyringForSnap` is invoked once + // (the cached migrate call is a no-op on subsequent calls). + await service.ensureReady(MOCK_SNAP_ID); + + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); + }); + + it('creates a v2 keyring for the Snap when one does not exist yet', async () => { + const addNewKeyring = jest.fn().mockResolvedValue(undefined); + const removeKeyring = jest.fn().mockResolvedValue(undefined); + const { service, mocks } = setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + }); + mocks.KeyringController.withController.mockImplementation( + async (operation) => + operation({ keyrings: [], addNewKeyring, removeKeyring }), + ); + + await service.init(); + await service.ensureReady(MOCK_SNAP_ID); + + expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { + snapId: MOCK_SNAP_ID, + accounts: {}, + }); + }); + + it('does not create a v2 keyring when one already exists for the Snap', async () => { + const addNewKeyring = jest.fn().mockResolvedValue(undefined); + const removeKeyring = jest.fn().mockResolvedValue(undefined); + const { service, mocks } = setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + }); + // First call: migration (no legacy snap keyring → early return). + // Second call: ensureReady keyring check (snap keyring already exists). + mocks.KeyringController.withController + .mockImplementationOnce(async (operation) => + operation({ keyrings: [], addNewKeyring, removeKeyring }), + ) + .mockImplementationOnce(async (operation) => + operation({ + keyrings: [ + { + keyringV2: { + type: KeyringType.Snap, + snapId: MOCK_SNAP_ID, + }, + }, + ], + addNewKeyring, + removeKeyring, + }), + ); + + await service.init(); + await service.ensureReady(MOCK_SNAP_ID); + + expect(addNewKeyring).not.toHaveBeenCalled(); + }); + it('waits for the Snap platform to become ready', async () => { const { service, rootMessenger } = setup({ snapIsReady: false, @@ -525,9 +682,9 @@ describe('SnapAccountService', () => { return undefined; }); - // Flush microtasks so #waitForSnapKeyring subscribes. - await Promise.resolve(); - await Promise.resolve(); + // Flush microtasks so migration completes and #waitForSnapKeyring + // subscribes. + await flushMicrotasks(); expect(resolved).toBe(false); @@ -584,7 +741,7 @@ describe('SnapAccountService', () => { return undefined; }); - await Promise.resolve(); + await flushMicrotasks(); expect(ensureOnboardingComplete).toHaveBeenCalledTimes(1); expect(resolved).toBe(false); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 7f73096178..54a36f1b79 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -3,6 +3,8 @@ import type { SnapKeyring as LegacySnapKeyring, SnapMessage, } from '@metamask/eth-snap-keyring'; +import { SnapKeyring, SnapKeyringState } from '@metamask/eth-snap-keyring/v2'; +import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, @@ -34,6 +36,7 @@ import type { SnapAccountServiceGetLegacySnapKeyringAction, SnapAccountServiceGetSnapsAction, SnapAccountServiceHandleKeyringSnapMessageAction, + SnapAccountServiceMigrateAction, } from './SnapAccountService-method-action-types'; import { SnapPlatformWatcher } from './SnapPlatformWatcher'; import type { SnapPlatformWatcherConfig } from './SnapPlatformWatcher'; @@ -63,6 +66,7 @@ const MESSENGER_EXPOSED_METHODS = [ 'getSnaps', 'getLegacySnapKeyring', 'handleKeyringSnapMessage', + 'migrate', ] as const; /** @@ -72,7 +76,8 @@ export type SnapAccountServiceActions = | SnapAccountServiceEnsureReadyAction | SnapAccountServiceGetSnapsAction | SnapAccountServiceGetLegacySnapKeyringAction - | SnapAccountServiceHandleKeyringSnapMessageAction; + | SnapAccountServiceHandleKeyringSnapMessageAction + | SnapAccountServiceMigrateAction; /** * Actions from other messengers that {@link SnapAccountService} calls. @@ -147,6 +152,17 @@ function isLegacySnapKeyring(keyring: { return keyring.type === KeyringTypes.snap; } +/** + * Checks if a given keyring is a Snap keyring (v2). + * + * @param keyring - The keyring to check. + * @returns `true` if the keyring is a Snap keyring (v2), `false` otherwise. + */ +function isSnapKeyring(keyring: Keyring): keyring is SnapKeyring { + // Using `KeyringType.Snap` (used for v2). + return keyring.type === KeyringType.Snap; +} + /** * Service responsible for managing account management snaps. */ @@ -162,6 +178,8 @@ export class SnapAccountService { readonly #tracker: SnapTracker; + #migratePromise: Promise | null = null; + /** * Constructs a new {@link SnapAccountService}. * @@ -285,7 +303,11 @@ export class SnapAccountService { /** * Ensures everything is ready to use Snap accounts for the given Snap. * 1. Validates that `snapId` is a tracked account-management Snap. - * 2. Waits for the Snap platform to be fully started. + * 2. Runs the legacy -> v2 Snap keyring migration (cached — no-op if + * already done). + * 3. Atomically creates the v2 keyring for this Snap if it doesn't exist + * yet. + * 4. Waits for the Snap platform to be fully started. * * Safe to call concurrently — each step is idempotent or mutex-protected. * @@ -296,11 +318,130 @@ export class SnapAccountService { if (!this.#tracker.canUse(snapId)) { throw new Error(`Unknown snap: "${snapId}"`); } + + // Migrate from the global v1 Snap keyring to the per-Snap v2 keyring + // before doing anything else. + await this.migrate(); + + // We still try to create the keyring for the Snap here, since we might + // want to use a new Snap that never had accounts before. + await this.#ensureKeyringIsReady(snapId); + // Before doing anything with our Snap, we need to make sure the platform // is ready to process requests. await this.#watcher.ensureCanUseSnapPlatform(); } + /** + * Migrate the legacy Snap keyring to the new (per-snap) Snap keyring v2. + * Safe to call concurrently — the migration runs only once; all callers + * await the same promise. + * + * @returns A promise that resolves when the migration is complete. + */ + async migrate(): Promise { + if (!this.#migratePromise) { + this.#migratePromise = this.#migrate(); + } + return await this.#migratePromise; + } + + /** + * Performs the actual migration logic. Should only be called once, and is not + * safe to call concurrently. + */ + async #migrate(): Promise { + log('Migration started...'); + + await this.#messenger.call( + 'KeyringController:withController', + async (controller) => { + const { keyrings } = controller; + + const legacySnapKeyringEntry = keyrings.find(({ keyring }) => + isLegacySnapKeyring(keyring), + ); + if (!legacySnapKeyringEntry) { + log('No legacy Snap keyring found. Migration not required.'); + return; + } + + // The legacy Snap keyring has never been a true `EthKeyring` so we + // need to cast it to `unknown` first. + const legacySnapKeyring = + legacySnapKeyringEntry.keyring as unknown as LegacySnapKeyring; + + // Compute the account list for each Snap, grouped by snap ID. + const states = new Map(); + for (const internalAccount of legacySnapKeyring.listAccounts()) { + // Convert `InternalAccount` to `KeyringAccount` since the Snap + // keyring (v2) expects accounts in that format and will verify it + // with `superstruct` when adding the keyring. + const { metadata, ...account } = internalAccount; + + const snap = metadata?.snap; + if (snap) { + const snapId = snap.id as SnapId; + + let state = states.get(snapId); + if (!state) { + state = { snapId, accounts: {} }; + states.set(snapId, state); + } + state.accounts[account.id] = account; + } + } + + // Create the new Snap keyring (v2) for each Snap and migrate the + // accounts over. + for (const state of states.values()) { + log(`Migrating accounts for Snap "${state.snapId}"...`); + await controller.addNewKeyring( + // IMPORTANT: The Snap keyring (v2) can also be used as a v1 + // keyring. So the builder associated with the v2 keyring type is + // able to build both v1 and v2 keyrings. + KeyringType.Snap, + state, + ); + } + + // Remove the legacy Snap keyring after migration. + log('Removing legacy Snap keyring...'); + await controller.removeKeyring(legacySnapKeyringEntry.metadata.id); + }, + ); + + log('Migration completed!'); + } + + /** + * Ensures a Snap keyring is ready for the given Snap. If it doesn't exist yet, it will be created. + * Safe to call concurrently. + * + * @param snapId - The Snap ID to ensure the keyring is ready for. + */ + async #ensureKeyringIsReady(snapId: SnapId): Promise { + await this.#messenger.call( + 'KeyringController:withController', + async (controller) => { + const hasKeyring = controller.keyrings.some( + ({ keyringV2 }) => + keyringV2 && + isSnapKeyring(keyringV2) && + keyringV2.snapId === snapId, + ); + + if (!hasKeyring) { + log(`Creating v2 keyring for Snap "${snapId}"...`); + await controller.addNewKeyring(KeyringType.Snap, { + snapId, + accounts: {}, + }); + } + }, + ); + } + /** * Atomically gets-or-creates the legacy (v1) Snap keyring — the keyring * associated with {@link KeyringTypes.snap}. diff --git a/yarn.lock b/yarn.lock index 9eff13004d..f1df01bf51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5465,6 +5465,7 @@ __metadata: "@metamask/account-tree-controller": "npm:^7.4.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/eth-snap-keyring": "npm:^22.0.1" + "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^25.5.0" "@metamask/keyring-utils": "npm:^3.2.1" "@metamask/messenger": "npm:^1.2.0" From 54e8dc08c82b5dcb7a27f7d380b158d7512006c6 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 4 May 2026 14:26:10 +0200 Subject: [PATCH 02/45] feat(multichain-account-service): use withKeyringV2 for Snap account providers --- .../multichain-account-service/CHANGELOG.md | 1 + .../src/providers/BaseBip44AccountProvider.ts | 35 ------ .../src/providers/BtcAccountProvider.test.ts | 85 ++++++------- .../src/providers/SnapAccountProvider.test.ts | 66 ++++++++-- .../src/providers/SnapAccountProvider.ts | 48 ++++--- .../src/providers/SolAccountProvider.test.ts | 117 ++++++++---------- .../src/providers/TrxAccountProvider.test.ts | 101 +++++++-------- 7 files changed, 224 insertions(+), 229 deletions(-) diff --git a/packages/multichain-account-service/CHANGELOG.md b/packages/multichain-account-service/CHANGELOG.md index 76fef2a86a..6d4e6df1b1 100644 --- a/packages/multichain-account-service/CHANGELOG.md +++ b/packages/multichain-account-service/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Replace `KeyringController:withKeyring` with `KeyringController:withKeyringV2` for the Snap account providers ([#8732](https://github.com/MetaMask/core/pull/8732)) - **BREAKING:** The service messenger now requires the `SnapAccountService:ensureReady` action to be declared ([#8715](https://github.com/MetaMask/core/pull/8715)) - **BREAKING:** Delegate Snap platform readiness to `@metamask/snap-account-service` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8752](https://github.com/MetaMask/core/pull/8752)) - Removed `MultichainAccountService.ensureCanUseSnapPlatform()` method and the corresponding `MultichainAccountService:ensureCanUseSnapPlatform` messenger action. diff --git a/packages/multichain-account-service/src/providers/BaseBip44AccountProvider.ts b/packages/multichain-account-service/src/providers/BaseBip44AccountProvider.ts index 5ac23e82d7..e7a63366bc 100644 --- a/packages/multichain-account-service/src/providers/BaseBip44AccountProvider.ts +++ b/packages/multichain-account-service/src/providers/BaseBip44AccountProvider.ts @@ -11,7 +11,6 @@ import type { } from '@metamask/keyring-api/v2'; import type { KeyringMetadata, - KeyringSelector, KeyringSelectorV2, } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; @@ -159,40 +158,6 @@ export abstract class BaseBip44AccountProvider< ) as unknown as Account; } - /** - * Run an operation against a V1 keyring selected by `selector`. - * - * Forwards to `KeyringController:withKeyring`. Use this for keyrings that - * have not yet migrated to the unified V2 `Keyring` interface (e.g. the - * snap keyring). - * - * @param selector - The selector identifying the keyring. - * @param operation - The operation to run with the selected keyring. - * @returns The result of the operation. - */ - protected async withKeyring( - selector: KeyringSelector, - operation: ({ - keyring, - metadata, - }: { - keyring: SelectedKeyring; - metadata: KeyringMetadata; - }) => Promise, - ): Promise { - const result = await this.messenger.call( - 'KeyringController:withKeyring', - selector, - ({ keyring, metadata }) => - operation({ - keyring: keyring as SelectedKeyring, - metadata, - }), - ); - - return result as CallbackResult; - } - /** * Run an operation against a V2 keyring selected by `selector`. * diff --git a/packages/multichain-account-service/src/providers/BtcAccountProvider.test.ts b/packages/multichain-account-service/src/providers/BtcAccountProvider.test.ts index c1e7dc05b1..bde6eba947 100644 --- a/packages/multichain-account-service/src/providers/BtcAccountProvider.test.ts +++ b/packages/multichain-account-service/src/providers/BtcAccountProvider.test.ts @@ -1,11 +1,7 @@ import { isBip44Account } from '@metamask/account-api'; -import type { SnapKeyring } from '@metamask/eth-snap-keyring'; import { AccountCreationType, BtcAccountType } from '@metamask/keyring-api'; import type { KeyringMetadata } from '@metamask/keyring-controller'; -import type { - EthKeyring, - InternalAccount, -} from '@metamask/keyring-internal-api'; +import type { InternalAccount } from '@metamask/keyring-internal-api'; import { SnapControllerState } from '@metamask/snaps-controllers'; import deepmerge from 'deepmerge'; @@ -69,9 +65,9 @@ class MockBtcKeyring { return Number(index); } - createAccount: SnapKeyring['createAccount'] = jest + createAccount = jest .fn() - .mockImplementation((_, { derivationPath, index, ...options }) => { + .mockImplementation(({ derivationPath, index, ...options }) => { // Determine the group index to use - either from derivationPath parsing, explicit index, or fallback let groupIndex: number; @@ -110,34 +106,32 @@ class MockBtcKeyring { return account; }); - createAccounts: SnapKeyring['createAccounts'] = jest - .fn() - .mockImplementation((_, options) => { - const groupIndices = - options.type === 'bip44:derive-index' - ? [options.groupIndex] - : toGroupIndexRangeArray(options.range); - - return groupIndices.map((groupIndex) => { - const found = this.accounts.find( - (account) => - isBip44Account(account) && - account.options.entropy.groupIndex === groupIndex, - ); - - if (found) { - return found; // Idempotent. - } - - const account = MockAccountBuilder.from(MOCK_BTC_P2WPKH_ACCOUNT_1) - .withUuid() - .withAddressSuffix(`${groupIndex}`) - .withGroupIndex(groupIndex) - .get(); - this.accounts.push(account); - return account; - }); + createAccounts = jest.fn().mockImplementation((options) => { + const groupIndices = + options.type === 'bip44:derive-index' + ? [options.groupIndex] + : toGroupIndexRangeArray(options.range); + + return groupIndices.map((groupIndex) => { + const found = this.accounts.find( + (account) => + isBip44Account(account) && + account.options.entropy.groupIndex === groupIndex, + ); + + if (found) { + return found; // Idempotent. + } + + const account = MockAccountBuilder.from(MOCK_BTC_P2WPKH_ACCOUNT_1) + .withUuid() + .withAddressSuffix(`${groupIndex}`) + .withGroupIndex(groupIndex) + .get(); + this.accounts.push(account); + return account; }); + }); } class MockBtcAccountProvider extends BtcAccountProvider { @@ -212,12 +206,10 @@ function setup({ ); messenger.registerActionHandler( - 'KeyringController:withKeyring', + 'KeyringController:withKeyringV2', async (_, operation) => operation({ - // We type-cast here, since `withKeyring` defaults to `EthKeyring` and the - // Snap keyring doesn't really implement this interface (this is expected). - keyring: keyring as unknown as EthKeyring, + keyring, metadata: keyring.metadata, }), ); @@ -243,8 +235,8 @@ function setup({ mocks: { handleRequest: mockHandleRequest, keyring: { - createAccount: keyring.createAccount as jest.Mock, - createAccounts: keyring.createAccounts as jest.Mock, + createAccount: keyring.createAccount, + createAccounts: keyring.createAccounts, }, trace: mockTrace, }, @@ -483,14 +475,11 @@ describe('BtcAccountProvider', () => { }); expect(newAccounts).toHaveLength(1); // Batch endpoint must be called, NOT the singular one. - expect(mocks.keyring.createAccounts).toHaveBeenCalledWith( - BtcAccountProvider.BTC_SNAP_ID, - { - type: AccountCreationType.Bip44DeriveIndex, - entropySource: MOCK_HD_KEYRING_1.metadata.id, - groupIndex: newGroupIndex, - }, - ); + expect(mocks.keyring.createAccounts).toHaveBeenCalledWith({ + type: AccountCreationType.Bip44DeriveIndex, + entropySource: MOCK_HD_KEYRING_1.metadata.id, + groupIndex: newGroupIndex, + }); expect(mocks.keyring.createAccount).not.toHaveBeenCalled(); }); diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts index 70a8931ff6..8cec884751 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts @@ -16,6 +16,7 @@ import type { KeyringCapabilities, } from '@metamask/keyring-api'; import type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api'; +import type { KeyringMetadata } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; import type { JsonRpcRequest, SnapId } from '@metamask/snaps-sdk'; import deepmerge from 'deepmerge'; @@ -153,10 +154,12 @@ const setup = ({ config: configOverride = {}, messenger = getRootMessenger(), accounts = [], + keyring: keyringOverrides = {}, }: { config?: DeepPartial; messenger?: RootMessenger; accounts?: InternalAccount[]; + keyring?: { type?: string; snapId?: SnapId }; } = {}) => { const mocks = { AccountsController: { @@ -165,6 +168,9 @@ const setup = ({ ErrorReportingService: { captureException: jest.fn(), }, + KeyringController: { + withKeyringV2: jest.fn(), + }, SnapController: { handleKeyringRequest: { getAccount: jest.fn(), @@ -223,18 +229,30 @@ const setup = ({ ); const keyring = { + type: keyringOverrides.type ?? 'snap', + snapId: keyringOverrides.snapId ?? TEST_SNAP_ID, createAccount: jest.fn(), createAccounts: jest.fn(), removeAccount: jest.fn(), + lookupByAddress: jest + .fn() + .mockImplementation((address: string) => + accounts.map(asKeyringAccount).find((a) => a.address === address), + ), }; + const metadata = { id: 'mock-keyring-id', name: '' } as KeyringMetadata; + mocks.KeyringController.withKeyringV2.mockImplementation( + async (selector, operation) => { + if (selector.filter && !selector.filter(keyring, metadata)) { + throw new Error('No keyring matches the selector'); + } + return await operation({ keyring, metadata }); + }, + ); messenger.registerActionHandler( - 'KeyringController:withKeyring', - jest - .fn() - .mockImplementation( - async (_ /* selector */, operation) => await operation({ keyring }), - ), + 'KeyringController:withKeyringV2', + mocks.KeyringController.withKeyringV2, ); const serviceMessenger = getMultichainAccountServiceMessenger(messenger); @@ -866,9 +884,8 @@ describe('SnapAccountProvider', () => { ).toHaveBeenCalledWith(extraSnapAccount2.id); // Should remove from keyring and recreate the missing account - expect(keyring.removeAccount).toHaveBeenCalledWith( - mockAccounts[1].address, - ); + // (the keyring has extraSnapAccount2 with the same address as mockAccounts[1]) + expect(keyring.removeAccount).toHaveBeenCalledWith(extraSnapAccount2.id); expect(createAccountsSpy).toHaveBeenCalledWith({ entropySource: mockAccounts[1].options.entropy.id, groupIndex: mockAccounts[1].options.entropy.groupIndex, @@ -949,6 +966,37 @@ describe('SnapAccountProvider', () => { }); }); + describe('withKeyringV2 selector', () => { + const mockAccounts = [ + MockAccountBuilder.from(MOCK_HD_ACCOUNT_1) + .withUuid() + .withSnapId(TEST_SNAP_ID) + .get(), + ].filter(isBip44Account); + + it('rejects when the keyring type is not a Snap keyring', async () => { + const { provider } = setup({ + accounts: mockAccounts, + keyring: { type: 'not-a-snap-keyring' }, + }); + + await expect(provider.resyncAccounts(mockAccounts)).rejects.toThrow( + 'No keyring matches the selector', + ); + }); + + it('rejects when the Snap keyring is for a different Snap ID', async () => { + const { provider } = setup({ + accounts: mockAccounts, + keyring: { snapId: 'npm:@metamask/other-snap' as SnapId }, + }); + + await expect(provider.resyncAccounts(mockAccounts)).rejects.toThrow( + 'No keyring matches the selector', + ); + }); + }); + describe('ensureReady', () => { it('delegates Snap platform readiness check to SnapAccountService:ensureReady', async () => { const { provider, mocks } = setup(); diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts index 0d3ae60c4d..95fb11c29d 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts @@ -1,7 +1,10 @@ import { assertIsBip44Account } from '@metamask/account-api'; import type { Bip44Account } from '@metamask/account-api'; import type { TraceCallback, TraceRequest } from '@metamask/controller-utils'; -import type { SnapKeyring } from '@metamask/eth-snap-keyring'; +import type { + SnapKeyring, + SnapKeyring as SnapKeyringV2, +} from '@metamask/eth-snap-keyring/v2'; import { AccountCreationType, assertCreateAccountOptionIsSupported, @@ -13,8 +16,8 @@ import type { EntropySourceId, KeyringAccount, } from '@metamask/keyring-api'; +import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringMetadata } from '@metamask/keyring-controller'; -import { KeyringTypes } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringClient } from '@metamask/keyring-snap-client'; import type { Json, JsonRpcRequest, SnapId } from '@metamask/snaps-sdk'; @@ -72,6 +75,18 @@ export type SnapAccountProviderConfig = { }; }; +// TODO: Move this in `eth-snap-keyring/v2` package? +/** + * Checks if a given keyring is a Snap keyring (v2). + * + * @param keyring - The keyring to check. + * @returns `true` if the keyring is a Snap keyring (v2), `false` otherwise. + */ +function isSnapKeyring(keyring: Keyring): keyring is SnapKeyring { + // Using `KeyringType.Snap` (used for v2). + return keyring.type === KeyringType.Snap; +} + export abstract class SnapAccountProvider extends BaseBip44AccountProvider { readonly snapId: SnapId; @@ -148,15 +163,15 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider { } async #getRestrictedSnapKeyring(): Promise { - // NOTE: We're not supposed to make the keyring instance escape `withKeyring` but - // we have to use the `SnapKeyring` instance to be able to create Solana account + // NOTE: We're not supposed to make the keyring instance escape `withKeyringV2` but + // we have to use the `SnapKeyringV2` instance to be able to create Solana account // without triggering UI confirmation. // Also, creating account that way won't invalidate the Snap keyring state. The // account will get created and persisted properly with the Snap account creation // flow "asynchronously" (with `notify:accountCreated`). const { createAccount, createAccounts } = await this.#withSnapKeyring<{ - createAccount: SnapKeyring['createAccount']; - createAccounts: SnapKeyring['createAccounts']; + createAccount: SnapKeyringV2['createAccount']; + createAccounts: SnapKeyringV2['createAccounts']; }>(async ({ keyring }) => ({ createAccount: keyring.createAccount.bind(keyring), createAccounts: keyring.createAccounts.bind(keyring), @@ -165,17 +180,19 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider { return { createAccount: async (options) => // We use the "unguarded" account creation here (see explanation above). - await createAccount(this.snapId, options, { + await createAccount(options, { displayAccountNameSuggestion: false, displayConfirmation: false, setSelectedAccount: false, }), - createAccounts: async (options) => - await createAccounts(this.snapId, options), + createAccounts: async (options) => await createAccounts(options), removeAccount: async (address: string) => // Though, when removing account, we can use the normal flow. await this.#withSnapKeyring(async ({ keyring }) => { - await keyring.removeAccount(address); + const account = keyring.lookupByAddress(address); + if (account) { + keyring.removeAccount(account.id); + } }), }; } @@ -290,15 +307,16 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider { keyring, metadata, }: { - keyring: SnapKeyring; + keyring: SnapKeyringV2; metadata: KeyringMetadata; }) => Promise, ): Promise { - return this.withKeyring( - { type: KeyringTypes.snap }, - (args) => { - return operation(args); + return this.withKeyringV2( + { + filter: (keyring) => + isSnapKeyring(keyring) && keyring.snapId === this.snapId, }, + (args) => operation(args), ); } diff --git a/packages/multichain-account-service/src/providers/SolAccountProvider.test.ts b/packages/multichain-account-service/src/providers/SolAccountProvider.test.ts index 6419707e3b..b2c424af5f 100644 --- a/packages/multichain-account-service/src/providers/SolAccountProvider.test.ts +++ b/packages/multichain-account-service/src/providers/SolAccountProvider.test.ts @@ -1,11 +1,7 @@ import { isBip44Account } from '@metamask/account-api'; -import type { SnapKeyring } from '@metamask/eth-snap-keyring'; import { AccountCreationType } from '@metamask/keyring-api'; import type { KeyringMetadata } from '@metamask/keyring-controller'; -import type { - EthKeyring, - InternalAccount, -} from '@metamask/keyring-internal-api'; +import type { InternalAccount } from '@metamask/keyring-internal-api'; import { SnapControllerState } from '@metamask/snaps-controllers'; import deepmerge from 'deepmerge'; @@ -68,60 +64,56 @@ class MockSolanaKeyring { return Number(index); } - createAccount: SnapKeyring['createAccount'] = jest - .fn() - .mockImplementation((_, { derivationPath }) => { - if (derivationPath !== undefined) { - const index = this.#getIndexFromDerivationPath(derivationPath); - const found = this.accounts.find( - (account) => - isBip44Account(account) && - account.options.entropy.groupIndex === index, - ); - - if (found) { - return found; // Idempotent. - } + createAccount = jest.fn().mockImplementation(({ derivationPath }) => { + if (derivationPath !== undefined) { + const index = this.#getIndexFromDerivationPath(derivationPath); + const found = this.accounts.find( + (account) => + isBip44Account(account) && + account.options.entropy.groupIndex === index, + ); + + if (found) { + return found; // Idempotent. + } + } + + const account = MockAccountBuilder.from(MOCK_SOL_ACCOUNT_1) + .withUuid() + .withAddressSuffix(`${this.accounts.length}`) + .withGroupIndex(this.accounts.length) + .get(); + this.accounts.push(account); + + return account; + }); + + createAccounts = jest.fn().mockImplementation((options) => { + const groupIndices = + options.type === 'bip44:derive-index' + ? [options.groupIndex] + : toGroupIndexRangeArray(options.range); + + return groupIndices.map((groupIndex) => { + const found = this.accounts.find( + (account) => + isBip44Account(account) && + account.options.entropy.groupIndex === groupIndex, + ); + + if (found) { + return found; // Idempotent. } const account = MockAccountBuilder.from(MOCK_SOL_ACCOUNT_1) .withUuid() - .withAddressSuffix(`${this.accounts.length}`) - .withGroupIndex(this.accounts.length) + .withAddressSuffix(`${groupIndex}`) + .withGroupIndex(groupIndex) .get(); this.accounts.push(account); - return account; }); - - createAccounts: SnapKeyring['createAccounts'] = jest - .fn() - .mockImplementation((_, options) => { - const groupIndices = - options.type === 'bip44:derive-index' - ? [options.groupIndex] - : toGroupIndexRangeArray(options.range); - - return groupIndices.map((groupIndex) => { - const found = this.accounts.find( - (account) => - isBip44Account(account) && - account.options.entropy.groupIndex === groupIndex, - ); - - if (found) { - return found; // Idempotent. - } - - const account = MockAccountBuilder.from(MOCK_SOL_ACCOUNT_1) - .withUuid() - .withAddressSuffix(`${groupIndex}`) - .withGroupIndex(groupIndex) - .get(); - this.accounts.push(account); - return account; - }); - }); + }); } class MockSolAccountProvider extends SolAccountProvider { @@ -201,12 +193,10 @@ function setup({ ); messenger.registerActionHandler( - 'KeyringController:withKeyring', + 'KeyringController:withKeyringV2', async (_, operation) => operation({ - // We type-cast here, since `withKeyring` defaults to `EthKeyring` and the - // Snap keyring doesn't really implement this interface (this is expected). - keyring: keyring as unknown as EthKeyring, + keyring, metadata: keyring.metadata, }), ); @@ -228,8 +218,8 @@ function setup({ mocks: { handleRequest: mockHandleRequest, keyring: { - createAccount: keyring.createAccount as jest.Mock, - createAccounts: keyring.createAccounts as jest.Mock, + createAccount: keyring.createAccount, + createAccounts: keyring.createAccounts, }, trace: mockTrace, }, @@ -465,14 +455,11 @@ describe('SolAccountProvider', () => { }); expect(newAccounts).toHaveLength(1); // Batch endpoint must be called, NOT the singular one. - expect(mocks.keyring.createAccounts).toHaveBeenCalledWith( - SolAccountProvider.SOLANA_SNAP_ID, - { - type: AccountCreationType.Bip44DeriveIndex, - entropySource: MOCK_HD_KEYRING_1.metadata.id, - groupIndex: newGroupIndex, - }, - ); + expect(mocks.keyring.createAccounts).toHaveBeenCalledWith({ + type: AccountCreationType.Bip44DeriveIndex, + entropySource: MOCK_HD_KEYRING_1.metadata.id, + groupIndex: newGroupIndex, + }); expect(mocks.keyring.createAccount).not.toHaveBeenCalled(); }); diff --git a/packages/multichain-account-service/src/providers/TrxAccountProvider.test.ts b/packages/multichain-account-service/src/providers/TrxAccountProvider.test.ts index c755f8e5ce..d8b617ad1e 100644 --- a/packages/multichain-account-service/src/providers/TrxAccountProvider.test.ts +++ b/packages/multichain-account-service/src/providers/TrxAccountProvider.test.ts @@ -1,11 +1,7 @@ import { isBip44Account } from '@metamask/account-api'; -import type { SnapKeyring } from '@metamask/eth-snap-keyring'; import { AccountCreationType } from '@metamask/keyring-api'; import type { KeyringMetadata } from '@metamask/keyring-controller'; -import type { - EthKeyring, - InternalAccount, -} from '@metamask/keyring-internal-api'; +import type { InternalAccount } from '@metamask/keyring-internal-api'; import { SnapControllerState } from '@metamask/snaps-controllers'; import deepmerge from 'deepmerge'; @@ -52,13 +48,39 @@ class MockTronKeyring { this.accounts = accounts; } - createAccount: SnapKeyring['createAccount'] = jest - .fn() - .mockImplementation((_, { index }) => { - // Use the provided index or fallback to accounts length - const groupIndex = index ?? this.accounts.length; + createAccount = jest.fn().mockImplementation(({ index }) => { + // Use the provided index or fallback to accounts length + const groupIndex = index ?? this.accounts.length; - // Check if an account already exists for this group index (idempotent behavior) + // Check if an account already exists for this group index (idempotent behavior) + const found = this.accounts.find( + (account) => + isBip44Account(account) && + account.options.entropy.groupIndex === groupIndex, + ); + + if (found) { + return found; // Idempotent. + } + + // Create new account with the correct group index + const account = MockAccountBuilder.from(MOCK_TRX_ACCOUNT_1) + .withUuid() + .withAddressSuffix(`${this.accounts.length}`) + .withGroupIndex(groupIndex) + .get(); + this.accounts.push(account); + + return account; + }); + + createAccounts = jest.fn().mockImplementation((options) => { + const groupIndices = + options.type === 'bip44:derive-index' + ? [options.groupIndex] + : toGroupIndexRangeArray(options.range); + + return groupIndices.map((groupIndex) => { const found = this.accounts.find( (account) => isBip44Account(account) && @@ -69,45 +91,15 @@ class MockTronKeyring { return found; // Idempotent. } - // Create new account with the correct group index const account = MockAccountBuilder.from(MOCK_TRX_ACCOUNT_1) .withUuid() - .withAddressSuffix(`${this.accounts.length}`) + .withAddressSuffix(`${groupIndex}`) .withGroupIndex(groupIndex) .get(); this.accounts.push(account); - return account; }); - - createAccounts: SnapKeyring['createAccounts'] = jest - .fn() - .mockImplementation((_, options) => { - const groupIndices = - options.type === 'bip44:derive-index' - ? [options.groupIndex] - : toGroupIndexRangeArray(options.range); - - return groupIndices.map((groupIndex) => { - const found = this.accounts.find( - (account) => - isBip44Account(account) && - account.options.entropy.groupIndex === groupIndex, - ); - - if (found) { - return found; // Idempotent. - } - - const account = MockAccountBuilder.from(MOCK_TRX_ACCOUNT_1) - .withUuid() - .withAddressSuffix(`${groupIndex}`) - .withGroupIndex(groupIndex) - .get(); - this.accounts.push(account); - return account; - }); - }); + }); // Add discoverAccounts method to match the provider's usage discoverAccounts = jest.fn().mockResolvedValue([]); @@ -192,12 +184,10 @@ function setup({ ); messenger.registerActionHandler( - 'KeyringController:withKeyring', + 'KeyringController:withKeyringV2', async (_, operation) => operation({ - // We type-cast here, since `withKeyring` defaults to `EthKeyring` and the - // Snap keyring doesn't really implement this interface (this is expected). - keyring: keyring as unknown as EthKeyring, + keyring, metadata: keyring.metadata, }), ); @@ -223,8 +213,8 @@ function setup({ mocks: { handleRequest: mockHandleRequest, keyring: { - createAccount: keyring.createAccount as jest.Mock, - createAccounts: keyring.createAccounts as jest.Mock, + createAccount: keyring.createAccount, + createAccounts: keyring.createAccounts, discoverAccounts: keyring.discoverAccounts, }, trace: mockTrace, @@ -466,14 +456,11 @@ describe('TrxAccountProvider', () => { }); expect(newAccounts).toHaveLength(1); // Batch endpoint must be called, NOT the singular one. - expect(mocks.keyring.createAccounts).toHaveBeenCalledWith( - TrxAccountProvider.TRX_SNAP_ID, - { - type: AccountCreationType.Bip44DeriveIndex, - entropySource: MOCK_HD_KEYRING_1.metadata.id, - groupIndex: newGroupIndex, - }, - ); + expect(mocks.keyring.createAccounts).toHaveBeenCalledWith({ + type: AccountCreationType.Bip44DeriveIndex, + entropySource: MOCK_HD_KEYRING_1.metadata.id, + groupIndex: newGroupIndex, + }); expect(mocks.keyring.createAccount).not.toHaveBeenCalled(); }); From ed0c8dcf41e5d4960a9109cd3fa1cd1fe1e60f23 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 16:19:17 +0200 Subject: [PATCH 03/45] fix: fix failing migration --- packages/snap-account-service/CHANGELOG.md | 1 + .../src/SnapAccountService.test.ts | 42 +++++++++++++++++++ .../src/SnapAccountService.ts | 15 ++++++- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index ee62ccdbce..d2395af0a9 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The service messenger now requires the `AccountTreeController:getSelectedAccountGroup` and `AccountTreeController:getAccountGroupObject` actions. - Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) - The migration is guaranteed to be run when using `ensureReady`. + - If the migration is not successful, it will get retried everytime we need to interact with any Snap keyring (v2) instances. - It is conccurent-free and can safely be called by multiple execution flows. - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 9a64a0da24..fba3061c95 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -546,6 +546,48 @@ describe('SnapAccountService', () => { }); expect(removeKeyring).toHaveBeenCalledWith(legacyKeyringId); }); + + it('does not re-run after a successful migration', async () => { + const { service, mocks } = setup(); + mocks.KeyringController.withController.mockResolvedValue(undefined); + + await service.migrate(); + await service.migrate(); + + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); + }); + + it('retries on a subsequent call after a failed migration', async () => { + const { service, mocks } = setup(); + const error = new Error('migration boom'); + mocks.KeyringController.withController + .mockRejectedValueOnce(error) + .mockResolvedValueOnce(undefined); + + await expect(service.migrate()).rejects.toThrow(error); + await expect(service.migrate()).resolves.toBeUndefined(); + + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); + }); + + it('shares the rejection across concurrent callers but allows a later retry', async () => { + const { service, mocks } = setup(); + const error = new Error('migration boom'); + mocks.KeyringController.withController + .mockRejectedValueOnce(error) + .mockResolvedValueOnce(undefined); + + const [first, second] = await Promise.allSettled([ + service.migrate(), + service.migrate(), + ]); + expect(first).toStrictEqual({ status: 'rejected', reason: error }); + expect(second).toStrictEqual({ status: 'rejected', reason: error }); + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); + + await expect(service.migrate()).resolves.toBeUndefined(); + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); + }); }); describe('ensureReady', () => { diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 54a36f1b79..e1f10a8958 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -178,6 +178,8 @@ export class SnapAccountService { readonly #tracker: SnapTracker; + #migrated = false; + #migratePromise: Promise | null = null; /** @@ -340,10 +342,19 @@ export class SnapAccountService { * @returns A promise that resolves when the migration is complete. */ async migrate(): Promise { + if (this.#migrated) { + return; + } if (!this.#migratePromise) { - this.#migratePromise = this.#migrate(); + this.#migratePromise = this.#migrate() + .then(() => { + this.#migrated = true; + }) + .finally(() => { + this.#migratePromise = null; + }); } - return await this.#migratePromise; + await this.#migratePromise; } /** From ef07834f1d68198fd343b5968be999a9ce23de94 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 17:00:56 +0200 Subject: [PATCH 04/45] fix: use deleteAccount instead of removeAccount --- .../src/providers/SnapAccountProvider.test.ts | 7 +++---- .../src/providers/SnapAccountProvider.ts | 18 +++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts index 8cec884751..6d4f4e972e 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.test.ts @@ -233,7 +233,7 @@ const setup = ({ snapId: keyringOverrides.snapId ?? TEST_SNAP_ID, createAccount: jest.fn(), createAccounts: jest.fn(), - removeAccount: jest.fn(), + deleteAccount: jest.fn().mockResolvedValue(undefined), lookupByAddress: jest .fn() .mockImplementation((address: string) => @@ -883,9 +883,8 @@ describe('SnapAccountProvider', () => { mocks.SnapController.handleKeyringRequest.deleteAccount, ).toHaveBeenCalledWith(extraSnapAccount2.id); - // Should remove from keyring and recreate the missing account - // (the keyring has extraSnapAccount2 with the same address as mockAccounts[1]) - expect(keyring.removeAccount).toHaveBeenCalledWith(extraSnapAccount2.id); + // Should delete the missing account from the keyring (by id) before recreating it. + expect(keyring.deleteAccount).toHaveBeenCalledWith(mockAccounts[1].id); expect(createAccountsSpy).toHaveBeenCalledWith({ entropySource: mockAccounts[1].options.entropy.id, groupIndex: mockAccounts[1].options.entropy.groupIndex, diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts index 95fb11c29d..7b2e32a70e 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts @@ -2,7 +2,6 @@ import { assertIsBip44Account } from '@metamask/account-api'; import type { Bip44Account } from '@metamask/account-api'; import type { TraceCallback, TraceRequest } from '@metamask/controller-utils'; import type { - SnapKeyring, SnapKeyring as SnapKeyringV2, } from '@metamask/eth-snap-keyring/v2'; import { @@ -36,9 +35,9 @@ import { BaseBip44AccountProvider } from './BaseBip44AccountProvider'; import { withTimeout } from './utils'; export type RestrictedSnapKeyring = { - createAccount: (options: Record) => Promise; - createAccounts: (options: CreateAccountOptions) => Promise; - removeAccount: (address: string) => Promise; + createAccount: SnapKeyringV2['createAccount']; + createAccounts: SnapKeyringV2['createAccounts']; + deleteAccount: SnapKeyringV2['deleteAccount']; }; export type SnapAccountProviderConfig = { @@ -82,7 +81,7 @@ export type SnapAccountProviderConfig = { * @param keyring - The keyring to check. * @returns `true` if the keyring is a Snap keyring (v2), `false` otherwise. */ -function isSnapKeyring(keyring: Keyring): keyring is SnapKeyring { +function isSnapKeyring(keyring: Keyring): keyring is SnapKeyringV2 { // Using `KeyringType.Snap` (used for v2). return keyring.type === KeyringType.Snap; } @@ -186,13 +185,10 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider { setSelectedAccount: false, }), createAccounts: async (options) => await createAccounts(options), - removeAccount: async (address: string) => + deleteAccount: async (id: string) => // Though, when removing account, we can use the normal flow. await this.#withSnapKeyring(async ({ keyring }) => { - const account = keyring.lookupByAddress(address); - if (account) { - keyring.removeAccount(account.id); - } + await keyring.deleteAccount(id); }), }; } @@ -282,7 +278,7 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider { // We still need to remove the accounts from the Snap keyring since we're // about to create the same account again, which will use a new ID, but will // keep using the same address, and the Snap keyring does not allow this. - await keyring.removeAccount(account.address); + await keyring.deleteAccount(account.id); // The Snap has no account in its state for this one, we re-create it. await this.createAccounts({ type: AccountCreationType.Bip44DeriveIndex, From a14f395237294c9a8896c46e26e859619f8ba317 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 17:49:15 +0200 Subject: [PATCH 05/45] chore: lint --- .../src/providers/SnapAccountProvider.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts index 7b2e32a70e..405df61ab5 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts @@ -1,9 +1,7 @@ import { assertIsBip44Account } from '@metamask/account-api'; import type { Bip44Account } from '@metamask/account-api'; import type { TraceCallback, TraceRequest } from '@metamask/controller-utils'; -import type { - SnapKeyring as SnapKeyringV2, -} from '@metamask/eth-snap-keyring/v2'; +import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; import { AccountCreationType, assertCreateAccountOptionIsSupported, From 99d1c69bc136efe5017b949cd7c5505d73383129 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 18:33:24 +0200 Subject: [PATCH 06/45] refactor: cosmetic (migrated flag) --- .../src/SnapAccountService.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index e1f10a8958..ab23707de2 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -346,13 +346,17 @@ export class SnapAccountService { return; } if (!this.#migratePromise) { - this.#migratePromise = this.#migrate() - .then(() => { - this.#migrated = true; - }) - .finally(() => { - this.#migratePromise = null; - }); + this.#migratePromise = this.#migrate(); + + try { + await this.#migratePromise; + + // Only mark it as migrated after the migration logic completes successfully. If + // it fails, we want future calls to retry the migration. + this.#migrated = true; + } finally { + this.#migratePromise = null; + }; } await this.#migratePromise; } From f1067d67d647a76fa445b3410801fc72f1885377 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 18:54:38 +0200 Subject: [PATCH 07/45] chore: lint --- packages/snap-account-service/src/SnapAccountService.test.ts | 4 ++-- packages/snap-account-service/src/SnapAccountService.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index fba3061c95..87d7dc4fb5 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -565,7 +565,7 @@ describe('SnapAccountService', () => { .mockResolvedValueOnce(undefined); await expect(service.migrate()).rejects.toThrow(error); - await expect(service.migrate()).resolves.toBeUndefined(); + expect(await service.migrate()).toBeUndefined(); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); }); @@ -585,7 +585,7 @@ describe('SnapAccountService', () => { expect(second).toStrictEqual({ status: 'rejected', reason: error }); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); - await expect(service.migrate()).resolves.toBeUndefined(); + expect(await service.migrate()).toBeUndefined(); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); }); }); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index ab23707de2..96b60f3f71 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -356,7 +356,7 @@ export class SnapAccountService { this.#migrated = true; } finally { this.#migratePromise = null; - }; + } } await this.#migratePromise; } From 940a8cce453c74553387d9265fddc85c551b7b68 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 18:56:20 +0200 Subject: [PATCH 08/45] feat: use keyring v2 for handleKeyringSnapMessage --- packages/snap-account-service/package.json | 1 + .../src/SnapAccountService.test.ts | 168 ++++++++++++++++-- .../src/SnapAccountService.ts | 65 ++++++- yarn.lock | 1 + 4 files changed, 218 insertions(+), 17 deletions(-) diff --git a/packages/snap-account-service/package.json b/packages/snap-account-service/package.json index c55e93b9fd..835f031167 100644 --- a/packages/snap-account-service/package.json +++ b/packages/snap-account-service/package.json @@ -58,6 +58,7 @@ "@metamask/eth-snap-keyring": "^22.0.1", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^25.5.0", + "@metamask/keyring-snap-sdk": "^9.0.1", "@metamask/messenger": "^1.2.0", "@metamask/snaps-controllers": "^19.0.0", "@metamask/snaps-sdk": "^11.0.0", diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 87d7dc4fb5..e4899aeaea 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -1,15 +1,22 @@ import type { AccountGroupId } from '@metamask/account-api'; import { SNAP_KEYRING_TYPE } from '@metamask/eth-snap-keyring'; import type { SnapKeyring, SnapMessage } from '@metamask/eth-snap-keyring'; +import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; +import { KeyringEvent } from '@metamask/keyring-api'; import { KeyringType } from '@metamask/keyring-api/v2'; import { + KeyringControllerError, + KeyringControllerErrorMessage, KeyringControllerState, KeyringTypes, } from '@metamask/keyring-controller'; import type { KeyringEntry, + KeyringMetadata, + KeyringSelectorV2, RestrictedController, } from '@metamask/keyring-controller'; +import { SnapManageAccountsMethod } from '@metamask/keyring-snap-sdk'; import { Messenger, MOCK_ANY_NAMESPACE } from '@metamask/messenger'; import type { MockAnyNamespace, @@ -64,6 +71,7 @@ type Mocks = { KeyringController: { getState: jest.MockedFunction<() => { keyrings: { type: string }[] }>; withController: jest.Mock; + withKeyringV2: jest.Mock; }; // eslint-disable-next-line @typescript-eslint/naming-convention AccountTreeController: { @@ -105,6 +113,7 @@ function getMessenger( 'SnapController:getRunnableSnaps', 'KeyringController:getState', 'KeyringController:withController', + 'KeyringController:withKeyringV2', 'AccountTreeController:getAccountGroupObject', 'AccountTreeController:getSelectedAccountGroup', ], @@ -317,6 +326,57 @@ function mockWithController( return { addNewKeyring }; } +/** + * Configures `mocks.KeyringController.withKeyringV2` so that the operation + * receives a Snap keyring v2 matching the given selector, or throws + * `KeyringNotFound` when none matches. + * + * @param mocks - The mocks object from {@link setup}. + * @param keyrings - The available v2 Snap keyrings, keyed by snap ID. + */ +function mockWithKeyringV2( + mocks: Mocks, + keyrings: Record>, +): void { + mocks.KeyringController.withKeyringV2.mockImplementation( + async ( + selector: KeyringSelectorV2, + operation: (args: { + keyring: SnapKeyringV2; + metadata: KeyringMetadata; + }) => Promise, + ) => { + const entry = Object.entries(keyrings).find(([snapId, kr]) => + // The selector's filter expects a v2 keyring object; we synthesise + // a minimal shape (`type` + `snapId`) so the production filter + // function can identify it. + selector.filter?.( + { + type: KeyringType.Snap, + snapId, + ...kr, + } as unknown, + { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, + ), + ); + if (!entry) { + throw new KeyringControllerError( + KeyringControllerErrorMessage.KeyringNotFound, + ); + } + const [snapId, kr] = entry; + return operation({ + keyring: { + type: KeyringType.Snap, + snapId, + ...kr, + } as unknown as SnapKeyringV2, + metadata: { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, + }); + }, + ); +} + /** * Configures `mocks.KeyringController.withController` to expose a single * legacy Snap keyring with the provided mocked methods. @@ -400,6 +460,7 @@ function setup({ KeyringController: { getState: jest.fn().mockReturnValue({ keyrings }), withController: jest.fn(), + withKeyringV2: jest.fn(), }, AccountTreeController: { getAccountGroupObject: jest.fn().mockReturnValue(undefined), @@ -423,6 +484,10 @@ function setup({ 'KeyringController:withController', mocks.KeyringController.withController, ); + rootMessenger.registerActionHandler( + 'KeyringController:withKeyringV2', + mocks.KeyringController.withKeyringV2, + ); rootMessenger.registerActionHandler( 'AccountTreeController:getAccountGroupObject', mocks.AccountTreeController.getAccountGroupObject, @@ -833,44 +898,122 @@ describe('SnapAccountService', () => { describe('handleKeyringSnapMessage', () => { const MOCK_MESSAGE = { - method: 'keyring_listAccounts', + method: KeyringEvent.AccountUpdated, + params: {}, + } as unknown as SnapMessage; + const MOCK_ACCOUNT_CREATED_MESSAGE = { + method: KeyringEvent.AccountCreated, params: {}, } as unknown as SnapMessage; + const MOCK_GROUP_ID = 'keyring:01JABC/group-1' as AccountGroupId; + const MOCK_ACCOUNTS = [ + '00000000-0000-0000-0000-000000000001', + '00000000-0000-0000-0000-000000000002', + ]; - it('forwards the call to the legacy Snap keyring and returns its result', async () => { + it('forwards the message to the matching v2 Snap keyring and returns its result', async () => { const { service, mocks } = setup(); const handleKeyringSnapMessage = jest .fn() .mockResolvedValue({ ok: true }); - mockLegacySnapKeyring(mocks, { handleKeyringSnapMessage }); + mockWithKeyringV2(mocks, { + [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, + }); const result = await service.handleKeyringSnapMessage( MOCK_SNAP_ID, MOCK_MESSAGE, ); - expect(handleKeyringSnapMessage).toHaveBeenCalledWith( - MOCK_SNAP_ID, - MOCK_MESSAGE, - ); + expect(handleKeyringSnapMessage).toHaveBeenCalledWith(MOCK_MESSAGE); expect(result).toStrictEqual({ ok: true }); }); - it('propagates errors thrown by the Snap keyring', async () => { + it('short-circuits the GetSelectedAccounts method by returning the selected account group accounts', async () => { + const { service, mocks } = setup(); + mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( + MOCK_GROUP_ID, + ); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + + const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { + method: SnapManageAccountsMethod.GetSelectedAccounts, + params: {}, + } as unknown as SnapMessage); + + expect(result).toStrictEqual(MOCK_ACCOUNTS); + expect(mocks.KeyringController.withKeyringV2).not.toHaveBeenCalled(); + }); + + it('returns an empty array for GetSelectedAccounts when no account group is selected', async () => { + const { service } = setup(); + + const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { + method: SnapManageAccountsMethod.GetSelectedAccounts, + params: {}, + } as unknown as SnapMessage); + + expect(result).toStrictEqual([]); + }); + + it('throws a dedicated error when no v2 Snap keyring exists for the given Snap', async () => { + const { service, mocks } = setup(); + mockWithKeyringV2(mocks, {}); + + await expect( + service.handleKeyringSnapMessage(MOCK_SNAP_ID, MOCK_MESSAGE), + ).rejects.toThrow( + `Cannot delegate keyring Snap message, keyring does not exist yet for Snap "${MOCK_SNAP_ID}".`, + ); + }); + + it('propagates non-KeyringNotFound errors thrown by the Snap keyring', async () => { const { service, mocks } = setup(); const error = new Error('snap boom'); const handleKeyringSnapMessage = jest.fn().mockRejectedValue(error); - mockLegacySnapKeyring(mocks, { handleKeyringSnapMessage }); + mockWithKeyringV2(mocks, { + [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, + }); await expect( service.handleKeyringSnapMessage(MOCK_SNAP_ID, MOCK_MESSAGE), ).rejects.toThrow(error); }); + it('ensures the v2 keyring exists before forwarding an AccountCreated event', async () => { + const { service, mocks } = setup(); + // `#ensureKeyringIsReady` uses `withController` — start with no keyring + // so it must create one. + const { addNewKeyring } = mockWithController(mocks, []); + const handleKeyringSnapMessage = jest.fn().mockResolvedValue(null); + // `withController` mock takes precedence over `withKeyringV2`; configure + // `withKeyringV2` separately for the forwarding step. + mockWithKeyringV2(mocks, { + [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, + }); + + await service.handleKeyringSnapMessage( + MOCK_SNAP_ID, + MOCK_ACCOUNT_CREATED_MESSAGE, + ); + + expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { + snapId: MOCK_SNAP_ID, + accounts: {}, + }); + expect(handleKeyringSnapMessage).toHaveBeenCalledWith( + MOCK_ACCOUNT_CREATED_MESSAGE, + ); + }); + it('is exposed as a messenger action', async () => { const { service, mocks, messenger } = setup(); const handleKeyringSnapMessage = jest.fn().mockResolvedValue('pong'); - mockLegacySnapKeyring(mocks, { handleKeyringSnapMessage }); + mockWithKeyringV2(mocks, { + [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, + }); // Reference `service` so it isn't flagged as unused; constructing it // registers the messenger action under test. @@ -882,10 +1025,7 @@ describe('SnapAccountService', () => { MOCK_MESSAGE, ); - expect(handleKeyringSnapMessage).toHaveBeenCalledWith( - MOCK_SNAP_ID, - MOCK_MESSAGE, - ); + expect(handleKeyringSnapMessage).toHaveBeenCalledWith(MOCK_MESSAGE); expect(result).toBe('pong'); }); }); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 96b60f3f71..338a6d03a1 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -4,15 +4,21 @@ import type { SnapMessage, } from '@metamask/eth-snap-keyring'; import { SnapKeyring, SnapKeyringState } from '@metamask/eth-snap-keyring/v2'; +import { KeyringEvent } from '@metamask/keyring-api'; import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, KeyringControllerUnlockEvent, KeyringControllerWithControllerAction, + KeyringControllerWithKeyringV2Action, KeyringEntry, } from '@metamask/keyring-controller'; -import { KeyringTypes } from '@metamask/keyring-controller'; +import { + isKeyringNotFoundError, + KeyringTypes, +} from '@metamask/keyring-controller'; +import { SnapManageAccountsMethod } from '@metamask/keyring-snap-sdk'; import type { AccountId, BaseKeyring } from '@metamask/keyring-utils'; import type { Messenger } from '@metamask/messenger'; import type { @@ -88,6 +94,7 @@ type AllowedActions = | SnapControllerGetRunnableSnapsAction | KeyringControllerGetStateAction | KeyringControllerWithControllerAction + | KeyringControllerWithKeyringV2Action | AccountTreeControllerGetAccountGroupObjectAction | AccountTreeControllerGetSelectedAccountGroupAction; @@ -515,8 +522,60 @@ export class SnapAccountService { snapId: SnapId, message: SnapMessage, ): Promise { - const snapKeyring = await this.getLegacySnapKeyring(); - return snapKeyring.handleKeyringSnapMessage(snapId, message); + // Handle specific methods first. + if (message.method === SnapManageAccountsMethod.GetSelectedAccounts) { + return ( + this.#getAccountGroup(this.#getSelectedAccountGroupId())?.accounts ?? [] + ); + } + + const event = message.method as KeyringEvent; // We assume the Snap platform always sends a valid `KeyringEvent` here. + log( + `Forwarding message "${event}" from Snap "${snapId}" to its keyring...`, + ); + + const isSnapKeyringForThisSnap = ( + keyring: Keyring, + ): keyring is SnapKeyring => + isSnapKeyring(keyring) && keyring.snapId === snapId; + + // We can create a new keyring if the message is an AccountCreated event. + const isAccountCreatedMessage = event === KeyringEvent.AccountCreated; + + // Create the Snap keyring if it doesn't exist yet (in an atomic way). We cannot assume + // the keyring exists (e.g for the MMI Snap). + // NOTE: We only auto-create it for v1 account creation flows. + if (isAccountCreatedMessage) { + await this.#ensureKeyringIsReady(snapId); + } + + // This part of the flow relies on v1 flows, but v2 keyrings are compatible with those messages + // too. + try { + const result = await this.#messenger.call( + 'KeyringController:withKeyringV2', + { filter: (keyring) => isSnapKeyringForThisSnap(keyring) }, + async ({ keyring }) => { + const snapKeyring = keyring as SnapKeyring; // Forced to cast here as generic does not work when using the messenger. + + return await snapKeyring.handleKeyringSnapMessage(message); + }, + ); + + return result as Json; + } catch (error) { + if (isKeyringNotFoundError(error)) { + log( + `No Snap keyring found for Snap "${snapId}". Cannot handle message with method "${event}".`, + ); + + throw new Error( + `Cannot delegate keyring Snap message, keyring does not exist yet for Snap "${snapId}".`, + ); + } + + throw error; + } } /** diff --git a/yarn.lock b/yarn.lock index f1df01bf51..3489069ede 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5467,6 +5467,7 @@ __metadata: "@metamask/eth-snap-keyring": "npm:^22.0.1" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^25.5.0" + "@metamask/keyring-snap-sdk": "npm:^9.0.1" "@metamask/keyring-utils": "npm:^3.2.1" "@metamask/messenger": "npm:^1.2.0" "@metamask/snaps-controllers": "npm:^19.0.0" From 68869ffbd6b7d9e416deef68ad1ff0f5db9de28c Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 12 May 2026 23:56:12 +0200 Subject: [PATCH 09/45] refactor: use v2 keyrings for setSelectedAccounts --- packages/snap-account-service/CHANGELOG.md | 2 + .../src/SnapAccountService.test.ts | 491 ++++++++++++------ .../src/SnapAccountService.ts | 60 ++- 3 files changed, 375 insertions(+), 178 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index d2395af0a9..19658b8000 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -46,6 +46,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - If the migration is not successful, it will get retried everytime we need to interact with any Snap keyring (v2) instances. - It is conccurent-free and can safely be called by multiple execution flows. - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. + - Selected-account forwarding now targets v2 Snap keyrings. + - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. ### Changed diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index e4899aeaea..14d248a37f 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -52,15 +52,6 @@ type MockTruncatedSnap = Pick< /** Mock account group type for tests. */ type MockAccountGroup = Pick; -/** Mock Snap keyring type for tests. */ -type MockSnapKeyring = { - type: KeyringTypes.snap; - handleKeyringSnapMessage?: jest.MockedFunction< - SnapKeyring['handleKeyringSnapMessage'] - >; - setSelectedAccounts?: jest.MockedFunction; -}; - type Mocks = { // eslint-disable-next-line @typescript-eslint/naming-convention SnapController: { @@ -72,6 +63,7 @@ type Mocks = { getState: jest.MockedFunction<() => { keyrings: { type: string }[] }>; withController: jest.Mock; withKeyringV2: jest.Mock; + withKeyringV2Unsafe: jest.Mock; }; // eslint-disable-next-line @typescript-eslint/naming-convention AccountTreeController: { @@ -114,6 +106,7 @@ function getMessenger( 'KeyringController:getState', 'KeyringController:withController', 'KeyringController:withKeyringV2', + 'KeyringController:withKeyringV2Unsafe', 'AccountTreeController:getAccountGroupObject', 'AccountTreeController:getSelectedAccountGroup', ], @@ -213,10 +206,10 @@ function publishUnlock(rootMessenger: RootMessenger): void { * Builds a minimal `TruncatedSnap` for tests. * * @param id - The Snap ID. - * @param hasKeyring - Whether the Snap declares the `endowment:keyring` initial permission. + * @param hasKeyring - Whether the Snap declares the `endowment:keyring` initial permission (default: `true`). * @returns A minimal `TruncatedSnap`. */ -function buildSnap(id: string, hasKeyring: boolean): TruncatedSnap { +function buildSnap(id: string, hasKeyring = true): TruncatedSnap { return { id: id as SnapId, initialPermissions: hasKeyring ? { 'endowment:keyring': {} } : {}, @@ -346,7 +339,7 @@ function mockWithKeyringV2( metadata: KeyringMetadata; }) => Promise, ) => { - const entry = Object.entries(keyrings).find(([snapId, kr]) => + const entry = Object.entries(keyrings).find(([snapId, snapKeyring]) => // The selector's filter expects a v2 keyring object; we synthesise // a minimal shape (`type` + `snapId`) so the production filter // function can identify it. @@ -354,7 +347,7 @@ function mockWithKeyringV2( { type: KeyringType.Snap, snapId, - ...kr, + ...snapKeyring, } as unknown, { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, ), @@ -364,12 +357,12 @@ function mockWithKeyringV2( KeyringControllerErrorMessage.KeyringNotFound, ); } - const [snapId, kr] = entry; + const [snapId, snapKeyring] = entry; return operation({ keyring: { type: KeyringType.Snap, snapId, - ...kr, + ...snapKeyring, } as unknown as SnapKeyringV2, metadata: { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, }); @@ -378,75 +371,90 @@ function mockWithKeyringV2( } /** - * Configures `mocks.KeyringController.withController` to expose a single - * legacy Snap keyring with the provided mocked methods. + * Configures `mocks.KeyringController.withKeyringV2Unsafe` so that the + * operation receives a Snap keyring v2 matching the given selector, or + * throws `KeyringNotFound` when none matches. * * @param mocks - The mocks object from {@link setup}. - * @param keyring - The mocked Snap keyring methods. - * @param keyring.handleKeyringSnapMessage - The mocked implementation. - * @param keyring.setSelectedAccounts - The mocked implementation. + * @param keyrings - The available v2 Snap keyrings, keyed by snap ID. */ -function mockLegacySnapKeyring( +function mockWithKeyringV2Unsafe( mocks: Mocks, - { - handleKeyringSnapMessage, - setSelectedAccounts, - }: { - handleKeyringSnapMessage?: jest.MockedFunction< - SnapKeyring['handleKeyringSnapMessage'] - >; - setSelectedAccounts?: jest.MockedFunction< - SnapKeyring['setSelectedAccounts'] - >; - }, + keyrings: Record< + string, + { + setSelectedAccounts?: jest.Mock; + hasAccount?: (id: string) => boolean; + } + >, ): void { - const snapKeyring: MockSnapKeyring = { - type: KeyringTypes.snap, - handleKeyringSnapMessage, - setSelectedAccounts, - }; - mocks.KeyringController.withController.mockImplementation(async (operation) => - operation({ - get keyrings() { - return Object.freeze([ + mocks.KeyringController.withKeyringV2Unsafe.mockImplementation( + async ( + selector: KeyringSelectorV2, + operation: (args: { + keyring: SnapKeyringV2; + metadata: KeyringMetadata; + }) => Promise, + ) => { + const entry = Object.entries(keyrings).find(([snapId, kr]) => + selector.filter?.( { - keyring: snapKeyring as KeyringEntry['keyring'], - metadata: { id: 'id-snap', name: KeyringTypes.snap }, - }, - ]); - }, - addNewKeyring: jest.fn(), - removeKeyring: jest.fn(), - }), + type: KeyringType.Snap, + snapId, + ...kr, + } as unknown, + { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, + ), + ); + if (!entry) { + throw new KeyringControllerError( + KeyringControllerErrorMessage.KeyringNotFound, + ); + } + const [snapId, kr] = entry; + return operation({ + keyring: { + type: KeyringType.Snap, + snapId, + hasAccount: () => true, + ...kr, + } as unknown as SnapKeyringV2, + metadata: { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, + }); + }, ); } /** - * Constructs the service under test with sensible defaults. + * Constructs the service under test with sensible defaults. Calls + * `service.init()` before returning unless `init: false` is passed. * * @param args - The arguments to this function. * @param args.snapIsReady - Initial value of `SnapController.isReady`. * @param args.keyrings - Initial keyrings returned by `KeyringController:getState`. * @param args.runnableSnaps - Snaps returned by `SnapController:getRunnableSnaps`. * @param args.config - Optional service config. + * @param args.init - Whether to call `service.init()` before returning (default: `true`). * @returns The new service, root messenger, service messenger, and mocks. */ -function setup({ +async function setup({ snapIsReady = true, keyrings = [{ type: KeyringTypes.snap }], runnableSnaps = [], config, + init = true, }: { snapIsReady?: boolean; keyrings?: { type: string }[]; runnableSnaps?: TruncatedSnap[]; config?: SnapAccountServiceOptions['config']; -} = {}): { + init?: boolean; +} = {}): Promise<{ service: SnapAccountService; rootMessenger: RootMessenger; messenger: SnapAccountServiceMessenger; mocks: Mocks; -} { +}> { const rootMessenger = getRootMessenger(); const messenger = getMessenger(rootMessenger); @@ -461,6 +469,7 @@ function setup({ getState: jest.fn().mockReturnValue({ keyrings }), withController: jest.fn(), withKeyringV2: jest.fn(), + withKeyringV2Unsafe: jest.fn(), }, AccountTreeController: { getAccountGroupObject: jest.fn().mockReturnValue(undefined), @@ -488,6 +497,10 @@ function setup({ 'KeyringController:withKeyringV2', mocks.KeyringController.withKeyringV2, ); + rootMessenger.registerActionHandler( + 'KeyringController:withKeyringV2Unsafe', + mocks.KeyringController.withKeyringV2Unsafe, + ); rootMessenger.registerActionHandler( 'AccountTreeController:getAccountGroupObject', mocks.AccountTreeController.getAccountGroupObject, @@ -499,6 +512,10 @@ function setup({ const service = new SnapAccountService({ messenger, config }); + if (init) { + await service.init(); + } + return { service, rootMessenger, messenger, mocks }; } @@ -508,7 +525,7 @@ const MOCK_OTHER_SNAP_ID = 'npm:@metamask/other-snap' as SnapId; describe('SnapAccountService', () => { describe('init', () => { it('resolves without throwing', async () => { - const { service } = setup(); + const { service } = await setup({ init: false }); expect(await service.init()).toBeUndefined(); }); @@ -516,19 +533,17 @@ describe('SnapAccountService', () => { describe('getSnaps', () => { it('exposes tracked Snaps seeded by init', async () => { - const { service } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); - await service.init(); - expect(service.getSnaps()).toStrictEqual([MOCK_SNAP_ID]); }); }); describe('migrate', () => { it('runs the migration only once when called concurrently', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.KeyringController.withController.mockResolvedValue(undefined); await Promise.all([service.migrate(), service.migrate()]); @@ -539,7 +554,7 @@ describe('SnapAccountService', () => { it('is a no-op when no legacy Snap keyring is present', async () => { const addNewKeyring = jest.fn().mockResolvedValue(undefined); const removeKeyring = jest.fn().mockResolvedValue(undefined); - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.KeyringController.withController.mockImplementation( async (operation) => operation({ keyrings: [], addNewKeyring, removeKeyring }), @@ -581,7 +596,7 @@ describe('SnapAccountService', () => { .fn() .mockReturnValue([account1, account2, account3, orphanAccount]), }; - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.KeyringController.withController.mockImplementation( async (operation) => operation({ @@ -613,7 +628,7 @@ describe('SnapAccountService', () => { }); it('does not re-run after a successful migration', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.KeyringController.withController.mockResolvedValue(undefined); await service.migrate(); @@ -623,7 +638,7 @@ describe('SnapAccountService', () => { }); it('retries on a subsequent call after a failed migration', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const error = new Error('migration boom'); mocks.KeyringController.withController .mockRejectedValueOnce(error) @@ -636,7 +651,7 @@ describe('SnapAccountService', () => { }); it('shares the rejection across concurrent callers but allows a later retry', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const error = new Error('migration boom'); mocks.KeyringController.withController .mockRejectedValueOnce(error) @@ -657,9 +672,7 @@ describe('SnapAccountService', () => { describe('ensureReady', () => { it('throws when the Snap is not tracked', async () => { - const { service } = setup(); - - await service.init(); + const { service } = await setup(); await expect(service.ensureReady(MOCK_SNAP_ID)).rejects.toThrow( `Unknown snap: "${MOCK_SNAP_ID}"`, @@ -667,8 +680,9 @@ describe('SnapAccountService', () => { }); it('throws before init even for runnable Snaps', async () => { - const { service } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + init: false, }); await expect(service.ensureReady(MOCK_SNAP_ID)).rejects.toThrow( @@ -677,22 +691,19 @@ describe('SnapAccountService', () => { }); it('resolves when platform is already ready', async () => { - const { service } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); - await service.init(); - expect(await service.ensureReady(MOCK_SNAP_ID)).toBeUndefined(); }); it('runs the migration before checking platform readiness', async () => { - const { service, mocks } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); mocks.KeyringController.withController.mockResolvedValue(undefined); - await service.init(); // `migrate` is invoked once + `#createKeyringForSnap` is invoked once // (the cached migrate call is a no-op on subsequent calls). await service.ensureReady(MOCK_SNAP_ID); @@ -703,15 +714,14 @@ describe('SnapAccountService', () => { it('creates a v2 keyring for the Snap when one does not exist yet', async () => { const addNewKeyring = jest.fn().mockResolvedValue(undefined); const removeKeyring = jest.fn().mockResolvedValue(undefined); - const { service, mocks } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); mocks.KeyringController.withController.mockImplementation( async (operation) => operation({ keyrings: [], addNewKeyring, removeKeyring }), ); - await service.init(); await service.ensureReady(MOCK_SNAP_ID); expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { @@ -723,8 +733,8 @@ describe('SnapAccountService', () => { it('does not create a v2 keyring when one already exists for the Snap', async () => { const addNewKeyring = jest.fn().mockResolvedValue(undefined); const removeKeyring = jest.fn().mockResolvedValue(undefined); - const { service, mocks } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); // First call: migration (no legacy snap keyring → early return). // Second call: ensureReady keyring check (snap keyring already exists). @@ -747,20 +757,17 @@ describe('SnapAccountService', () => { }), ); - await service.init(); await service.ensureReady(MOCK_SNAP_ID); expect(addNewKeyring).not.toHaveBeenCalled(); }); it('waits for the Snap platform to become ready', async () => { - const { service, rootMessenger } = setup({ + const { service, rootMessenger } = await setup({ snapIsReady: false, - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); - await service.init(); - let resolved = false; const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { resolved = true; @@ -776,13 +783,11 @@ describe('SnapAccountService', () => { }); it('waits for the Snap keyring to appear via KeyringController:stateChange', async () => { - const { service, rootMessenger } = setup({ + const { service, rootMessenger } = await setup({ keyrings: [], - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); - await service.init(); - let resolved = false; const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { resolved = true; @@ -802,16 +807,14 @@ describe('SnapAccountService', () => { }); it('rejects if the Snap keyring does not appear within snapKeyringWaitTimeoutMs', async () => { - const { service } = setup({ + const { service } = await setup({ keyrings: [], - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], config: { snapPlatformWatcher: { snapKeyringWaitTimeoutMs: 1_000 }, }, }); - await service.init(); - jest.useFakeTimers(); const ensurePromise = service.ensureReady(MOCK_SNAP_ID); // Attach rejection handler before advancing timers to avoid unhandled rejection. @@ -835,13 +838,11 @@ describe('SnapAccountService', () => { }), ); - const { service } = setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID, true)], + const { service } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], config: { snapPlatformWatcher: { ensureOnboardingComplete } }, }); - await service.init(); - let resolved = false; const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { resolved = true; @@ -861,7 +862,7 @@ describe('SnapAccountService', () => { describe('getLegacySnapKeyring', () => { it('returns the existing Snap keyring when one is already present', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const existing = buildKeyringEntry(KeyringTypes.snap); const { addNewKeyring } = mockWithController(mocks, [ buildKeyringEntry(KeyringTypes.hd), @@ -875,7 +876,7 @@ describe('SnapAccountService', () => { }); it('creates a new Snap keyring when none exists', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const { addNewKeyring } = mockWithController(mocks, [ buildKeyringEntry(KeyringTypes.hd), ]); @@ -887,7 +888,7 @@ describe('SnapAccountService', () => { }); it('propagates errors thrown by withController', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.KeyringController.withController.mockImplementation(async () => { throw new Error('boom'); }); @@ -912,7 +913,7 @@ describe('SnapAccountService', () => { ]; it('forwards the message to the matching v2 Snap keyring and returns its result', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const handleKeyringSnapMessage = jest .fn() .mockResolvedValue({ ok: true }); @@ -930,7 +931,7 @@ describe('SnapAccountService', () => { }); it('short-circuits the GetSelectedAccounts method by returning the selected account group accounts', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); @@ -948,7 +949,7 @@ describe('SnapAccountService', () => { }); it('returns an empty array for GetSelectedAccounts when no account group is selected', async () => { - const { service } = setup(); + const { service } = await setup(); const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { method: SnapManageAccountsMethod.GetSelectedAccounts, @@ -959,7 +960,7 @@ describe('SnapAccountService', () => { }); it('throws a dedicated error when no v2 Snap keyring exists for the given Snap', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); mockWithKeyringV2(mocks, {}); await expect( @@ -970,7 +971,7 @@ describe('SnapAccountService', () => { }); it('propagates non-KeyringNotFound errors thrown by the Snap keyring', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); const error = new Error('snap boom'); const handleKeyringSnapMessage = jest.fn().mockRejectedValue(error); mockWithKeyringV2(mocks, { @@ -983,7 +984,7 @@ describe('SnapAccountService', () => { }); it('ensures the v2 keyring exists before forwarding an AccountCreated event', async () => { - const { service, mocks } = setup(); + const { service, mocks } = await setup(); // `#ensureKeyringIsReady` uses `withController` — start with no keyring // so it must create one. const { addNewKeyring } = mockWithController(mocks, []); @@ -1009,7 +1010,7 @@ describe('SnapAccountService', () => { }); it('is exposed as a messenger action', async () => { - const { service, mocks, messenger } = setup(); + const { service, mocks, messenger } = await setup(); const handleKeyringSnapMessage = jest.fn().mockResolvedValue('pong'); mockWithKeyringV2(mocks, { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, @@ -1037,14 +1038,26 @@ describe('SnapAccountService', () => { '00000000-0000-0000-0000-000000000002', ]; - it('forwards the selected accounts to the Snap keyring', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + it('forwards owned accounts to every tracked v2 Snap keyring in parallel', async () => { + const { rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID), buildSnap(MOCK_OTHER_SNAP_ID)], + }); + const setSelectedAccounts1 = jest.fn().mockResolvedValue(undefined); + const setSelectedAccounts2 = jest.fn().mockResolvedValue(undefined); + // Snap A owns the first account; Snap B owns the second. + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { + setSelectedAccounts: setSelectedAccounts1, + hasAccount: (id) => id === MOCK_ACCOUNTS[0], + }, + [MOCK_OTHER_SNAP_ID]: { + setSelectedAccounts: setSelectedAccounts2, + hasAccount: (id) => id === MOCK_ACCOUNTS[1], + }, + }); mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); - expect(service).toBeDefined(); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1052,14 +1065,74 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).toHaveBeenCalledWith(MOCK_GROUP_ID); - expect(setSelectedAccounts).toHaveBeenCalledWith(MOCK_ACCOUNTS); + expect(setSelectedAccounts1).toHaveBeenCalledWith([MOCK_ACCOUNTS[0]]); + expect(setSelectedAccounts2).toHaveBeenCalledWith([MOCK_ACCOUNTS[1]]); }); - it('does nothing when the new group ID is empty', async () => { - const { service, rootMessenger, mocks } = setup(); + it('forwards an empty list to a tracked Snap that owns none of the selected accounts', async () => { + const { rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { + setSelectedAccounts, + hasAccount: () => false, + }, + }); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + + publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); + await flushMicrotasks(); + + expect(setSelectedAccounts).toHaveBeenCalledWith([]); + }); + + it('does nothing when no Snap is tracked', async () => { + const { service, rootMessenger, mocks } = await setup(); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + + publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); + await flushMicrotasks(); + + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); expect(service).toBeDefined(); + }); + + it('silently skips a tracked Snap that has no v2 keyring yet', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + // No keyrings configured → withKeyringV2Unsafe throws KeyringNotFound. + mockWithKeyringV2Unsafe(mocks, {}); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementation(() => undefined); + + publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); + await flushMicrotasks(); + + expect(consoleErrorSpy).not.toHaveBeenCalled(); + expect(service).toBeDefined(); + consoleErrorSpy.mockRestore(); + }); + + it('does nothing when the new group ID is empty', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); publishSelectedAccountGroupChange(rootMessenger, ''); await flushMicrotasks(); @@ -1067,17 +1140,22 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); it('does nothing when the account group is not found', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( undefined, ); - expect(service).toBeDefined(); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1085,31 +1163,75 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).toHaveBeenCalledWith(MOCK_GROUP_ID); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); - it('logs an error when forwarding to the Snap keyring fails', async () => { - const { service, rootMessenger, mocks } = setup(); + it('logs an error when forwarding to a v2 Snap keyring fails, but still forwards to the others', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID), buildSnap(MOCK_OTHER_SNAP_ID)], + }); const error = new Error('forward boom'); - const setSelectedAccounts = jest.fn().mockRejectedValue(error); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const setSelectedAccounts1 = jest.fn().mockRejectedValue(error); + const setSelectedAccounts2 = jest.fn().mockResolvedValue(undefined); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: setSelectedAccounts1 }, + [MOCK_OTHER_SNAP_ID]: { setSelectedAccounts: setSelectedAccounts2 }, + }); mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => undefined); - expect(service).toBeDefined(); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); - expect(setSelectedAccounts).toHaveBeenCalledWith(MOCK_ACCOUNTS); + expect(setSelectedAccounts1).toHaveBeenCalled(); + expect(setSelectedAccounts2).toHaveBeenCalledWith(MOCK_ACCOUNTS); expect(consoleErrorSpy).toHaveBeenCalledWith( - 'Error forwarding selected accounts:', + `Error forwarding selected accounts to Snap "${MOCK_SNAP_ID}":`, error, ); + expect(service).toBeDefined(); + consoleErrorSpy.mockRestore(); + }); + + it('logs a top-level error if forwarding itself rejects unexpectedly', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + const innerError = new Error('inner boom'); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { + setSelectedAccounts: jest.fn().mockRejectedValue(innerError), + }, + }); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + // Force the per-Snap error handler itself to throw on its first + // invocation, so the rejection escapes the inner try/catch and reaches + // the outer `.catch` (the top-level fallback). Subsequent calls + // (including the top-level one) no-op. + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementation(() => undefined); + consoleErrorSpy.mockImplementationOnce(() => { + throw new Error('logger boom'); + }); + publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); + await flushMicrotasks(); + + expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Error forwarding selected accounts:', + expect.any(Error), + ); + expect(service).toBeDefined(); consoleErrorSpy.mockRestore(); }); }); @@ -1121,17 +1243,20 @@ describe('SnapAccountService', () => { '00000000-0000-0000-0000-000000000002', ]; - it('forwards the currently selected account group to the Snap keyring', async () => { - const { service, rootMessenger, mocks } = setup(); + it('forwards the currently selected account group to every tracked v2 Snap keyring', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); - expect(service).toBeDefined(); publishUnlock(rootMessenger); await flushMicrotasks(); @@ -1143,14 +1268,17 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject, ).toHaveBeenCalledWith(MOCK_GROUP_ID); expect(setSelectedAccounts).toHaveBeenCalledWith(MOCK_ACCOUNTS); + expect(service).toBeDefined(); }); it('does nothing when no account group is selected', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue(''); - expect(service).toBeDefined(); publishUnlock(rootMessenger); await flushMicrotasks(); @@ -1158,14 +1286,21 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); - it('logs an error when forwarding to the Snap keyring fails', async () => { - const { service, rootMessenger, mocks } = setup(); + it('logs an error when forwarding to a v2 Snap keyring fails', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); const error = new Error('forward boom'); const setSelectedAccounts = jest.fn().mockRejectedValue(error); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); @@ -1175,17 +1310,16 @@ describe('SnapAccountService', () => { const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => undefined); - expect(service).toBeDefined(); publishUnlock(rootMessenger); await flushMicrotasks(); expect(setSelectedAccounts).toHaveBeenCalledWith(MOCK_ACCOUNTS); expect(consoleErrorSpy).toHaveBeenCalledWith( - 'Error forwarding selected accounts:', + `Error forwarding selected accounts to Snap "${MOCK_SNAP_ID}":`, error, ); - + expect(service).toBeDefined(); consoleErrorSpy.mockRestore(); }); }); @@ -1202,13 +1336,16 @@ describe('SnapAccountService', () => { ]; it('forwards the accounts from the event payload when the affected group is the selected one', async () => { - const { service, rootMessenger, mocks } = setup(); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); - expect(service).toBeDefined(); publishEvent(rootMessenger, buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS)); await flushMicrotasks(); @@ -1217,16 +1354,19 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); expect(setSelectedAccounts).toHaveBeenCalledWith(MOCK_ACCOUNTS); + expect(service).toBeDefined(); }); it('does nothing when the affected group is not the selected one', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( OTHER_GROUP_ID, ); - expect(service).toBeDefined(); publishEvent(rootMessenger, buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS)); await flushMicrotasks(); @@ -1234,15 +1374,20 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); it('does nothing when no account group is selected', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue(''); - expect(service).toBeDefined(); publishEvent(rootMessenger, buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS)); await flushMicrotasks(); @@ -1250,7 +1395,10 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); }); @@ -1258,14 +1406,17 @@ describe('SnapAccountService', () => { const MOCK_GROUP_ID = 'keyring:01JABC/group-1' as AccountGroupId; const OTHER_GROUP_ID = 'keyring:01JABC/group-2' as AccountGroupId; - it('clears the selected accounts when the removed group is the selected one', async () => { - const { service, rootMessenger, mocks } = setup(); + it('clears the selected accounts on every tracked v2 Snap keyring when the removed group is the selected one', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); - expect(service).toBeDefined(); publishAccountGroupRemoved(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1274,16 +1425,19 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); expect(setSelectedAccounts).toHaveBeenCalledWith([]); + expect(service).toBeDefined(); }); it('does nothing when the removed group is not the selected one', async () => { - const { service, rootMessenger, mocks } = setup(); - const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); - mockLegacySnapKeyring(mocks, { setSelectedAccounts }); + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, + }); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( OTHER_GROUP_ID, ); - expect(service).toBeDefined(); publishAccountGroupRemoved(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1291,7 +1445,10 @@ describe('SnapAccountService', () => { expect( mocks.AccountTreeController.getAccountGroupObject, ).not.toHaveBeenCalled(); - expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(service).toBeDefined(); }); }); }); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 338a6d03a1..f459dbb41b 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -12,6 +12,7 @@ import type { KeyringControllerUnlockEvent, KeyringControllerWithControllerAction, KeyringControllerWithKeyringV2Action, + KeyringControllerWithKeyringV2UnsafeAction, KeyringEntry, } from '@metamask/keyring-controller'; import { @@ -95,6 +96,7 @@ type AllowedActions = | KeyringControllerGetStateAction | KeyringControllerWithControllerAction | KeyringControllerWithKeyringV2Action + | KeyringControllerWithKeyringV2UnsafeAction | AccountTreeControllerGetAccountGroupObjectAction | AccountTreeControllerGetSelectedAccountGroupAction; @@ -603,20 +605,56 @@ export class SnapAccountService { return; } - const forwardSelectedAccounts = async (): Promise => { - if (accounts.length) { - log( - `Forwarding selected accounts (from "${groupId}"): ${accounts.join(', ')}`, - ); - } else { - log(`Clearing selected accounts (from "${groupId}")`); - } + if (accounts.length) { + log( + `Forwarding selected accounts (from "${groupId}"): ${accounts.join(', ')}`, + ); + } else { + log(`Clearing selected accounts (from "${groupId}")`); + } - const snapKeyring = await this.getLegacySnapKeyring(); - await snapKeyring.setSelectedAccounts(accounts); + const forwardSelectedAccounts = async (): Promise => { + await Promise.all( + this.#tracker.getSnaps().map(async (snapId) => { + try { + // We can safely invoke this method without taking the controller lock + // because it should not mutate the keyring state. So we can use + // `withKeyringV2Unsafe` in this case. + await this.#messenger.call( + 'KeyringController:withKeyringV2Unsafe', + { + filter: (keyring): keyring is SnapKeyring => + isSnapKeyring(keyring) && keyring.snapId === snapId, + }, + async ({ keyring }) => { + const snapKeyring = keyring as SnapKeyring; // Forced to cast here as generic does not work when using the messenger. + + // The group's accounts may belong to several Snaps; only + // forward the subset this Snap actually owns. An empty + // subset still gets forwarded to explicitly clear the + // Snap selected accounts. + await snapKeyring.setSelectedAccounts( + accounts.filter((id) => snapKeyring.hasAccount(id)), + ); + }, + ); + } catch (error) { + // Tracked Snaps without a v2 keyring yet are expected — + // forwarding will resume on the next event once `ensureReady` + // has run. + if (!isKeyringNotFoundError(error)) { + console.error( + `Error forwarding selected accounts to Snap "${snapId}":`, + error, + ); + } + } + }), + ); }; - // There is nothing we can do if forwarding fails. This will auto-recover on the next relevant event. + // There is nothing we can do if forwarding fails. This will auto-recover on + // the next relevant event. forwardSelectedAccounts().catch((error) => { console.error('Error forwarding selected accounts:', error); }); From 992b4ea5306c7a8833ee0237f1085afa8e761f82 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 10:21:09 +0200 Subject: [PATCH 10/45] refactor: refactor withKeyringV2* calls --- .../src/SnapAccountService.ts | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index f459dbb41b..18d1991e6b 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -466,6 +466,75 @@ export class SnapAccountService { ); } + /** + * Shared body for {@link SnapAccountService.#withKeyringV2} and + * {@link SnapAccountService.#withKeyringV2Unsafe}. Hides the per-Snap + * filter and the cast back to {@link SnapKeyring} (the messenger action's + * callback receives a generic `Keyring`; the selector's type predicate + * doesn't flow through the messenger's generics). + * + * @param action - The messenger action to invoke. + * @param snapId - The Snap ID to look up the keyring for. + * @param operation - The operation to run with the matching keyring. + * @returns The result of the operation. + */ + async #withKeyringV2Call( + action: + | 'KeyringController:withKeyringV2' + | 'KeyringController:withKeyringV2Unsafe', + snapId: SnapId, + operation: (keyring: SnapKeyring) => Promise, + ): Promise { + return this.#messenger.call( + action, + { + filter: (keyring): keyring is SnapKeyring => + isSnapKeyring(keyring) && keyring.snapId === snapId, + }, + async ({ keyring }) => operation(keyring as SnapKeyring), + ) as Result; + } + + /** + * Runs an operation against the v2 Snap keyring for the given Snap, under + * the `KeyringController` mutex. Throws `KeyringNotFound` if no v2 Snap + * keyring exists for the given Snap. + * + * @param snapId - The Snap ID to look up the keyring for. + * @param operation - The operation to run with the matching keyring. + * @returns The result of the operation. + */ + async #withKeyringV2( + snapId: SnapId, + operation: (keyring: SnapKeyring) => Promise, + ): Promise { + return this.#withKeyringV2Call( + 'KeyringController:withKeyringV2', + snapId, + operation, + ); + } + + /** + * Lock-free variant of {@link SnapAccountService.#withKeyringV2}. Only use + * for operations that do not mutate keyring or controller state — see + * `KeyringController.withKeyringV2Unsafe` for the contract. + * + * @param snapId - The Snap ID to look up the keyring for. + * @param operation - The operation to run with the matching keyring. + * @returns The result of the operation. + */ + async #withKeyringV2Unsafe( + snapId: SnapId, + operation: (keyring: SnapKeyring) => Promise, + ): Promise { + return this.#withKeyringV2Call( + 'KeyringController:withKeyringV2Unsafe', + snapId, + operation, + ); + } + /** * Atomically gets-or-creates the legacy (v1) Snap keyring — the keyring * associated with {@link KeyringTypes.snap}. @@ -536,11 +605,6 @@ export class SnapAccountService { `Forwarding message "${event}" from Snap "${snapId}" to its keyring...`, ); - const isSnapKeyringForThisSnap = ( - keyring: Keyring, - ): keyring is SnapKeyring => - isSnapKeyring(keyring) && keyring.snapId === snapId; - // We can create a new keyring if the message is an AccountCreated event. const isAccountCreatedMessage = event === KeyringEvent.AccountCreated; @@ -554,17 +618,9 @@ export class SnapAccountService { // This part of the flow relies on v1 flows, but v2 keyrings are compatible with those messages // too. try { - const result = await this.#messenger.call( - 'KeyringController:withKeyringV2', - { filter: (keyring) => isSnapKeyringForThisSnap(keyring) }, - async ({ keyring }) => { - const snapKeyring = keyring as SnapKeyring; // Forced to cast here as generic does not work when using the messenger. - - return await snapKeyring.handleKeyringSnapMessage(message); - }, + return await this.#withKeyringV2(snapId, async (keyring) => + keyring.handleKeyringSnapMessage(message), ); - - return result as Json; } catch (error) { if (isKeyringNotFoundError(error)) { log( @@ -620,24 +676,15 @@ export class SnapAccountService { // We can safely invoke this method without taking the controller lock // because it should not mutate the keyring state. So we can use // `withKeyringV2Unsafe` in this case. - await this.#messenger.call( - 'KeyringController:withKeyringV2Unsafe', - { - filter: (keyring): keyring is SnapKeyring => - isSnapKeyring(keyring) && keyring.snapId === snapId, - }, - async ({ keyring }) => { - const snapKeyring = keyring as SnapKeyring; // Forced to cast here as generic does not work when using the messenger. - - // The group's accounts may belong to several Snaps; only - // forward the subset this Snap actually owns. An empty - // subset still gets forwarded to explicitly clear the - // Snap selected accounts. - await snapKeyring.setSelectedAccounts( - accounts.filter((id) => snapKeyring.hasAccount(id)), - ); - }, - ); + await this.#withKeyringV2Unsafe(snapId, async (keyring) => { + // The group's accounts may belong to several Snaps; only + // forward the subset this Snap actually owns. An empty + // subset still gets forwarded to explicitly clear the + // Snap selected accounts. + await keyring.setSelectedAccounts( + accounts.filter((id) => keyring.hasAccount(id)), + ); + }); } catch (error) { // Tracked Snaps without a v2 keyring yet are expected — // forwarding will resume on the next event once `ensureReady` From b1119d25f4e5068731c9f6c2031c2018d3ace56a Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 10:36:04 +0200 Subject: [PATCH 11/45] refactor: filters accounts per Snap Id for getSelectedAccounts --- .../src/SnapAccountService.test.ts | 15 ++++++++++++--- .../src/SnapAccountService.ts | 7 +++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 14d248a37f..f8d35e3485 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -930,7 +930,7 @@ describe('SnapAccountService', () => { expect(result).toStrictEqual({ ok: true }); }); - it('short-circuits the GetSelectedAccounts method by returning the selected account group accounts', async () => { + it('short-circuits GetSelectedAccounts by returning only the selected group accounts the Snap actually owns', async () => { const { service, mocks } = await setup(); mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, @@ -938,18 +938,27 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + // The Snap only owns the first account of the selected group. + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { + hasAccount: (id) => id === MOCK_ACCOUNTS[0], + }, + }); const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { method: SnapManageAccountsMethod.GetSelectedAccounts, params: {}, } as unknown as SnapMessage); - expect(result).toStrictEqual(MOCK_ACCOUNTS); + expect(result).toStrictEqual([MOCK_ACCOUNTS[0]]); expect(mocks.KeyringController.withKeyringV2).not.toHaveBeenCalled(); }); it('returns an empty array for GetSelectedAccounts when no account group is selected', async () => { - const { service } = await setup(); + const { service, mocks } = await setup(); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { hasAccount: () => true }, + }); const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { method: SnapManageAccountsMethod.GetSelectedAccounts, diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 18d1991e6b..1c7ebb69ba 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -595,8 +595,11 @@ export class SnapAccountService { ): Promise { // Handle specific methods first. if (message.method === SnapManageAccountsMethod.GetSelectedAccounts) { - return ( - this.#getAccountGroup(this.#getSelectedAccountGroupId())?.accounts ?? [] + const groupId = this.#getSelectedAccountGroupId(); + const accounts = this.#getAccountGroup(groupId)?.accounts ?? []; + + return await this.#withKeyringV2Unsafe(snapId, async (keyring) => + accounts.filter((id) => keyring.hasAccount(id)), ); } From 851ca8e034a34520ea00f063e02af85342502dac Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 15:03:45 +0200 Subject: [PATCH 12/45] chore: move migration logs --- packages/snap-account-service/src/SnapAccountService.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 1c7ebb69ba..9361c269f5 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -375,8 +375,6 @@ export class SnapAccountService { * safe to call concurrently. */ async #migrate(): Promise { - log('Migration started...'); - await this.#messenger.call( 'KeyringController:withController', async (controller) => { @@ -390,6 +388,8 @@ export class SnapAccountService { return; } + log('Migration started...'); + // The legacy Snap keyring has never been a true `EthKeyring` so we // need to cast it to `unknown` first. const legacySnapKeyring = @@ -432,10 +432,10 @@ export class SnapAccountService { // Remove the legacy Snap keyring after migration. log('Removing legacy Snap keyring...'); await controller.removeKeyring(legacySnapKeyringEntry.metadata.id); + + log('Migration completed!'); }, ); - - log('Migration completed!'); } /** From 94a8c4a04aba522a176d147a71a1c73d68627ff8 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 15:05:43 +0200 Subject: [PATCH 13/45] refactor!: remove getLegacySnapKeyring (not usable after running the migration) --- packages/snap-account-service/CHANGELOG.md | 5 ++ .../SnapAccountService-method-action-types.ts | 12 ----- .../src/SnapAccountService.test.ts | 39 +------------- .../src/SnapAccountService.ts | 51 ------------------- 4 files changed, 6 insertions(+), 101 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 19658b8000..1b6c655d80 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -49,6 +49,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Selected-account forwarding now targets v2 Snap keyrings. - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. +### Removed + +- **BREAKING:** Removed `getLegacySnapKeyring` ([#8732](https://github.com/MetaMask/core/pull/8732)) + - The legacy Snap keyring should not be used anymore after the migration has completed. + ### Changed - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts index fd6bccbbfe..1c08a74df2 100644 --- a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts +++ b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts @@ -48,17 +48,6 @@ export type SnapAccountServiceMigrateAction = { handler: SnapAccountService['migrate']; }; -/** - * Atomically gets-or-creates the legacy (v1) Snap keyring — the keyring - * associated with {@link KeyringTypes.snap}. - * - * @returns The existing or newly-created Snap keyring instance. - */ -export type SnapAccountServiceGetLegacySnapKeyringAction = { - type: `SnapAccountService:getLegacySnapKeyring`; - handler: SnapAccountService['getLegacySnapKeyring']; -}; - /** * Handle a message from a Snap. * @@ -78,5 +67,4 @@ export type SnapAccountServiceMethodActions = | SnapAccountServiceGetSnapsAction | SnapAccountServiceEnsureReadyAction | SnapAccountServiceMigrateAction - | SnapAccountServiceGetLegacySnapKeyringAction | SnapAccountServiceHandleKeyringSnapMessageAction; diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index f8d35e3485..89ee9bb318 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -1,6 +1,6 @@ import type { AccountGroupId } from '@metamask/account-api'; import { SNAP_KEYRING_TYPE } from '@metamask/eth-snap-keyring'; -import type { SnapKeyring, SnapMessage } from '@metamask/eth-snap-keyring'; +import type { SnapMessage } from '@metamask/eth-snap-keyring'; import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; import { KeyringEvent } from '@metamask/keyring-api'; import { KeyringType } from '@metamask/keyring-api/v2'; @@ -860,43 +860,6 @@ describe('SnapAccountService', () => { }); }); - describe('getLegacySnapKeyring', () => { - it('returns the existing Snap keyring when one is already present', async () => { - const { service, mocks } = await setup(); - const existing = buildKeyringEntry(KeyringTypes.snap); - const { addNewKeyring } = mockWithController(mocks, [ - buildKeyringEntry(KeyringTypes.hd), - existing, - ]); - - const result = await service.getLegacySnapKeyring(); - - expect(result).toBe(existing.keyring as unknown as SnapKeyring); - expect(addNewKeyring).not.toHaveBeenCalled(); - }); - - it('creates a new Snap keyring when none exists', async () => { - const { service, mocks } = await setup(); - const { addNewKeyring } = mockWithController(mocks, [ - buildKeyringEntry(KeyringTypes.hd), - ]); - - const result = await service.getLegacySnapKeyring(); - - expect(addNewKeyring).toHaveBeenCalledWith(KeyringTypes.snap); - expect(result.type).toBe(KeyringTypes.snap); - }); - - it('propagates errors thrown by withController', async () => { - const { service, mocks } = await setup(); - mocks.KeyringController.withController.mockImplementation(async () => { - throw new Error('boom'); - }); - - await expect(service.getLegacySnapKeyring()).rejects.toThrow('boom'); - }); - }); - describe('handleKeyringSnapMessage', () => { const MOCK_MESSAGE = { method: KeyringEvent.AccountUpdated, diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 9361c269f5..645da69a4f 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -13,7 +13,6 @@ import type { KeyringControllerWithControllerAction, KeyringControllerWithKeyringV2Action, KeyringControllerWithKeyringV2UnsafeAction, - KeyringEntry, } from '@metamask/keyring-controller'; import { isKeyringNotFoundError, @@ -40,7 +39,6 @@ import type { Json } from '@metamask/utils'; import { projectLogger as log } from './logger'; import type { SnapAccountServiceEnsureReadyAction, - SnapAccountServiceGetLegacySnapKeyringAction, SnapAccountServiceGetSnapsAction, SnapAccountServiceHandleKeyringSnapMessageAction, SnapAccountServiceMigrateAction, @@ -71,7 +69,6 @@ export const serviceName = 'SnapAccountService'; const MESSENGER_EXPOSED_METHODS = [ 'ensureReady', 'getSnaps', - 'getLegacySnapKeyring', 'handleKeyringSnapMessage', 'migrate', ] as const; @@ -82,7 +79,6 @@ const MESSENGER_EXPOSED_METHODS = [ export type SnapAccountServiceActions = | SnapAccountServiceEnsureReadyAction | SnapAccountServiceGetSnapsAction - | SnapAccountServiceGetLegacySnapKeyringAction | SnapAccountServiceHandleKeyringSnapMessageAction | SnapAccountServiceMigrateAction; @@ -535,53 +531,6 @@ export class SnapAccountService { ); } - /** - * Atomically gets-or-creates the legacy (v1) Snap keyring — the keyring - * associated with {@link KeyringTypes.snap}. - * - * @returns The existing or newly-created Snap keyring instance. - */ - async getLegacySnapKeyring(): Promise { - type Result = { - snapKeyring: LegacySnapKeyring; - }; - - // `KeyringController:withController` forbids returning a direct keyring - // reference (it checks the result via `Object.is`), so we smuggle the - // instance out wrapped in an object and unwrap it after the call. - // NOTE: This violates the abstraction of `KeyringController:withController`, but this - // is how we currently interact with the legacy Snap keyring. Once we migrate it to - // the Snap keyring v2, we won't be using the same pattern. - const result = await this.#messenger.call( - 'KeyringController:withController', - async (controller): Promise => { - let snapKeyring: KeyringEntry['keyring'] | undefined; - - const found = controller.keyrings.find(({ keyring }) => - isLegacySnapKeyring(keyring), - ); - if (found) { - snapKeyring = found.keyring; - } - - if (!snapKeyring) { - const { - keyring: newSnapKeyring, - metadata: { id }, - } = await controller.addNewKeyring(KeyringTypes.snap); - snapKeyring = newSnapKeyring; - - log(`Legacy Snap keyring created. ("${id}")`); - } - - // The legacy Snap keyring is not compatible with `EthKeyring`, so we need to cast here. - return { snapKeyring } as unknown as Result; - }, - ); - - return (result as Result).snapKeyring; - } - /** * Handle a message from a Snap. * From 262b8903de82c0894ff80a53a365374bb311209a Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 16:10:41 +0200 Subject: [PATCH 14/45] chore: fix changelog --- packages/snap-account-service/CHANGELOG.md | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 1b6c655d80..efe55c0be8 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) + - The migration is guaranteed to be run when using `ensureReady`. + - If the migration is not successful, it will get retried everytime we need to interact with any Snap keyring (v2) instances. + - It is conccurent-free and can safely be called by multiple execution flows. + - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. + - Selected-account forwarding now targets v2 Snap keyrings. + - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. + +### Removed + +- **BREAKING:** Removed `getLegacySnapKeyring` ([#8732](https://github.com/MetaMask/core/pull/8732)) + - The legacy Snap keyring should not be used anymore after the migration has completed. + ## [0.2.0] ### Added @@ -18,7 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `SnapAccountService` ([#8414](https://github.com/MetaMask/core/pull/8414)) -- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8725](https://github.com/MetaMask/core/pull/8725)), ([#8732](https://github.com/MetaMask/core/pull/8732)) +- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8725](https://github.com/MetaMask/core/pull/8725)) - Waits for the Snap platform to be ready and for a Snap keyring to appear in `KeyringController` state before allowing Snap account operations. - Callers must ensure `init()` has run and the Snap is currently installed, enabled, non-blocked, and declares `endowment:keyring`. - `SnapAccountService.ensureReady` now awaits the watcher, so it only resolves once both conditions hold (or rejects if the Snap keyring does not appear within the configured timeout). @@ -41,24 +56,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - This logic used to live on the clients. - The service messenger now requires the `KeyringController:unlock`, `AccountTreeController:selectedAccountGroupChange`, `AccountTreeController:accountGroup{Created,Updated,Removed}` events. - The service messenger now requires the `AccountTreeController:getSelectedAccountGroup` and `AccountTreeController:getAccountGroupObject` actions. -- Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) - - The migration is guaranteed to be run when using `ensureReady`. - - If the migration is not successful, it will get retried everytime we need to interact with any Snap keyring (v2) instances. - - It is conccurent-free and can safely be called by multiple execution flows. - - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. - - Selected-account forwarding now targets v2 Snap keyrings. - - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. - -### Removed - -- **BREAKING:** Removed `getLegacySnapKeyring` ([#8732](https://github.com/MetaMask/core/pull/8732)) - - The legacy Snap keyring should not be used anymore after the migration has completed. ### Changed - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) - Bump `@metamask/account-tree-controller` from `^7.3.0` to `^7.4.0` ([#8783](https://github.com/MetaMask/core/pull/8783)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.2.0...HEAD [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.1.0...@metamask/snap-account-service@0.2.0 [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/snap-account-service@0.1.0 From 6d71351f16834c350ff19a7132dafbfe214759ae Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Wed, 13 May 2026 18:57:28 +0200 Subject: [PATCH 15/45] chore: fix changelogs --- packages/multichain-account-service/CHANGELOG.md | 2 +- packages/snap-account-service/CHANGELOG.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/multichain-account-service/CHANGELOG.md b/packages/multichain-account-service/CHANGELOG.md index 6d4e6df1b1..507d34acf2 100644 --- a/packages/multichain-account-service/CHANGELOG.md +++ b/packages/multichain-account-service/CHANGELOG.md @@ -9,13 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Replace `KeyringController:withKeyring` with `KeyringController:withKeyringV2` for the Snap account providers ([#8732](https://github.com/MetaMask/core/pull/8732)) - Bump `@metamask/snap-account-service` from `^0.1.0` to `^0.2.0` ([#8844](https://github.com/MetaMask/core/pull/8844)) ## [10.0.0] ### Changed -- **BREAKING:** Replace `KeyringController:withKeyring` with `KeyringController:withKeyringV2` for the Snap account providers ([#8732](https://github.com/MetaMask/core/pull/8732)) - **BREAKING:** The service messenger now requires the `SnapAccountService:ensureReady` action to be declared ([#8715](https://github.com/MetaMask/core/pull/8715)) - **BREAKING:** Delegate Snap platform readiness to `@metamask/snap-account-service` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8752](https://github.com/MetaMask/core/pull/8752)) - Removed `MultichainAccountService.ensureCanUseSnapPlatform()` method and the corresponding `MultichainAccountService:ensureCanUseSnapPlatform` messenger action. diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index efe55c0be8..177749c8dd 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Selected-account forwarding now targets v2 Snap keyrings. - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. +### Changed + +- `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available ([#8732](https://github.com/MetaMask/core/pull/8732)) + ### Removed - **BREAKING:** Removed `getLegacySnapKeyring` ([#8732](https://github.com/MetaMask/core/pull/8732)) @@ -38,7 +42,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Callers must ensure `init()` has run and the Snap is currently installed, enabled, non-blocked, and declares `endowment:keyring`. - `SnapAccountService.ensureReady` now awaits the watcher, so it only resolves once both conditions hold (or rejects if the Snap keyring does not appear within the configured timeout). - `SnapAccountService.ensureReady` now throws `Unknown snap: ""` when called with a Snap ID that isn't tracked as an account-management Snap. - - `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available. - Add `config` option to `SnapAccountService` constructor with a `snapPlatformWatcher` field exposing `ensureOnboardingComplete` and `snapKeyringWaitTimeoutMs` ([#8715](https://github.com/MetaMask/core/pull/8715)) - Export `SnapAccountServiceConfig` and `SnapPlatformWatcherConfig` types. - Add `@metamask/keyring-controller` dependency ([#8715](https://github.com/MetaMask/core/pull/8715)) @@ -62,5 +65,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) - Bump `@metamask/account-tree-controller` from `^7.3.0` to `^7.4.0` ([#8783](https://github.com/MetaMask/core/pull/8783)) +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.2.0...HEAD [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.1.0...@metamask/snap-account-service@0.2.0 [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/snap-account-service@0.1.0 From 9b0fce074b0b9756a53eb20bf16f1efa5f14ca6b Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 18 May 2026 16:36:33 +0200 Subject: [PATCH 16/45] refactor: bump eth-snap-keyring + use isSnapKeyring --- packages/accounts-controller/package.json | 2 +- .../multichain-account-service/package.json | 2 +- .../src/providers/SnapAccountProvider.ts | 15 +-------------- packages/snap-account-service/package.json | 2 +- .../src/SnapAccountService.ts | 13 +------------ yarn.lock | 18 +++++++++--------- 6 files changed, 14 insertions(+), 38 deletions(-) diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index 5d59260faa..da8f810e66 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -55,7 +55,7 @@ "dependencies": { "@ethereumjs/util": "^9.1.0", "@metamask/base-controller": "^9.1.0", - "@metamask/eth-snap-keyring": "^22.0.1", + "@metamask/eth-snap-keyring": "^22.1.0", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^25.5.0", "@metamask/keyring-internal-api": "^11.0.1", diff --git a/packages/multichain-account-service/package.json b/packages/multichain-account-service/package.json index 4025daf5d3..96a96a120d 100644 --- a/packages/multichain-account-service/package.json +++ b/packages/multichain-account-service/package.json @@ -56,7 +56,7 @@ "@ethereumjs/util": "^9.1.0", "@metamask/accounts-controller": "^38.1.1", "@metamask/base-controller": "^9.1.0", - "@metamask/eth-snap-keyring": "^22.0.1", + "@metamask/eth-snap-keyring": "^22.1.0", "@metamask/key-tree": "^10.1.1", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^25.5.0", diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts index 405df61ab5..e08b8356ef 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts @@ -1,7 +1,7 @@ import { assertIsBip44Account } from '@metamask/account-api'; import type { Bip44Account } from '@metamask/account-api'; import type { TraceCallback, TraceRequest } from '@metamask/controller-utils'; -import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; +import type { SnapKeyring as SnapKeyringV2, isSnapKeyring } from '@metamask/eth-snap-keyring/v2'; import { AccountCreationType, assertCreateAccountOptionIsSupported, @@ -13,7 +13,6 @@ import type { EntropySourceId, KeyringAccount, } from '@metamask/keyring-api'; -import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringMetadata } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringClient } from '@metamask/keyring-snap-client'; @@ -72,18 +71,6 @@ export type SnapAccountProviderConfig = { }; }; -// TODO: Move this in `eth-snap-keyring/v2` package? -/** - * Checks if a given keyring is a Snap keyring (v2). - * - * @param keyring - The keyring to check. - * @returns `true` if the keyring is a Snap keyring (v2), `false` otherwise. - */ -function isSnapKeyring(keyring: Keyring): keyring is SnapKeyringV2 { - // Using `KeyringType.Snap` (used for v2). - return keyring.type === KeyringType.Snap; -} - export abstract class SnapAccountProvider extends BaseBip44AccountProvider { readonly snapId: SnapId; diff --git a/packages/snap-account-service/package.json b/packages/snap-account-service/package.json index 835f031167..72e5b5013f 100644 --- a/packages/snap-account-service/package.json +++ b/packages/snap-account-service/package.json @@ -55,7 +55,7 @@ "dependencies": { "@metamask/account-api": "^1.0.4", "@metamask/account-tree-controller": "^7.4.0", - "@metamask/eth-snap-keyring": "^22.0.1", + "@metamask/eth-snap-keyring": "^22.1.0", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^25.5.0", "@metamask/keyring-snap-sdk": "^9.0.1", diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 645da69a4f..b891b9f21c 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -3,7 +3,7 @@ import type { SnapKeyring as LegacySnapKeyring, SnapMessage, } from '@metamask/eth-snap-keyring'; -import { SnapKeyring, SnapKeyringState } from '@metamask/eth-snap-keyring/v2'; +import { SnapKeyring, SnapKeyringState, isSnapKeyring } from '@metamask/eth-snap-keyring/v2'; import { KeyringEvent } from '@metamask/keyring-api'; import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; import type { @@ -157,17 +157,6 @@ function isLegacySnapKeyring(keyring: { return keyring.type === KeyringTypes.snap; } -/** - * Checks if a given keyring is a Snap keyring (v2). - * - * @param keyring - The keyring to check. - * @returns `true` if the keyring is a Snap keyring (v2), `false` otherwise. - */ -function isSnapKeyring(keyring: Keyring): keyring is SnapKeyring { - // Using `KeyringType.Snap` (used for v2). - return keyring.type === KeyringType.Snap; -} - /** * Service responsible for managing account management snaps. */ diff --git a/yarn.lock b/yarn.lock index 3489069ede..2aa31b6206 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2575,7 +2575,7 @@ __metadata: "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/eth-snap-keyring": "npm:^22.0.1" + "@metamask/eth-snap-keyring": "npm:^22.1.0" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^25.5.0" "@metamask/keyring-internal-api": "npm:^11.0.1" @@ -3889,17 +3889,17 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-snap-keyring@npm:^22.0.1": - version: 22.0.1 - resolution: "@metamask/eth-snap-keyring@npm:22.0.1" +"@metamask/eth-snap-keyring@npm:^22.1.0": + version: 22.1.0 + resolution: "@metamask/eth-snap-keyring@npm:22.1.0" dependencies: "@ethereumjs/tx": "npm:^5.4.0" "@metamask/eth-sig-util": "npm:^8.2.0" "@metamask/keyring-internal-api": "npm:^11.0.1" "@metamask/keyring-internal-snap-client": "npm:^10.0.3" - "@metamask/keyring-sdk": "npm:^2.0.2" + "@metamask/keyring-sdk": "npm:^2.1.1" "@metamask/keyring-snap-sdk": "npm:^9.0.1" - "@metamask/keyring-utils": "npm:^3.2.0" + "@metamask/keyring-utils": "npm:^3.3.1" "@metamask/messenger": "npm:^1.1.1" "@metamask/snaps-controllers": "npm:^19.0.1" "@metamask/snaps-sdk": "npm:^11.0.0" @@ -3911,7 +3911,7 @@ __metadata: uuid: "npm:^9.0.1" peerDependencies: "@metamask/keyring-api": ^23.0.0 - checksum: 10/138a17918ba3fae5788f8c80fe48df959055d8e0567ae62114ae7754f7a0b812bc9efe7f211c0ee0f303cc1d6b898b9049d4743d30f947e5075ac8f273168a1c + checksum: 10/91082e01cda399ab054e6015577e83f8654228015b9ec44e9ed759200a3ccc3ae5af8874ed0bc98e347b76eefbef62fd4a9052ca881f8f9bfa1eeefaf24123d1 languageName: node linkType: hard @@ -4576,7 +4576,7 @@ __metadata: "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/eth-hd-keyring": "npm:^14.1.1" - "@metamask/eth-snap-keyring": "npm:^22.0.1" + "@metamask/eth-snap-keyring": "npm:^22.1.0" "@metamask/key-tree": "npm:^10.1.1" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^25.5.0" @@ -5464,7 +5464,7 @@ __metadata: "@metamask/account-api": "npm:^1.0.4" "@metamask/account-tree-controller": "npm:^7.4.0" "@metamask/auto-changelog": "npm:^6.1.0" - "@metamask/eth-snap-keyring": "npm:^22.0.1" + "@metamask/eth-snap-keyring": "npm:^22.1.0" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^25.5.0" "@metamask/keyring-snap-sdk": "npm:^9.0.1" From 441ec237c0eaa4f6b7fe1754f99c8b8a05815f73 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 18 May 2026 16:54:35 +0200 Subject: [PATCH 17/45] chore: lint --- .../src/providers/SnapAccountProvider.ts | 3 ++- packages/snap-account-service/src/SnapAccountService.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts index e08b8356ef..b7721af0f7 100644 --- a/packages/multichain-account-service/src/providers/SnapAccountProvider.ts +++ b/packages/multichain-account-service/src/providers/SnapAccountProvider.ts @@ -1,7 +1,8 @@ import { assertIsBip44Account } from '@metamask/account-api'; import type { Bip44Account } from '@metamask/account-api'; import type { TraceCallback, TraceRequest } from '@metamask/controller-utils'; -import type { SnapKeyring as SnapKeyringV2, isSnapKeyring } from '@metamask/eth-snap-keyring/v2'; +import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; +import { isSnapKeyring } from '@metamask/eth-snap-keyring/v2'; import { AccountCreationType, assertCreateAccountOptionIsSupported, diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index b891b9f21c..e624b282d0 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -3,9 +3,13 @@ import type { SnapKeyring as LegacySnapKeyring, SnapMessage, } from '@metamask/eth-snap-keyring'; -import { SnapKeyring, SnapKeyringState, isSnapKeyring } from '@metamask/eth-snap-keyring/v2'; +import { + SnapKeyring, + SnapKeyringState, + isSnapKeyring, +} from '@metamask/eth-snap-keyring/v2'; import { KeyringEvent } from '@metamask/keyring-api'; -import { Keyring, KeyringType } from '@metamask/keyring-api/v2'; +import { KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, From 3ab5f83aa9833d900317d8bc5c95e5711e60c94b Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 18 May 2026 17:27:56 +0200 Subject: [PATCH 18/45] chore: changelog --- packages/accounts-controller/CHANGELOG.md | 4 ++++ packages/multichain-account-service/CHANGELOG.md | 1 + packages/snap-account-service/CHANGELOG.md | 1 + 3 files changed, 6 insertions(+) diff --git a/packages/accounts-controller/CHANGELOG.md b/packages/accounts-controller/CHANGELOG.md index eb53fa85f3..bbc3be047e 100644 --- a/packages/accounts-controller/CHANGELOG.md +++ b/packages/accounts-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732)) + ## [38.1.1] ### Changed diff --git a/packages/multichain-account-service/CHANGELOG.md b/packages/multichain-account-service/CHANGELOG.md index 507d34acf2..a94ac76eb2 100644 --- a/packages/multichain-account-service/CHANGELOG.md +++ b/packages/multichain-account-service/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Replace `KeyringController:withKeyring` with `KeyringController:withKeyringV2` for the Snap account providers ([#8732](https://github.com/MetaMask/core/pull/8732)) - Bump `@metamask/snap-account-service` from `^0.1.0` to `^0.2.0` ([#8844](https://github.com/MetaMask/core/pull/8844)) +- Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732)) ## [10.0.0] diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 177749c8dd..9f26341641 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available ([#8732](https://github.com/MetaMask/core/pull/8732)) +- Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732)) ### Removed From f39f26bd90dbd5811db92c06bb4b552e66b44a37 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 18 May 2026 17:50:14 +0200 Subject: [PATCH 19/45] fix: remove old action :getLegacySnapKeyring export --- packages/snap-account-service/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/snap-account-service/src/index.ts b/packages/snap-account-service/src/index.ts index 1713e9e6ce..8f8022612a 100644 --- a/packages/snap-account-service/src/index.ts +++ b/packages/snap-account-service/src/index.ts @@ -9,7 +9,6 @@ export type { export type { SnapAccountServiceEnsureReadyAction, SnapAccountServiceGetSnapsAction, - SnapAccountServiceGetLegacySnapKeyringAction, SnapAccountServiceHandleKeyringSnapMessageAction, } from './SnapAccountService-method-action-types'; export { SnapPlatformWatcher } from './SnapPlatformWatcher'; From 61b84463a2e4cb62fc393c135d1d8e33e924dd0b Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 18 May 2026 21:57:32 +0200 Subject: [PATCH 20/45] fix: add missing export --- packages/snap-account-service/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/snap-account-service/src/index.ts b/packages/snap-account-service/src/index.ts index 8f8022612a..b76df66284 100644 --- a/packages/snap-account-service/src/index.ts +++ b/packages/snap-account-service/src/index.ts @@ -10,6 +10,7 @@ export type { SnapAccountServiceEnsureReadyAction, SnapAccountServiceGetSnapsAction, SnapAccountServiceHandleKeyringSnapMessageAction, + SnapAccountServiceMigrateAction, } from './SnapAccountService-method-action-types'; export { SnapPlatformWatcher } from './SnapPlatformWatcher'; export type { SnapPlatformWatcherConfig } from './SnapPlatformWatcher'; From a4b03df125a0328af7f72bed2c4053159e74ce9e Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 21 May 2026 11:07:42 +0200 Subject: [PATCH 21/45] fix: watcher no longer waits for legacy Snap keyring --- eslint-suppressions.json | 6 +- .../src/SnapAccountService.test.ts | 74 +------ .../src/SnapPlatformWatcher.test.ts | 202 +----------------- .../src/SnapPlatformWatcher.ts | 109 +--------- 4 files changed, 8 insertions(+), 383 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 5ba155be96..196ccc6324 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -2156,12 +2156,12 @@ }, "packages/snap-account-service/src/SnapPlatformWatcher.test.ts": { "no-restricted-syntax": { - "count": 2 + "count": 1 } }, "packages/snap-account-service/src/SnapPlatformWatcher.ts": { "no-restricted-syntax": { - "count": 2 + "count": 1 } }, "packages/subscription-controller/src/SubscriptionController.test.ts": { @@ -2343,4 +2343,4 @@ "count": 10 } } -} +} \ No newline at end of file diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 89ee9bb318..1629643107 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -7,8 +7,6 @@ import { KeyringType } from '@metamask/keyring-api/v2'; import { KeyringControllerError, KeyringControllerErrorMessage, - KeyringControllerState, - KeyringTypes, } from '@metamask/keyring-controller'; import type { KeyringEntry, @@ -40,9 +38,6 @@ type RootMessenger = Messenger< MessengerEvents >; -/** Mock keyring controller state type for tests. */ -type MockKeyringControllerState = Pick; - /** Mock truncated snap type for tests. */ type MockTruncatedSnap = Pick< TruncatedSnap, @@ -146,23 +141,6 @@ function publishSnapIsReady( ); } -/** - * Publishes a KeyringController stateChange event on the root messenger. - * - * @param rootMessenger - The root messenger. - * @param keyrings - The keyrings to publish. - */ -function publishKeyrings( - rootMessenger: RootMessenger, - keyrings: { type: string }[], -): void { - rootMessenger.publish( - 'KeyringController:stateChange', - { keyrings } as MockKeyringControllerState as KeyringControllerState, - [], - ); -} - /** * Flushes pending microtasks so that chained `await`s in fire-and-forget * handlers resolve before assertions run. @@ -431,7 +409,6 @@ function mockWithKeyringV2Unsafe( * * @param args - The arguments to this function. * @param args.snapIsReady - Initial value of `SnapController.isReady`. - * @param args.keyrings - Initial keyrings returned by `KeyringController:getState`. * @param args.runnableSnaps - Snaps returned by `SnapController:getRunnableSnaps`. * @param args.config - Optional service config. * @param args.init - Whether to call `service.init()` before returning (default: `true`). @@ -439,13 +416,11 @@ function mockWithKeyringV2Unsafe( */ async function setup({ snapIsReady = true, - keyrings = [{ type: KeyringTypes.snap }], runnableSnaps = [], config, init = true, }: { snapIsReady?: boolean; - keyrings?: { type: string }[]; runnableSnaps?: TruncatedSnap[]; config?: SnapAccountServiceOptions['config']; init?: boolean; @@ -466,7 +441,7 @@ async function setup({ getRunnableSnaps: jest.fn().mockReturnValue(runnableSnaps), }, KeyringController: { - getState: jest.fn().mockReturnValue({ keyrings }), + getState: jest.fn().mockReturnValue({ keyrings: [] }), withController: jest.fn(), withKeyringV2: jest.fn(), withKeyringV2Unsafe: jest.fn(), @@ -782,53 +757,6 @@ describe('SnapAccountService', () => { expect(resolved).toBe(true); }); - it('waits for the Snap keyring to appear via KeyringController:stateChange', async () => { - const { service, rootMessenger } = await setup({ - keyrings: [], - runnableSnaps: [buildSnap(MOCK_SNAP_ID)], - }); - - let resolved = false; - const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { - resolved = true; - return undefined; - }); - - // Flush microtasks so migration completes and #waitForSnapKeyring - // subscribes. - await flushMicrotasks(); - - expect(resolved).toBe(false); - - publishKeyrings(rootMessenger, [{ type: KeyringTypes.snap }]); - - await ensurePromise; - expect(resolved).toBe(true); - }); - - it('rejects if the Snap keyring does not appear within snapKeyringWaitTimeoutMs', async () => { - const { service } = await setup({ - keyrings: [], - runnableSnaps: [buildSnap(MOCK_SNAP_ID)], - config: { - snapPlatformWatcher: { snapKeyringWaitTimeoutMs: 1_000 }, - }, - }); - - jest.useFakeTimers(); - const ensurePromise = service.ensureReady(MOCK_SNAP_ID); - // Attach rejection handler before advancing timers to avoid unhandled rejection. - // eslint-disable-next-line jest/valid-expect -- assertion is awaited after advancing timers - const expectRejection = expect(ensurePromise).rejects.toThrow( - 'Snap platform or keyrings still not ready. Aborting.', - ); - await Promise.resolve(); - await jest.advanceTimersByTimeAsync(1_000 + 1); - jest.useRealTimers(); - - await expectRejection; - }); - it('awaits config.snapPlatformWatcher.ensureOnboardingComplete before resolving', async () => { let resolveOnboarding: (() => void) | undefined; const ensureOnboardingComplete = jest.fn( diff --git a/packages/snap-account-service/src/SnapPlatformWatcher.test.ts b/packages/snap-account-service/src/SnapPlatformWatcher.test.ts index c94a9290e9..dfce52b79b 100644 --- a/packages/snap-account-service/src/SnapPlatformWatcher.test.ts +++ b/packages/snap-account-service/src/SnapPlatformWatcher.test.ts @@ -1,5 +1,4 @@ /* eslint-disable no-void */ -import { KeyringTypes } from '@metamask/keyring-controller'; import { Messenger, MOCK_ANY_NAMESPACE } from '@metamask/messenger'; import type { MockAnyNamespace, @@ -10,10 +9,7 @@ import type { SnapControllerState } from '@metamask/snaps-controllers'; import { createDeferredPromise } from '@metamask/utils'; import type { SnapAccountServiceMessenger } from './SnapAccountService'; -import { - DEFAULT_SNAP_KEYRING_WAIT_TIMEOUT_MS, - SnapPlatformWatcher, -} from './SnapPlatformWatcher'; +import { SnapPlatformWatcher } from './SnapPlatformWatcher'; type RootMessenger = Messenger< MockAnyNamespace, @@ -34,8 +30,8 @@ function getMessenger( }); rootMessenger.delegate({ messenger, - actions: ['SnapController:getState', 'KeyringController:getState'], - events: ['SnapController:stateChange', 'KeyringController:stateChange'], + actions: ['SnapController:getState'], + events: ['SnapController:stateChange'], }); return messenger; } @@ -56,10 +52,6 @@ function setup( SnapController: { getState: jest.Mock; }; - // eslint-disable-next-line @typescript-eslint/naming-convention - KeyringController: { - getState: jest.Mock<{ keyrings: { type: string }[] }>; - }; }; watcher: SnapPlatformWatcher; } { @@ -67,9 +59,6 @@ function setup( SnapController: { getState: jest.fn(), }, - KeyringController: { - getState: jest.fn(), - }, }; rootMessenger.registerActionHandler( @@ -80,16 +69,6 @@ function setup( isReady: false, } as SnapControllerState); - rootMessenger.registerActionHandler( - 'KeyringController:getState', - mocks.KeyringController.getState, - ); - // By default, Snap keyring exists so ensureCanUseSnapPlatform can complete - // (including #waitForSnapKeyring) without arming the timeout. - mocks.KeyringController.getState.mockReturnValue({ - keyrings: [{ type: KeyringTypes.snap }], - }); - const messenger = getMessenger(rootMessenger); const watcher = new SnapPlatformWatcher(messenger); @@ -282,181 +261,6 @@ describe('SnapPlatformWatcher', () => { expect(watcher.isReady).toBe(true); }); - it('resolves when Snap keyring is available (does not throw)', async () => { - const { rootMessenger, watcher, mocks } = setup(); - - publishIsReadyState(rootMessenger, true); - - expect(await watcher.ensureCanUseSnapPlatform()).toBeUndefined(); - - // When keyring exists, getState is used to check for Snap keyring, so we - // return without throwing. - expect(mocks.KeyringController.getState).toHaveBeenCalled(); - }); - - it('resolves when Snap keyring appears via stateChange (listener path)', async () => { - const { messenger, mocks } = setup(); - mocks.SnapController.getState.mockReturnValue({ - isReady: true, - } as SnapControllerState); - mocks.KeyringController.getState.mockReturnValue({ keyrings: [] }); - const subscribeSpy = jest.spyOn(messenger, 'subscribe'); - const watcher = new SnapPlatformWatcher(messenger); - - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - await Promise.resolve(); - await Promise.resolve(); // flush so #waitForSnapKeyring runs and subscribe is called - - expect(subscribeSpy.mock.calls.map((call) => call[0])).toContain( - 'KeyringController:stateChange', - ); - const stateChangeCall = subscribeSpy.mock.calls.find( - (call) => call[0] === 'KeyringController:stateChange', - ); - if (stateChangeCall === undefined) { - throw new Error( - 'KeyringController:stateChange subscribe call not found', - ); - } - const listener = stateChangeCall[1] as ( - keyrings: { type: string }[], - ) => void; - listener([{ type: KeyringTypes.snap }]); - - expect(await ensurePromise).toBeUndefined(); - }); - - it('resolves when Snap keyring appears via published stateChange (selector path)', async () => { - const { rootMessenger, messenger, mocks } = setup(); - mocks.SnapController.getState.mockReturnValue({ - isReady: true, - } as SnapControllerState); - mocks.KeyringController.getState.mockReturnValue({ keyrings: [] }); - const watcher = new SnapPlatformWatcher(messenger); - - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - await Promise.resolve(); - await Promise.resolve(); - - rootMessenger.publish( - 'KeyringController:stateChange', - { - isUnlocked: true, - keyrings: [ - { - type: KeyringTypes.snap, - accounts: [], - metadata: { id: 'snap', name: 'Snap' }, - }, - ], - }, - [], - ); - - expect(await ensurePromise).toBeUndefined(); - }); - - it('resolves when getState throws but stateChange later delivers Snap keyring (covers #hasSnapKeyring catch path)', async () => { - const { messenger, mocks } = setup(); - mocks.SnapController.getState.mockReturnValue({ - isReady: true, - } as SnapControllerState); - mocks.KeyringController.getState.mockImplementation(() => { - throw new Error('KeyringController locked'); - }); - const subscribeSpy = jest.spyOn(messenger, 'subscribe'); - const watcher = new SnapPlatformWatcher(messenger); - - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - await Promise.resolve(); - await Promise.resolve(); - - expect(subscribeSpy.mock.calls.map((call) => call[0])).toContain( - 'KeyringController:stateChange', - ); - const stateChangeCall = subscribeSpy.mock.calls.find( - (call) => call[0] === 'KeyringController:stateChange', - ); - if (stateChangeCall === undefined) { - throw new Error( - 'KeyringController:stateChange subscribe call not found', - ); - } - const listener = stateChangeCall[1] as ( - keyrings: { type: string }[], - ) => void; - listener([{ type: KeyringTypes.snap }]); - - expect(await ensurePromise).toBeUndefined(); - }); - - it('rejects with explicit error when Snap keyring does not appear within timeout', async () => { - const { rootMessenger, watcher, mocks } = setup(); - - mocks.KeyringController.getState.mockReturnValue({ keyrings: [] }); - publishIsReadyState(rootMessenger, true); - - jest.useFakeTimers(); - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - // Attach rejection handler before advancing timers to avoid unhandled rejection. - // eslint-disable-next-line jest/valid-expect -- assertion is awaited after advancing timers - const expectRejection = expect(ensurePromise).rejects.toThrow( - 'Snap platform or keyrings still not ready. Aborting.', - ); - await Promise.resolve(); - await jest.advanceTimersByTimeAsync( - DEFAULT_SNAP_KEYRING_WAIT_TIMEOUT_MS + 1, - ); - jest.useRealTimers(); - - await expectRejection; - }); - - it('rejects when timeout fires (covers timeout callback path)', async () => { - const { rootMessenger, messenger, mocks } = setup(); - mocks.KeyringController.getState.mockReturnValue({ keyrings: [] }); - const watcher = new SnapPlatformWatcher(messenger, { - snapKeyringWaitTimeoutMs: 1, - }); - publishIsReadyState(rootMessenger, true); - - jest.useFakeTimers(); - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - await Promise.resolve(); - await Promise.resolve(); - // Attach rejection handler before advancing timers to avoid unhandled rejection. - // eslint-disable-next-line jest/valid-expect -- assertion is awaited after advancing timers - const rejectionAssertion = expect(ensurePromise).rejects.toThrow( - 'Snap platform or keyrings still not ready. Aborting.', - ); - await jest.advanceTimersByTimeAsync(10); - jest.useRealTimers(); - await rejectionAssertion; - }); - - it('uses custom snapKeyringWaitTimeoutMs when provided', async () => { - const { rootMessenger, messenger, mocks } = setup(); - mocks.KeyringController.getState.mockReturnValue({ keyrings: [] }); - - const watcher = new SnapPlatformWatcher(messenger, { - snapKeyringWaitTimeoutMs: 100, - }); - publishIsReadyState(rootMessenger, true); - - jest.useFakeTimers(); - const ensurePromise = watcher.ensureCanUseSnapPlatform(); - // Attach a rejection handler before advancing timers to avoid unhandled rejection. - // eslint-disable-next-line jest/valid-expect -- assertion is awaited after advancing timers - const expectRejection = expect(ensurePromise).rejects.toThrow( - 'Snap platform or keyrings still not ready. Aborting.', - ); - await Promise.resolve(); - await jest.advanceTimersByTimeAsync(100); - jest.useRealTimers(); - - await expectRejection; - }); - it('waits for ensureOnboardingComplete first when platform is already ready', async () => { const { rootMessenger, messenger } = setup(); const { promise: onboardingPromise, resolve: resolveOnboarding } = diff --git a/packages/snap-account-service/src/SnapPlatformWatcher.ts b/packages/snap-account-service/src/SnapPlatformWatcher.ts index da294df397..91beb4144d 100644 --- a/packages/snap-account-service/src/SnapPlatformWatcher.ts +++ b/packages/snap-account-service/src/SnapPlatformWatcher.ts @@ -1,43 +1,14 @@ -import { KeyringTypes } from '@metamask/keyring-controller'; import { createDeferredPromise, DeferredPromise } from '@metamask/utils'; import { once } from 'lodash'; -import { projectLogger as log, WARNING_PREFIX } from './logger'; +import { projectLogger as log } from './logger'; import type { SnapAccountServiceMessenger } from './SnapAccountService'; -/** Minimal KeyringController state shape needed to detect Snap keyring. */ -type KeyringControllerStateSlice = { - keyrings: { type: string }[]; -}; - -/** Default wait for Snap keyring to appear before rejecting (ms). */ -export const DEFAULT_SNAP_KEYRING_WAIT_TIMEOUT_MS = 5_000; - -/** Error message when Snap keyring does not appear within the timeout. */ -const SNAP_KEYRING_TIMEOUT_MESSAGE = - 'Snap platform or keyrings still not ready. Aborting.'; - -/** - * Returns true if the given KeyringController state slice contains a Snap keyring. - * - * @param state - KeyringController state. - * @returns True if state.keyrings contains a keyring with type KeyringTypes.snap. - */ -function stateHasSnapKeyring(state: KeyringControllerStateSlice): boolean { - return state.keyrings.some((k) => k.type === KeyringTypes.snap); -} - export type SnapPlatformWatcherConfig = { /** * Resolves when onboarding is complete. */ ensureOnboardingComplete?: () => Promise; - /** - * How long to wait for the Snap keyring to appear before rejecting (ms). - * - * @default DEFAULT_SNAP_KEYRING_WAIT_TIMEOUT_MS - */ - snapKeyringWaitTimeoutMs?: number; }; export class SnapPlatformWatcher { @@ -45,8 +16,6 @@ export class SnapPlatformWatcher { readonly #ensureOnboardingComplete?: () => Promise; - readonly #snapKeyringWaitTimeoutMs: number; - readonly #isReadyOnce: DeferredPromise; #isReady: boolean; @@ -57,8 +26,6 @@ export class SnapPlatformWatcher { ) { this.#messenger = messenger; this.#ensureOnboardingComplete = config.ensureOnboardingComplete; - this.#snapKeyringWaitTimeoutMs = - config.snapKeyringWaitTimeoutMs ?? DEFAULT_SNAP_KEYRING_WAIT_TIMEOUT_MS; this.#isReady = false; this.#isReadyOnce = createDeferredPromise(); @@ -80,80 +47,6 @@ export class SnapPlatformWatcher { if (!this.#isReady) { throw new Error('Snap platform cannot be used now.'); } - - // After a restore/reset, the Snap keyring is created lazily by the client (e.g. when - // getSnapKeyring() is called). Non-EVM account creation needs the keyring to exist, so we - // wait for it here with a timeout to avoid "Keyring not found" errors. - await this.#waitForSnapKeyring(); - } - - /** - * Waits for KeyringController to have a Snap keyring available. - * Checks once, then subscribes to KeyringController:stateChange until the keyring - * appears or the timeout is reached (then throws). - */ - async #waitForSnapKeyring(): Promise { - if (this.#hasSnapKeyring()) { - return; - } - await this.#waitForSnapKeyringViaStateChange(); - } - - /** - * Returns true if KeyringController already has a Snap keyring. - * Logs and returns false on error. - * - * @returns True if a Snap keyring exists, false otherwise or on error. - */ - #hasSnapKeyring(): boolean { - try { - const state = this.#messenger.call( - 'KeyringController:getState', - ) as KeyringControllerStateSlice; - return stateHasSnapKeyring(state); - } catch (error) { - log( - `${WARNING_PREFIX} KeyringController error while waiting for Snap keyring:`, - error, - ); - return false; - } - } - - /** - * Subscribes to KeyringController:stateChange and resolves when a Snap keyring - * appears in state, or rejects with an error after the timeout. - */ - async #waitForSnapKeyringViaStateChange(): Promise { - await new Promise((resolve, reject) => { - const timeoutRef: { id: ReturnType | undefined } = { - id: undefined, - }; - - const listener = ( - keyrings: KeyringControllerStateSlice['keyrings'], - ): void => { - if (stateHasSnapKeyring({ keyrings })) { - clearTimeout(timeoutRef.id); - this.#messenger.unsubscribe( - 'KeyringController:stateChange', - listener, - ); - resolve(); - } - }; - - timeoutRef.id = setTimeout(() => { - this.#messenger.unsubscribe('KeyringController:stateChange', listener); - reject(new Error(SNAP_KEYRING_TIMEOUT_MESSAGE)); - }, this.#snapKeyringWaitTimeoutMs); - - this.#messenger.subscribe( - 'KeyringController:stateChange', - listener, - (state) => state.keyrings, - ); - }); } #watch(): void { From 6d6b51e5b502a0900adacb8a2a9dafd148728c9c Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 21 May 2026 12:00:52 +0200 Subject: [PATCH 22/45] chore: lint --- eslint-suppressions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 196ccc6324..14b200d2d6 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -2343,4 +2343,4 @@ "count": 10 } } -} \ No newline at end of file +} From 8e8c4f6f526e1fa1aee25cc8324a519199dacbf1 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 21 May 2026 14:24:38 +0200 Subject: [PATCH 23/45] fix: relax :handleKeyringSnapMessage for v2 --- .../src/SnapAccountService.test.ts | 64 ++----------------- .../src/SnapAccountService.ts | 30 +++------ 2 files changed, 15 insertions(+), 79 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 1629643107..680c41789c 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -297,57 +297,6 @@ function mockWithController( return { addNewKeyring }; } -/** - * Configures `mocks.KeyringController.withKeyringV2` so that the operation - * receives a Snap keyring v2 matching the given selector, or throws - * `KeyringNotFound` when none matches. - * - * @param mocks - The mocks object from {@link setup}. - * @param keyrings - The available v2 Snap keyrings, keyed by snap ID. - */ -function mockWithKeyringV2( - mocks: Mocks, - keyrings: Record>, -): void { - mocks.KeyringController.withKeyringV2.mockImplementation( - async ( - selector: KeyringSelectorV2, - operation: (args: { - keyring: SnapKeyringV2; - metadata: KeyringMetadata; - }) => Promise, - ) => { - const entry = Object.entries(keyrings).find(([snapId, snapKeyring]) => - // The selector's filter expects a v2 keyring object; we synthesise - // a minimal shape (`type` + `snapId`) so the production filter - // function can identify it. - selector.filter?.( - { - type: KeyringType.Snap, - snapId, - ...snapKeyring, - } as unknown, - { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, - ), - ); - if (!entry) { - throw new KeyringControllerError( - KeyringControllerErrorMessage.KeyringNotFound, - ); - } - const [snapId, snapKeyring] = entry; - return operation({ - keyring: { - type: KeyringType.Snap, - snapId, - ...snapKeyring, - } as unknown as SnapKeyringV2, - metadata: { id: `id-${snapId}`, name: 'snap' } as KeyringMetadata, - }); - }, - ); -} - /** * Configures `mocks.KeyringController.withKeyringV2Unsafe` so that the * operation receives a Snap keyring v2 matching the given selector, or @@ -363,6 +312,7 @@ function mockWithKeyringV2Unsafe( { setSelectedAccounts?: jest.Mock; hasAccount?: (id: string) => boolean; + handleKeyringSnapMessage?: jest.Mock; } >, ): void { @@ -808,7 +758,7 @@ describe('SnapAccountService', () => { const handleKeyringSnapMessage = jest .fn() .mockResolvedValue({ ok: true }); - mockWithKeyringV2(mocks, { + mockWithKeyringV2Unsafe(mocks, { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, }); @@ -861,7 +811,7 @@ describe('SnapAccountService', () => { it('throws a dedicated error when no v2 Snap keyring exists for the given Snap', async () => { const { service, mocks } = await setup(); - mockWithKeyringV2(mocks, {}); + mockWithKeyringV2Unsafe(mocks, {}); await expect( service.handleKeyringSnapMessage(MOCK_SNAP_ID, MOCK_MESSAGE), @@ -874,7 +824,7 @@ describe('SnapAccountService', () => { const { service, mocks } = await setup(); const error = new Error('snap boom'); const handleKeyringSnapMessage = jest.fn().mockRejectedValue(error); - mockWithKeyringV2(mocks, { + mockWithKeyringV2Unsafe(mocks, { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, }); @@ -889,9 +839,7 @@ describe('SnapAccountService', () => { // so it must create one. const { addNewKeyring } = mockWithController(mocks, []); const handleKeyringSnapMessage = jest.fn().mockResolvedValue(null); - // `withController` mock takes precedence over `withKeyringV2`; configure - // `withKeyringV2` separately for the forwarding step. - mockWithKeyringV2(mocks, { + mockWithKeyringV2Unsafe(mocks, { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, }); @@ -912,7 +860,7 @@ describe('SnapAccountService', () => { it('is exposed as a messenger action', async () => { const { service, mocks, messenger } = await setup(); const handleKeyringSnapMessage = jest.fn().mockResolvedValue('pong'); - mockWithKeyringV2(mocks, { + mockWithKeyringV2Unsafe(mocks, { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, }); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index e624b282d0..85d66912f4 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -484,26 +484,6 @@ export class SnapAccountService { ) as Result; } - /** - * Runs an operation against the v2 Snap keyring for the given Snap, under - * the `KeyringController` mutex. Throws `KeyringNotFound` if no v2 Snap - * keyring exists for the given Snap. - * - * @param snapId - The Snap ID to look up the keyring for. - * @param operation - The operation to run with the matching keyring. - * @returns The result of the operation. - */ - async #withKeyringV2( - snapId: SnapId, - operation: (keyring: SnapKeyring) => Promise, - ): Promise { - return this.#withKeyringV2Call( - 'KeyringController:withKeyringV2', - snapId, - operation, - ); - } - /** * Lock-free variant of {@link SnapAccountService.#withKeyringV2}. Only use * for operations that do not mutate keyring or controller state — see @@ -563,7 +543,15 @@ export class SnapAccountService { // This part of the flow relies on v1 flows, but v2 keyrings are compatible with those messages // too. try { - return await this.#withKeyringV2(snapId, async (keyring) => + // NOTE: We use "unsafe" here since none of the messages should trigger mutations to the keyring state. + // The exception might be `:accountCreated`, but even in that case, the mutation is handled differently + // in the client by call `:persistAllKeyrings` explicitly. + // Using `:withKeyringV2` would cause a deadlock when we're initiating operations like `removeAccount` from + // the keyring itself: + // 1: withKeyring(..., ({ keyring }) => { keyring.removeAccount(...) }) + // 2. removeAccount(...) -> handleKeyringSnapMessage(..., { method: 'accountRemoved', ... }) + // 3. handleKeyringSnapMessage tries to acquire the same lock again via withKeyringV2 -> deadlock. + return await this.#withKeyringV2Unsafe(snapId, async (keyring) => keyring.handleKeyringSnapMessage(message), ); } catch (error) { From 3ecf1d725c8a47305c05bdcfa9bd7a0f6e067851 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 10:11:18 +0200 Subject: [PATCH 24/45] Initialize Release 1020.0.0 --- packages/address-book-controller/CHANGELOG.md | 8 ++-- packages/announcement-controller/CHANGELOG.md | 15 ++++++- packages/app-metadata-controller/CHANGELOG.md | 8 ++++ packages/approval-controller/CHANGELOG.md | 16 +++++++- packages/base-controller/CHANGELOG.md | 15 +++++-- packages/build-utils/CHANGELOG.md | 22 +++++++++-- packages/client-controller/CHANGELOG.md | 11 ++++++ packages/composable-controller/CHANGELOG.md | 26 +++++++++---- packages/connectivity-controller/CHANGELOG.md | 11 ++++++ packages/eip-5792-middleware/CHANGELOG.md | 8 +++- packages/eth-block-tracker/CHANGELOG.md | 14 +++++++ packages/eth-json-rpc-middleware/CHANGELOG.md | 7 ++++ packages/eth-json-rpc-provider/CHANGELOG.md | 8 +++- packages/foundryup/CHANGELOG.md | 14 +++++++ .../json-rpc-middleware-stream/CHANGELOG.md | 39 +++++++++++++------ packages/logging-controller/CHANGELOG.md | 6 +-- packages/message-manager/CHANGELOG.md | 6 +-- .../CHANGELOG.md | 22 ++++++----- packages/name-controller/CHANGELOG.md | 10 ++--- .../permission-log-controller/CHANGELOG.md | 20 ++++++++-- packages/perps-controller/CHANGELOG.md | 4 ++ packages/preferences-controller/CHANGELOG.md | 23 ++++++++--- packages/profile-sync-controller/CHANGELOG.md | 20 +++++----- packages/rate-limit-controller/CHANGELOG.md | 16 ++++++-- packages/react-data-query/CHANGELOG.md | 4 ++ packages/shield-controller/CHANGELOG.md | 4 +- packages/snap-account-service/CHANGELOG.md | 4 +- packages/storage-service/CHANGELOG.md | 9 +++++ packages/wallet-framework-docs/CHANGELOG.md | 4 ++ packages/wallet/CHANGELOG.md | 4 ++ 30 files changed, 292 insertions(+), 86 deletions(-) diff --git a/packages/address-book-controller/CHANGELOG.md b/packages/address-book-controller/CHANGELOG.md index b88fb656a5..1357c53e26 100644 --- a/packages/address-book-controller/CHANGELOG.md +++ b/packages/address-book-controller/CHANGELOG.md @@ -104,10 +104,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/rpc-errors` from `^7.0.1` to `^7.0.2` ([#5080](https://github.com/MetaMask/core/pull/5080)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) ## [6.0.2] @@ -129,7 +129,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/announcement-controller/CHANGELOG.md b/packages/announcement-controller/CHANGELOG.md index 54eb3665a4..5fbf45c3c4 100644 --- a/packages/announcement-controller/CHANGELOG.md +++ b/packages/announcement-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -56,7 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) ## [7.0.2] @@ -80,7 +91,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/app-metadata-controller/CHANGELOG.md b/packages/app-metadata-controller/CHANGELOG.md index 8daaf5216f..c90484ffb2 100644 --- a/packages/app-metadata-controller/CHANGELOG.md +++ b/packages/app-metadata-controller/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/approval-controller/CHANGELOG.md b/packages/approval-controller/CHANGELOG.md index fe58556d33..bacc1dbaea 100644 --- a/packages/approval-controller/CHANGELOG.md +++ b/packages/approval-controller/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -70,7 +82,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [7.1.2] @@ -106,7 +118,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/base-controller/CHANGELOG.md b/packages/base-controller/CHANGELOG.md index 8d04231dfe..8eae73d9ff 100644 --- a/packages/base-controller/CHANGELOG.md +++ b/packages/base-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) +- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) +- Release/951.0.0 ([#8661](https://github.com/MetaMask/core/pull/8661)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) + ### Changed - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) @@ -150,14 +157,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove `RestrictedControllerMessenger` export which was an alias for `RestrictedMessenger`. Consumers should import `RestrictedMessenger` directly - Remove `RestrictedControllerMessengerConstraint` type export which was an alias for `RestrictedMessengerConstraint`. Consumers should use `RestrictedMessengerConstraint` type directly - Simplify `RestrictedMessenger` constructor by removing deprecated `controllerMessenger` parameter. The messenger instance should now be passed using only the `messenger` parameter instead of supporting both options -- Widen input parameter for type guard `isBaseController` from `ControllerInstance` to `unknown` ([#5018](https://github.com/MetaMask/core/pull/5018/)) +- Widen input parameter for type guard `isBaseController` from `ControllerInstance` to `unknown` ([#5018](https://github.com/MetaMask/core/pull/5018)) - Bump `@metamask/json-rpc-engine` from `^10.0.2` to `^10.0.3` ([#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ### Removed -- **BREAKING:** Remove class `BaseControllerV1` and type guard `isBaseControllerV1` ([#5018](https://github.com/MetaMask/core/pull/5018/)) -- **BREAKING:** Remove types `BaseConfig`, `BaseControllerV1Instance`, `BaseState`, `ConfigConstraintV1`, `Listener`, `StateConstraintV1`, `LegacyControllerStateConstraint`, `ControllerInstance` ([#5018](https://github.com/MetaMask/core/pull/5018/)) +- **BREAKING:** Remove class `BaseControllerV1` and type guard `isBaseControllerV1` ([#5018](https://github.com/MetaMask/core/pull/5018)) +- **BREAKING:** Remove types `BaseConfig`, `BaseControllerV1Instance`, `BaseState`, `ConfigConstraintV1`, `Listener`, `StateConstraintV1`, `LegacyControllerStateConstraint`, `ControllerInstance` ([#5018](https://github.com/MetaMask/core/pull/5018)) ## [7.1.1] @@ -194,7 +201,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/build-utils/CHANGELOG.md b/packages/build-utils/CHANGELOG.md index e7d9bee939..a007a93d91 100644 --- a/packages/build-utils/CHANGELOG.md +++ b/packages/build-utils/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) +- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) +- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) +- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) +- chore(lint): Fix suppressed ESLint errors in `build-utils` package ([#7460](https://github.com/MetaMask/core/pull/7460)) +- chore: Re-enable `@typescript-eslint/no-unnecessary-type-assertions` ([#7296](https://github.com/MetaMask/core/pull/7296)) +- chore: Fix all auto-fixable ESLint warnings ([#7105](https://github.com/MetaMask/core/pull/7105)) +- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) +- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) + ### Changed - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511)) @@ -21,7 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) ## [3.0.2] @@ -47,7 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -89,7 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Initial release ([#3577](https://github.com/MetaMask/core/pull/3577) [#3588](https://github.com/MetaMask/core/pull/3588)) +- 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@3.0.4...HEAD [3.0.4]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.3...@metamask/build-utils@3.0.4 diff --git a/packages/client-controller/CHANGELOG.md b/packages/client-controller/CHANGELOG.md index 85bdd90982..8c29474a16 100644 --- a/packages/client-controller/CHANGELOG.md +++ b/packages/client-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/composable-controller/CHANGELOG.md b/packages/composable-controller/CHANGELOG.md index 24f50341c7..5cf9ee4ec5 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] +### Uncategorized + +- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) +- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) + ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.3.0` ([#8661](https://github.com/MetaMask/core/pull/8661)) @@ -48,16 +58,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632),[#6807](https://github.com/MetaMask/core/pull/6807)) +- Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632), [#6807](https://github.com/MetaMask/core/pull/6807)) ## [11.0.0] ### Changed -- **BREAKING:** Re-define `ComposableControllerStateConstraint` type using `StateConstraint` instead of `LegacyControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018/)) -- **BREAKING:** Constrain the `ComposableControllerState` generic argument for the `ComposableController` class using `ComposableControllerStateConstraint` instead of `LegacyComposableControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018/)) -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- **BREAKING:** Re-define `ComposableControllerStateConstraint` type using `StateConstraint` instead of `LegacyControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018)) +- **BREAKING:** Constrain the `ComposableControllerState` generic argument for the `ComposableController` class using `ComposableControllerStateConstraint` instead of `LegacyComposableControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082), [#5272](https://github.com/MetaMask/core/pull/5272)) ## [10.0.0] @@ -84,7 +94,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -143,9 +153,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** The `ComposableController` class is now a generic class that expects one generic argument `ComposableControllerState` ([#3952](https://github.com/MetaMask/core/pull/3952)). +- **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)). +- **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)) diff --git a/packages/connectivity-controller/CHANGELOG.md b/packages/connectivity-controller/CHANGELOG.md index e7d226e25b..490fbd6cd5 100644 --- a/packages/connectivity-controller/CHANGELOG.md +++ b/packages/connectivity-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Added - Add `connectivityControllerSelectors` with `selectConnectivityStatus` and `selectIsOffline` selectors ([#7701](https://github.com/MetaMask/core/pull/7701)) diff --git a/packages/eip-5792-middleware/CHANGELOG.md b/packages/eip-5792-middleware/CHANGELOG.md index efe85d6134..44f8e3cdf0 100644 --- a/packages/eip-5792-middleware/CHANGELOG.md +++ b/packages/eip-5792-middleware/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release/1003.0.0 ([#8912](https://github.com/MetaMask/core/pull/8912)) + ### Changed - Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.0` ([#8848](https://github.com/MetaMask/core/pull/8848)) @@ -60,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/transaction-controller` from `^61.3.0` to `^62.7.0` ([#7007](https://github.com/MetaMask/core/pull/7007), [#7126](https://github.com/MetaMask/core/pull/7126), [#7153](https://github.com/MetaMask/core/pull/7153), [#7202](https://github.com/MetaMask/core/pull/7202), [#7215](https://github.com/MetaMask/core/pull/7202), [#7220](https://github.com/MetaMask/core/pull/7220), [#7236](https://github.com/MetaMask/core/pull/7236), [#7257](https://github.com/MetaMask/core/pull/7257), [#7289](https://github.com/MetaMask/core/pull/7289), [#7325](https://github.com/MetaMask/core/pull/7325), [#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) +- Bump `@metamask/transaction-controller` from `^61.3.0` to `^62.7.0` ([#7007](https://github.com/MetaMask/core/pull/7007), [#7126](https://github.com/MetaMask/core/pull/7126), [#7153](https://github.com/MetaMask/core/pull/7153), [#7202](https://github.com/MetaMask/core/pull/7202), [#7215](https://github.com/MetaMask/core/pull/7215), [#7220](https://github.com/MetaMask/core/pull/7220), [#7236](https://github.com/MetaMask/core/pull/7236), [#7257](https://github.com/MetaMask/core/pull/7257), [#7289](https://github.com/MetaMask/core/pull/7289), [#7325](https://github.com/MetaMask/core/pull/7325), [#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) ## [2.0.0] @@ -94,7 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708)) -- Bump `@metamask/transaction-controller` from `^60.4.0` to `^60.6.0` ([#6708](https://github.com/MetaMask/core/pull/6733), [#6771](https://github.com/MetaMask/core/pull/6771)) +- Bump `@metamask/transaction-controller` from `^60.4.0` to `^60.6.0` ([#6708](https://github.com/MetaMask/core/pull/6708), [#6771](https://github.com/MetaMask/core/pull/6771)) - Remove dependency `@metamask/eth-json-rpc-middleware` ([#6714](https://github.com/MetaMask/core/pull/6714)) ## [1.2.0] diff --git a/packages/eth-block-tracker/CHANGELOG.md b/packages/eth-block-tracker/CHANGELOG.md index a5245d8834..4140d23aa4 100644 --- a/packages/eth-block-tracker/CHANGELOG.md +++ b/packages/eth-block-tracker/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) +- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- Release 840.0.0 ([#8078](https://github.com/MetaMask/core/pull/8078)) +- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) +- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) +- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) +- Release 795.0.0 ([#7856](https://github.com/MetaMask/core/pull/7856)) +- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) + ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.3.0` ([#8661](https://github.com/MetaMask/core/pull/8661)) diff --git a/packages/eth-json-rpc-middleware/CHANGELOG.md b/packages/eth-json-rpc-middleware/CHANGELOG.md index 3ddc7b7fd2..39d6f822b2 100644 --- a/packages/eth-json-rpc-middleware/CHANGELOG.md +++ b/packages/eth-json-rpc-middleware/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release 978.0.0 ([#8774](https://github.com/MetaMask/core/pull/8774)) +- Release 975.0.0 ([#8765](https://github.com/MetaMask/core/pull/8765)) +- feat(gator-permissions-controller): Added redeemer rule ([#8537](https://github.com/MetaMask/core/pull/8537)) +- Release 947.0.0 ([#8636](https://github.com/MetaMask/core/pull/8636)) + ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) diff --git a/packages/eth-json-rpc-provider/CHANGELOG.md b/packages/eth-json-rpc-provider/CHANGELOG.md index a23945cd76..35d1b32c25 100644 --- a/packages/eth-json-rpc-provider/CHANGELOG.md +++ b/packages/eth-json-rpc-provider/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) + ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) @@ -103,7 +109,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/foundryup/CHANGELOG.md b/packages/foundryup/CHANGELOG.md index f6ce1417dc..ac20139361 100644 --- a/packages/foundryup/CHANGELOG.md +++ b/packages/foundryup/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) +- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) +- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) +- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) +- chore: Update ESLint config packages to v15 ([#7305](https://github.com/MetaMask/core/pull/7305)) +- chore: Re-enable `@typescript-eslint/no-unnecessary-type-assertions` ([#7296](https://github.com/MetaMask/core/pull/7296)) +- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) +- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) + ## [1.0.1] ### Fixed diff --git a/packages/json-rpc-middleware-stream/CHANGELOG.md b/packages/json-rpc-middleware-stream/CHANGELOG.md index d7cdd1f041..3fd7cfa490 100644 --- a/packages/json-rpc-middleware-stream/CHANGELOG.md +++ b/packages/json-rpc-middleware-stream/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) +- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) +- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) +- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) +- chore(lint): Fix suppressed ESLint errors in `json-rpc-middleware-stream` package ([#7463](https://github.com/MetaMask/core/pull/7463)) +- chore: Update ESLint config packages to v15 ([#7305](https://github.com/MetaMask/core/pull/7305)) +- Revert "Release 687.0.0" ([#7201](https://github.com/MetaMask/core/pull/7201)) +- Release 687.0.0 ([#7190](https://github.com/MetaMask/core/pull/7190)) +- chore: Fix all auto-fixable ESLint warnings ([#7105](https://github.com/MetaMask/core/pull/7105)) +- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) +- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) + ### Changed - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511)) @@ -61,7 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -224,13 +241,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [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 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@6.0.0...@metamask/json-rpc-middleware-stream@6.0.1 -[6.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@5.0.1...@metamask/json-rpc-middleware-stream@6.0.0 -[5.0.1]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@5.0.0...json-rpc-middleware-stream@5.0.1 -[5.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.3...json-rpc-middleware-stream@5.0.0 -[4.2.3]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.2...json-rpc-middleware-stream@4.2.3 -[4.2.2]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.1...json-rpc-middleware-stream@4.2.2 -[4.2.1]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.0...json-rpc-middleware-stream@4.2.1 -[4.2.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.1.0...json-rpc-middleware-stream@4.2.0 -[4.1.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.0.0...json-rpc-middleware-stream@4.1.0 -[4.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@3.0.0...json-rpc-middleware-stream@4.0.0 -[3.0.0]: https://github.com/MetaMask/core/releases/tag/json-rpc-middleware-stream@3.0.0 +[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@5.0.1...@metamask/json-rpc-middleware-stream@6.0.0 +[5.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@5.0.0...@metamask/json-rpc-middleware-stream@5.0.1 +[5.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.3...@metamask/json-rpc-middleware-stream@5.0.0 +[4.2.3]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.2...@metamask/json-rpc-middleware-stream@4.2.3 +[4.2.2]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.1...@metamask/json-rpc-middleware-stream@4.2.2 +[4.2.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.0...@metamask/json-rpc-middleware-stream@4.2.1 +[4.2.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.1.0...@metamask/json-rpc-middleware-stream@4.2.0 +[4.1.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.0.0...@metamask/json-rpc-middleware-stream@4.1.0 +[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@3.0.0...@metamask/json-rpc-middleware-stream@4.0.0 +[3.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/json-rpc-middleware-stream@3.0.0 diff --git a/packages/logging-controller/CHANGELOG.md b/packages/logging-controller/CHANGELOG.md index 414e6703f2..1fc8bed5f7 100644 --- a/packages/logging-controller/CHANGELOG.md +++ b/packages/logging-controller/CHANGELOG.md @@ -78,8 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) ## [6.0.3] @@ -106,7 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/message-manager/CHANGELOG.md b/packages/message-manager/CHANGELOG.md index c00daf76cb..cf81902acb 100644 --- a/packages/message-manager/CHANGELOG.md +++ b/packages/message-manager/CHANGELOG.md @@ -91,8 +91,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [12.0.0] @@ -153,7 +153,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/multichain-transactions-controller/CHANGELOG.md b/packages/multichain-transactions-controller/CHANGELOG.md index 0c5a8cdb97..3e9dc4ace9 100644 --- a/packages/multichain-transactions-controller/CHANGELOG.md +++ b/packages/multichain-transactions-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release `964.0.0` ([#8722](https://github.com/MetaMask/core/pull/8722)) + ### Changed - Bump `@metamask/accounts-controller` from `^38.0.0` to `^38.1.2` ([#8755](https://github.com/MetaMask/core/pull/8755), [#8774](https://github.com/MetaMask/core/pull/8774), [#8912](https://github.com/MetaMask/core/pull/8912)) @@ -54,7 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/accounts-controller` from `^36.0.0` to `^37.0.0` ([#7996](https://github.com/MetaMask/core/pull/7996)), ([#8140](https://github.com/MetaMask/core/pull/8140)) +- Bump `@metamask/accounts-controller` from `^36.0.0` to `^37.0.0` ([#7996](https://github.com/MetaMask/core/pull/7996), [#8140](https://github.com/MetaMask/core/pull/8140)) - Bump `@metamask/polling-controller` from `^16.0.2` to `^16.0.3` ([#7996](https://github.com/MetaMask/core/pull/7996)) ## [7.0.1] @@ -67,7 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/snaps-sdk` from `^9.0.0` to `^10.3.0` ([#7550](https://github.com/MetaMask/core/pull/7550)) - Bump `@metamask/snaps-utils` from `^11.0.0` to `^11.7.0` ([#7550](https://github.com/MetaMask/core/pull/7550)) - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511)) -- Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209), [#7550](https://github.com/MetaMask/core/pull/7550), [#7604](https://github.com/MetaMask/core/pull/7604)), ([#7642](https://github.com/MetaMask/core/pull/7642), [#7897](https://github.com/MetaMask/core/pull/7897)) +- Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209), [#7550](https://github.com/MetaMask/core/pull/7550), [#7604](https://github.com/MetaMask/core/pull/7604), [#7642](https://github.com/MetaMask/core/pull/7642), [#7897](https://github.com/MetaMask/core/pull/7897)) - The dependencies moved are: - `@metamask/accounts-controller` (^36.0.0) - `@metamask/snaps-controllers` (^17.2.0) @@ -236,8 +240,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Sort transactions (newest first) ([#5339](https://github.com/MetaMask/core/pull/5339)) - Bump `@metamask/keyring-controller"` from `^19.1.0` to `^19.2.0` ([#5357](https://github.com/MetaMask/core/pull/5357)) - Bump `@metamask/keyring-api"` from `^17.0.0` to `^17.2.0` ([#5366](https://github.com/MetaMask/core/pull/5366)) -- Bump `@metamask/keyring-internal-api` from `^4.0.1` to `^4.0.3` ([#5356](https://github.com/MetaMask/core/pull/5356)), ([#5366](https://github.com/MetaMask/core/pull/5366)) -- Bump `@metamask/keyring-snap-client` from `^3.0.3` to `^4.0.1` ([#5356](https://github.com/MetaMask/core/pull/5356)), ([#5366](https://github.com/MetaMask/core/pull/5366)) +- Bump `@metamask/keyring-internal-api` from `^4.0.1` to `^4.0.3` ([#5356](https://github.com/MetaMask/core/pull/5356), [#5366](https://github.com/MetaMask/core/pull/5366)) +- Bump `@metamask/keyring-snap-client` from `^3.0.3` to `^4.0.1` ([#5356](https://github.com/MetaMask/core/pull/5356), [#5366](https://github.com/MetaMask/core/pull/5366)) - Bump `@metamask/utils` from `^11.1.0` to `^11.2.0` ([#5301](https://github.com/MetaMask/core/pull/5301)) ### Fixed @@ -267,7 +271,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^22.0.0` to `^23.0.0` ([#5292](https://github.com/MetaMask/core/pull/5292)) - **BREAKING:** Bump `@metamask/snaps-controllers` peer dependency from `^9.10.0` to `^9.19.0` ([#5265](https://github.com/MetaMask/core/pull/5265)) -- Bump `@metamask/snaps-sdk` from `^6.7.0` to `^6.17.1` ([#5220](https://github.com/MetaMask/core/pull/5220)), ([#5265](https://github.com/MetaMask/core/pull/5265)) +- Bump `@metamask/snaps-sdk` from `^6.7.0` to `^6.17.1` ([#5220](https://github.com/MetaMask/core/pull/5220), [#5265](https://github.com/MetaMask/core/pull/5265)) - Bump `@metamask/snaps-utils` from `^8.9.0` to `^8.10.0` ([#5265](https://github.com/MetaMask/core/pull/5265)) - Bump `@metamask/snaps-controllers` from `^9.10.0` to `^9.19.0` ([#5265](https://github.com/MetaMask/core/pull/5265)) - Bump `@metamask/keyring-api"` from `^16.1.0` to `^17.0.0` ([#5280](https://github.com/MetaMask/core/pull/5280)) @@ -279,15 +283,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^21.0.0` to `^22.0.0` ([#5218](https://github.com/MetaMask/core/pull/5218)) -- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190)), ([#5208](https://github.com/MetaMask/core/pull/5208)) -- Bump `@metamask/keyring-internal-api` from `^2.0.1` to `^4.0.1` ([#5190](https://github.com/MetaMask/core/pull/5190)), ([#5208](https://github.com/MetaMask/core/pull/5208)) -- Bump `@metamask/keyring-snap-client` from `^3.0.0` to `^3.0.3` ([#5190](https://github.com/MetaMask/core/pull/5190)), ([#5208](https://github.com/MetaMask/core/pull/5208)) +- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190), [#5208](https://github.com/MetaMask/core/pull/5208)) +- Bump `@metamask/keyring-internal-api` from `^2.0.1` to `^4.0.1` ([#5190](https://github.com/MetaMask/core/pull/5190), [#5208](https://github.com/MetaMask/core/pull/5208)) +- Bump `@metamask/keyring-snap-client` from `^3.0.0` to `^3.0.3` ([#5190](https://github.com/MetaMask/core/pull/5190), [#5208](https://github.com/MetaMask/core/pull/5208)) ## [0.0.1] ### Added -- Initial release ([#5133](https://github.com/MetaMask/core/pull/5133)), ([#5177](https://github.com/MetaMask/core/pull/5177)) +- Initial release ([#5133](https://github.com/MetaMask/core/pull/5133), [#5177](https://github.com/MetaMask/core/pull/5177)) [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.1.0...HEAD [7.1.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.0.4...@metamask/multichain-transactions-controller@7.1.0 diff --git a/packages/name-controller/CHANGELOG.md b/packages/name-controller/CHANGELOG.md index 68aeac2afa..04affc8e86 100644 --- a/packages/name-controller/CHANGELOG.md +++ b/packages/name-controller/CHANGELOG.md @@ -64,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/utils` from `^11.2.0` to `^11.8.1` ([#6054](https://github.com/MetaMask/core/pull/6054)[#6588](https://github.com/MetaMask/core/pull/6588), [#6708](https://github.com/MetaMask/core/pull/6708)) +- Bump `@metamask/utils` from `^11.2.0` to `^11.8.1` ([#6054](https://github.com/MetaMask/core/pull/6054), [#6588](https://github.com/MetaMask/core/pull/6588), [#6708](https://github.com/MetaMask/core/pull/6708)) - Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632), [#6807](https://github.com/MetaMask/core/pull/6807)) - Bump `@metamask/controller-utils` from `^11.5.0` to `^11.14.1` ([#5439](https://github.com/MetaMask/core/pull/5439), [#5583](https://github.com/MetaMask/core/pull/5583), [#5765](https://github.com/MetaMask/core/pull/5765), [#5812](https://github.com/MetaMask/core/pull/5812), [#5935](https://github.com/MetaMask/core/pull/5935), [#6069](https://github.com/MetaMask/core/pull/6069), [#6303](https://github.com/MetaMask/core/pull/6303), [#6620](https://github.com/MetaMask/core/pull/6620), [#6629](https://github.com/MetaMask/core/pull/6629), [#6807](https://github.com/MetaMask/core/pull/6807)) @@ -72,9 +72,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) - Bump `@metamask/base-controller` from `^7.0.0` to `^7.1.0` ([#5079](https://github.com/MetaMask/core/pull/5079)) ## [8.0.2] @@ -103,7 +103,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/permission-log-controller/CHANGELOG.md b/packages/permission-log-controller/CHANGELOG.md index 6109a43f09..76586a5353 100644 --- a/packages/permission-log-controller/CHANGELOG.md +++ b/packages/permission-log-controller/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) @@ -76,9 +88,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.0` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082)), ([#5272](https://github.com/MetaMask/core/pull/5272)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/base-controller` from `^7.0.0` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) - Bump `nanoid` from `^3.1.31` to `^3.3.8` ([#5073](https://github.com/MetaMask/core/pull/5073)) ## [3.0.2] @@ -112,7 +124,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/perps-controller/CHANGELOG.md b/packages/perps-controller/CHANGELOG.md index 8af2f9c01a..7feb123ece 100644 --- a/packages/perps-controller/CHANGELOG.md +++ b/packages/perps-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Release/1017.0.0 ([#8986](https://github.com/MetaMask/core/pull/8986)) + ## [7.0.0] ### Added diff --git a/packages/preferences-controller/CHANGELOG.md b/packages/preferences-controller/CHANGELOG.md index 1a469c357a..642cbdd9e9 100644 --- a/packages/preferences-controller/CHANGELOG.md +++ b/packages/preferences-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -51,7 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Remove legacy methods and state ([#8115](https://github.com/MetaMask/core/pull/8115)) - `identities`, `lostIdentities` and `selectedAddress` along with any associated methods and types were removed. - `setSmartAccountOptInForAccounts` was also removed as it is deprecated and not used in the clients. -- Removed `@metamask/keyring-controller` and `@metamask/controller-utils` dependencies ([#7995](https://github.com/MetaMask/core/pull/7995)), ([#8115](https://github.com/MetaMask/core/pull/8115)) +- Removed `@metamask/keyring-controller` and `@metamask/controller-utils` dependencies ([#7995](https://github.com/MetaMask/core/pull/7995), [#8115](https://github.com/MetaMask/core/pull/8115)) ## [22.1.0] @@ -210,8 +221,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) ## [15.0.1] @@ -223,7 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) ## [14.0.0] @@ -276,7 +287,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -504,7 +515,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `disabledRpcMethodPreferences` state to PreferencesController ([#1109](https://github.com/MetaMask/core/pull/1109)). See [this PR on extension](https://github.com/MetaMask/metamask-extension/pull/17308) and [this ticket](https://github.com/MetaMask/metamask-mobile/issues/5676) +- `disabledRpcMethodPreferences` state to PreferencesController. See [this PR on extension](https://github.com/MetaMask/metamask-extension/pull/17308) and [this ticket](https://github.com/MetaMask/metamask-mobile/issues/5676) ([#1109](https://github.com/MetaMask/core/pull/1109)) ## [2.0.0] diff --git a/packages/profile-sync-controller/CHANGELOG.md b/packages/profile-sync-controller/CHANGELOG.md index ea74007481..1b14006fa7 100644 --- a/packages/profile-sync-controller/CHANGELOG.md +++ b/packages/profile-sync-controller/CHANGELOG.md @@ -67,7 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Expose missing public `UserStorageController` methods through its messenger ([#7976](https://github.com/MetaMask/core/pull/7976/)) +- Expose missing public `UserStorageController` methods through its messenger ([#7976](https://github.com/MetaMask/core/pull/7976)) - The following actions are now available: - `UserStorageController:performDeleteStorageAllFeatureEntries` - `UserStorageController:listEntropySources` @@ -81,7 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Add client-side JWT `exp` claim validation to prevent stale cached tokens from being returned ([#8144](https://github.com/MetaMask/core/pull/8144)) - `validateLoginResponse` now decodes the JWT `exp` claim and rejects tokens that have actually expired, regardless of client-side TTL tracking (`obtainedAt`/`expiresIn`) - Non-JWT access tokens are now rejected as invalid. In production this has no effect (access tokens are always JWTs from the OIDC server), but E2E test mocks that use raw identifier strings as access tokens must be updated. `getMockAuthAccessTokenResponse` now wraps identifiers in a JWT; consumers should use `getE2EIdentifierFromJwt` (newly exported) to extract the identifier from the bearer token in mock servers. -- **BREAKING:** Standardize names of `AuthenticationController` and `UserStorageController` messenger action types ([#7976](https://github.com/MetaMask/core/pull/7976/)) +- **BREAKING:** Standardize names of `AuthenticationController` and `UserStorageController` messenger action types ([#7976](https://github.com/MetaMask/core/pull/7976)) - All existing types for messenger actions have been renamed so they end in `Action` (e.g. `AuthenticationControllerPerformSignIn` -> `AuthenticationControllerPerformSignInAction`). You will need to update imports appropriately. - This change only affects the types. The action type strings themselves have not changed, so you do not need to update the list of actions you pass when initializing `AuthenticationController` and `UserStorageController` messengers. @@ -355,7 +355,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Peer dependencies `@metamask/keyring-controller` and `@metamask/network-controller` are no longer also direct dependencies ([#5464](https://github.com/MetaMask/core/pull/5464))) +- Peer dependencies `@metamask/keyring-controller` and `@metamask/network-controller` are no longer also direct dependencies) ([#5464](https://github.com/MetaMask/core/pull/5464)) ## [10.1.0] @@ -455,7 +455,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^21.0.0` to `^22.0.0` ([#5218](https://github.com/MetaMask/core/pull/5218)) -- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190)), ([#5208](https://github.com/MetaMask/core/pull/5208)) +- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190), [#5208](https://github.com/MetaMask/core/pull/5208)) ## [4.1.1] @@ -482,7 +482,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^20.0.0` to `^21.0.0` ([#5140](https://github.com/MetaMask/core/pull/5140)) - Bump `@metamask/base-controller` from `7.1.0` to `^7.1.1` ([#5135](https://github.com/MetaMask/core/pull/5135)) - Bump `@metamask/keyring-api` from `^12.0.0` to `^13.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066)) -- Bump `@metamask/keyring-internal-api` from `^1.0.0` to `^2.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066)), ([#5136](https://github.com/MetaMask/core/pull/5136)) +- Bump `@metamask/keyring-internal-api` from `^1.0.0` to `^2.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066), [#5136](https://github.com/MetaMask/core/pull/5136)) - Bump `@metamask/keyring-controller` from `^19.0.2` to `^19.0.3` ([#5140](https://github.com/MetaMask/core/pull/5140)) ## [3.3.0] @@ -561,8 +561,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) -- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) +- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) ## [1.0.2] @@ -649,7 +649,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump accounts related packages ([#4713](https://github.com/MetaMask/core/pull/4713)), ([#4728](https://github.com/MetaMask/core/pull/4728)) +- Bump accounts related packages ([#4713](https://github.com/MetaMask/core/pull/4713), [#4728](https://github.com/MetaMask/core/pull/4728)) - Those packages are now built slightly differently and are part of the [accounts monorepo](https://github.com/MetaMask/accounts). - Bump `@metamask/keyring-api` from `^8.1.0` to `^8.1.4` @@ -728,7 +728,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -833,7 +833,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - added `LoginResponse` validation in profile syncing SDK ([#4541](https://github.com/MetaMask/core/pull/4541)) - - added snap caching when calling the message signing snap ([#4532](https://github.com/MetaMask/core/pull/4532)) ### Removed @@ -855,7 +854,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - added platform field when logging in to receive correct OIDC access token ([#4480](https://github.com/MetaMask/core/pull/4480)) - - added metametrics validation in constructor ([#4480](https://github.com/MetaMask/core/pull/4480)) ### Changed diff --git a/packages/rate-limit-controller/CHANGELOG.md b/packages/rate-limit-controller/CHANGELOG.md index 3942b766e7..345aea1afc 100644 --- a/packages/rate-limit-controller/CHANGELOG.md +++ b/packages/rate-limit-controller/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) +- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -50,9 +58,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) - Bump `@metamask/rpc-errors` from `^7.0.1` to `^7.0.2` ([#5080](https://github.com/MetaMask/core/pull/5080)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) ## [6.0.2] @@ -80,7 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). +- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -97,7 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.comMetaMask/core/pull/4232)) +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) ## [5.0.1] diff --git a/packages/react-data-query/CHANGELOG.md b/packages/react-data-query/CHANGELOG.md index 3e75ea4b24..2bea48614e 100644 --- a/packages/react-data-query/CHANGELOG.md +++ b/packages/react-data-query/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore(react-data-query): declare @metamask/messenger as a devDep ([#8971](https://github.com/MetaMask/core/pull/8971)) + ## [0.2.1] ### Changed diff --git a/packages/shield-controller/CHANGELOG.md b/packages/shield-controller/CHANGELOG.md index 9c12f10371..0c8a3cfdcc 100644 --- a/packages/shield-controller/CHANGELOG.md +++ b/packages/shield-controller/CHANGELOG.md @@ -135,13 +135,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added metrics in the Shield coverage response to track the latency ( [#7133](https://github.com/MetaMask/core/pull/7133)) +- Added metrics in the Shield coverage response to track the latency ([#7133](https://github.com/MetaMask/core/pull/7133)) ## [2.0.0] ### Changed -- **BREAKING:** Bump `@metamask/signature-controller` from `^35.0.0` to `^36.0.0` ( [#4651](https://github.com/MetaMask/core/pull/4651)) +- **BREAKING:** Bump `@metamask/signature-controller` from `^35.0.0` to `^36.0.0` ([#4651](https://github.com/MetaMask/core/pull/4651)) ## [1.2.0] diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 9a7a83dd72..c5f061a97c 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -47,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `SnapAccountService` ([#8414](https://github.com/MetaMask/core/pull/8414)) -- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715)), ([#8725](https://github.com/MetaMask/core/pull/8725)) +- Add `SnapPlatformWatcher` and `SnapAccountService.ensureReady` ([#8715](https://github.com/MetaMask/core/pull/8715), [#8725](https://github.com/MetaMask/core/pull/8725)) - Waits for the Snap platform to be ready and for a Snap keyring to appear in `KeyringController` state before allowing Snap account operations. - Callers must ensure `init()` has run and the Snap is currently installed, enabled, non-blocked, and declares `endowment:keyring`. - `SnapAccountService.ensureReady` now awaits the watcher, so it only resolves once both conditions hold (or rejects if the Snap keyring does not appear within the configured timeout). @@ -65,7 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The service messenger now requires the `KeyringController:withController` action. - Add `handleKeyringSnapMessage` ([#8758](https://github.com/MetaMask/core/pull/8758)) - This will be the new entry point for consumer that needs to forward keyring events to a account management Snap (instead of using the legacy Snap keyring instance directly). -- Forward selected account group accounts ([#8763](https://github.com/MetaMask/core/pull/8763)), ([#8770](https://github.com/MetaMask/core/pull/8770)) +- Forward selected account group accounts ([#8763](https://github.com/MetaMask/core/pull/8763), [#8770](https://github.com/MetaMask/core/pull/8770)) - This logic used to live on the clients. - The service messenger now requires the `KeyringController:unlock`, `AccountTreeController:selectedAccountGroupChange`, `AccountTreeController:accountGroup{Created,Updated,Removed}` events. - The service messenger now requires the `AccountTreeController:getSelectedAccountGroup` and `AccountTreeController:getAccountGroupObject` actions. diff --git a/packages/storage-service/CHANGELOG.md b/packages/storage-service/CHANGELOG.md index 4b5852c090..89de265d13 100644 --- a/packages/storage-service/CHANGELOG.md +++ b/packages/storage-service/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) +- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) +- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) +- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) +- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) +- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) + ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/wallet-framework-docs/CHANGELOG.md b/packages/wallet-framework-docs/CHANGELOG.md index b518709c7b..8cf5726c6c 100644 --- a/packages/wallet-framework-docs/CHANGELOG.md +++ b/packages/wallet-framework-docs/CHANGELOG.md @@ -7,4 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- Initialize Wallet Framework documentation ([#8927](https://github.com/MetaMask/core/pull/8927)) + [Unreleased]: https://github.com/MetaMask/core/ diff --git a/packages/wallet/CHANGELOG.md b/packages/wallet/CHANGELOG.md index 787705fe66..d95d3e0500 100644 --- a/packages/wallet/CHANGELOG.md +++ b/packages/wallet/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Uncategorized + +- refactor(wallet): migrate keyring + storage instances to directory convention ([#8977](https://github.com/MetaMask/core/pull/8977)) + ### Added - **BREAKING:** Wire `ApprovalController` into the default wallet initialization ([#8953](https://github.com/MetaMask/core/pull/8953)) From 04c476e55fc6abbc07dc6d7706b325d90d4fd32d Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 10:18:28 +0200 Subject: [PATCH 25/45] Update Release 1020.0.0 --- package.json | 2 +- packages/account-tree-controller/CHANGELOG.md | 5 +- packages/account-tree-controller/package.json | 6 +- packages/accounts-controller/CHANGELOG.md | 5 +- packages/accounts-controller/package.json | 2 +- packages/address-book-controller/CHANGELOG.md | 8 +- packages/announcement-controller/CHANGELOG.md | 15 +- packages/app-metadata-controller/CHANGELOG.md | 8 -- packages/approval-controller/CHANGELOG.md | 16 +-- packages/assets-controller/CHANGELOG.md | 5 +- packages/assets-controller/package.json | 12 +- packages/assets-controllers/CHANGELOG.md | 5 +- packages/assets-controllers/package.json | 12 +- packages/base-controller/CHANGELOG.md | 15 +- packages/bridge-controller/CHANGELOG.md | 5 +- packages/bridge-controller/package.json | 12 +- .../bridge-status-controller/CHANGELOG.md | 5 +- .../bridge-status-controller/package.json | 8 +- packages/build-utils/CHANGELOG.md | 22 +-- packages/client-controller/CHANGELOG.md | 11 -- packages/composable-controller/CHANGELOG.md | 26 ++-- packages/connectivity-controller/CHANGELOG.md | 11 -- packages/core-backend/CHANGELOG.md | 5 +- packages/core-backend/package.json | 4 +- packages/earn-controller/package.json | 4 +- packages/eip-5792-middleware/CHANGELOG.md | 8 +- packages/eip-5792-middleware/package.json | 2 +- packages/eth-block-tracker/CHANGELOG.md | 14 -- packages/eth-json-rpc-middleware/CHANGELOG.md | 7 - packages/eth-json-rpc-provider/CHANGELOG.md | 8 +- packages/foundryup/CHANGELOG.md | 14 -- .../gator-permissions-controller/package.json | 2 +- .../json-rpc-middleware-stream/CHANGELOG.md | 39 ++---- packages/logging-controller/CHANGELOG.md | 6 +- packages/message-manager/CHANGELOG.md | 6 +- .../money-account-controller/CHANGELOG.md | 5 +- .../money-account-controller/package.json | 4 +- .../multichain-account-service/CHANGELOG.md | 5 +- .../multichain-account-service/package.json | 6 +- .../multichain-api-middleware/CHANGELOG.md | 5 +- .../multichain-api-middleware/package.json | 6 +- .../CHANGELOG.md | 5 +- .../package.json | 4 +- .../CHANGELOG.md | 5 +- .../package.json | 4 +- packages/name-controller/CHANGELOG.md | 10 +- .../package.json | 4 +- .../permission-log-controller/CHANGELOG.md | 20 +-- packages/perps-controller/CHANGELOG.md | 4 - packages/perps-controller/package.json | 4 +- packages/phishing-controller/package.json | 2 +- packages/preferences-controller/CHANGELOG.md | 23 +--- .../profile-metrics-controller/CHANGELOG.md | 5 +- .../profile-metrics-controller/package.json | 6 +- packages/profile-sync-controller/CHANGELOG.md | 20 +-- packages/rate-limit-controller/CHANGELOG.md | 16 +-- packages/react-data-query/CHANGELOG.md | 4 - packages/shield-controller/CHANGELOG.md | 4 +- packages/shield-controller/package.json | 4 +- packages/signature-controller/CHANGELOG.md | 5 +- packages/signature-controller/package.json | 4 +- packages/snap-account-service/CHANGELOG.md | 5 +- packages/snap-account-service/package.json | 4 +- packages/storage-service/CHANGELOG.md | 9 -- packages/subscription-controller/package.json | 2 +- packages/transaction-controller/CHANGELOG.md | 5 +- packages/transaction-controller/package.json | 6 +- .../transaction-pay-controller/package.json | 10 +- .../user-operation-controller/package.json | 2 +- packages/wallet-framework-docs/CHANGELOG.md | 4 - packages/wallet/CHANGELOG.md | 4 - yarn.lock | 130 +++++++++--------- 72 files changed, 273 insertions(+), 427 deletions(-) diff --git a/package.json b/package.json index c3dbd90f00..cbc599b0eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/core-monorepo", - "version": "1019.0.0", + "version": "1020.0.0", "private": true, "description": "Monorepo for packages shared between MetaMask clients", "repository": { diff --git a/packages/account-tree-controller/CHANGELOG.md b/packages/account-tree-controller/CHANGELOG.md index e7d0966aa0..20763cb035 100644 --- a/packages/account-tree-controller/CHANGELOG.md +++ b/packages/account-tree-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.5.1] + ## [7.5.0] ### Added @@ -583,7 +585,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#5847](https://github.com/MetaMask/core/pull/5847)) - Grouping accounts into 3 main categories: Entropy source, Snap ID, keyring types. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.5.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.5.1...HEAD +[7.5.1]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.5.0...@metamask/account-tree-controller@7.5.1 [7.5.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.4.0...@metamask/account-tree-controller@7.5.0 [7.4.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.3.0...@metamask/account-tree-controller@7.4.0 [7.3.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@7.2.0...@metamask/account-tree-controller@7.3.0 diff --git a/packages/account-tree-controller/package.json b/packages/account-tree-controller/package.json index 7073824de7..5377032bc0 100644 --- a/packages/account-tree-controller/package.json +++ b/packages/account-tree-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/account-tree-controller", - "version": "7.5.0", + "version": "7.5.1", "description": "Controller to group account together based on some pre-defined rules", "keywords": [ "Ethereum", @@ -53,12 +53,12 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^26.0.0", "@metamask/messenger": "^1.2.0", - "@metamask/multichain-account-service": "^10.0.1", + "@metamask/multichain-account-service": "^10.0.2", "@metamask/profile-sync-controller": "^28.1.1", "@metamask/snaps-controllers": "^19.0.0", "@metamask/snaps-sdk": "^11.0.0", diff --git a/packages/accounts-controller/CHANGELOG.md b/packages/accounts-controller/CHANGELOG.md index 77d4ee763a..3060adf689 100644 --- a/packages/accounts-controller/CHANGELOG.md +++ b/packages/accounts-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [39.0.0] + ### Changed - **BREAKING:** Re-publish `SnapAccountService:account{AssetList,Balances,Transactions}Updated` events as `AccountsController:account{AssetList,Balances,Transactions}Updated` events ([#8978](https://github.com/MetaMask/core/pull/8978)) @@ -811,7 +813,8 @@ 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@38.1.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@39.0.0...HEAD +[39.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.1.2...@metamask/accounts-controller@39.0.0 [38.1.2]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.1.1...@metamask/accounts-controller@38.1.2 [38.1.1]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.1.0...@metamask/accounts-controller@38.1.1 [38.1.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.0.0...@metamask/accounts-controller@38.1.0 diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index ea32a13e10..510d7578c3 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/accounts-controller", - "version": "38.1.2", + "version": "39.0.0", "description": "Manages internal accounts", "keywords": [ "Ethereum", diff --git a/packages/address-book-controller/CHANGELOG.md b/packages/address-book-controller/CHANGELOG.md index 1357c53e26..b88fb656a5 100644 --- a/packages/address-book-controller/CHANGELOG.md +++ b/packages/address-book-controller/CHANGELOG.md @@ -104,10 +104,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/rpc-errors` from `^7.0.1` to `^7.0.2` ([#5080](https://github.com/MetaMask/core/pull/5080)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [6.0.2] @@ -129,7 +129,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/announcement-controller/CHANGELOG.md b/packages/announcement-controller/CHANGELOG.md index 5fbf45c3c4..54eb3665a4 100644 --- a/packages/announcement-controller/CHANGELOG.md +++ b/packages/announcement-controller/CHANGELOG.md @@ -7,17 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -67,7 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) ## [7.0.2] @@ -91,7 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/app-metadata-controller/CHANGELOG.md b/packages/app-metadata-controller/CHANGELOG.md index c90484ffb2..8daaf5216f 100644 --- a/packages/app-metadata-controller/CHANGELOG.md +++ b/packages/app-metadata-controller/CHANGELOG.md @@ -7,14 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/approval-controller/CHANGELOG.md b/packages/approval-controller/CHANGELOG.md index bacc1dbaea..fe58556d33 100644 --- a/packages/approval-controller/CHANGELOG.md +++ b/packages/approval-controller/CHANGELOG.md @@ -7,18 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -82,7 +70,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [7.1.2] @@ -118,7 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/assets-controller/CHANGELOG.md b/packages/assets-controller/CHANGELOG.md index 850aaa0471..a80f2bd73b 100644 --- a/packages/assets-controller/CHANGELOG.md +++ b/packages/assets-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.3.2] + ## [8.3.1] ### Fixed @@ -561,7 +563,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactor `RpcDataSource` to delegate polling to `BalanceFetcher` and `TokenDetector` services ([#7709](https://github.com/MetaMask/core/pull/7709)) - Refactor `BalanceFetcher` and `TokenDetector` to extend `StaticIntervalPollingControllerOnly` for independent polling management ([#7709](https://github.com/MetaMask/core/pull/7709)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.3.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.3.2...HEAD +[8.3.2]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.3.1...@metamask/assets-controller@8.3.2 [8.3.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.3.0...@metamask/assets-controller@8.3.1 [8.3.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.2.0...@metamask/assets-controller@8.3.0 [8.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@8.1.0...@metamask/assets-controller@8.2.0 diff --git a/packages/assets-controller/package.json b/packages/assets-controller/package.json index 99463f36ec..e7f6e7453c 100644 --- a/packages/assets-controller/package.json +++ b/packages/assets-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/assets-controller", - "version": "8.3.1", + "version": "8.3.2", "description": "Tracks assets balances/prices and handles token detection across all digital assets", "keywords": [ "Ethereum", @@ -56,13 +56,13 @@ "@ethereumjs/util": "^9.1.0", "@ethersproject/abi": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@metamask/account-tree-controller": "^7.5.0", - "@metamask/accounts-controller": "^38.1.2", - "@metamask/assets-controllers": "^108.4.0", + "@metamask/account-tree-controller": "^7.5.1", + "@metamask/accounts-controller": "^39.0.0", + "@metamask/assets-controllers": "^108.5.0", "@metamask/base-controller": "^9.1.0", "@metamask/client-controller": "^1.0.1", "@metamask/controller-utils": "^12.1.0", - "@metamask/core-backend": "^6.3.1", + "@metamask/core-backend": "^6.3.2", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^26.0.0", "@metamask/keyring-internal-api": "^11.0.1", @@ -76,7 +76,7 @@ "@metamask/preferences-controller": "^23.1.0", "@metamask/snaps-controllers": "^19.0.0", "@metamask/snaps-utils": "^12.1.2", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "async-mutex": "^0.5.0", "bignumber.js": "^9.1.2", diff --git a/packages/assets-controllers/CHANGELOG.md b/packages/assets-controllers/CHANGELOG.md index c23600469b..6c06d0619b 100644 --- a/packages/assets-controllers/CHANGELOG.md +++ b/packages/assets-controllers/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [108.5.0] + ### Added - Add `isDeprecated` option to `TokenListController` constructor, a function that returns whether the controller should be disabled ([#8945](https://github.com/MetaMask/core/pull/8945)) @@ -3142,7 +3144,8 @@ 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@108.4.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@108.5.0...HEAD +[108.5.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@108.4.0...@metamask/assets-controllers@108.5.0 [108.4.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@108.3.0...@metamask/assets-controllers@108.4.0 [108.3.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@108.2.0...@metamask/assets-controllers@108.3.0 [108.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@108.1.0...@metamask/assets-controllers@108.2.0 diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index d7fee1ea04..2d1cb04aff 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/assets-controllers", - "version": "108.4.0", + "version": "108.5.0", "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)", "keywords": [ "Ethereum", @@ -60,19 +60,19 @@ "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", "@metamask/abi-utils": "^2.0.3", - "@metamask/account-tree-controller": "^7.5.0", - "@metamask/accounts-controller": "^38.1.2", + "@metamask/account-tree-controller": "^7.5.1", + "@metamask/accounts-controller": "^39.0.0", "@metamask/approval-controller": "^9.0.1", "@metamask/base-controller": "^9.1.0", "@metamask/contract-metadata": "^2.4.0", "@metamask/controller-utils": "^12.1.0", - "@metamask/core-backend": "^6.3.1", + "@metamask/core-backend": "^6.3.2", "@metamask/eth-query": "^4.0.0", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^26.0.0", "@metamask/messenger": "^1.2.0", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/multichain-account-service": "^10.0.1", + "@metamask/multichain-account-service": "^10.0.2", "@metamask/network-controller": "^32.0.0", "@metamask/network-enablement-controller": "^5.2.0", "@metamask/permission-controller": "^13.1.1", @@ -85,7 +85,7 @@ "@metamask/snaps-sdk": "^11.0.0", "@metamask/snaps-utils": "^12.1.2", "@metamask/storage-service": "^1.0.1", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "@tanstack/query-core": "^5.62.16", "@types/bn.js": "^5.1.5", diff --git a/packages/base-controller/CHANGELOG.md b/packages/base-controller/CHANGELOG.md index 8eae73d9ff..8d04231dfe 100644 --- a/packages/base-controller/CHANGELOG.md +++ b/packages/base-controller/CHANGELOG.md @@ -7,13 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) -- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) -- Release/951.0.0 ([#8661](https://github.com/MetaMask/core/pull/8661)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) - ### Changed - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) @@ -157,14 +150,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove `RestrictedControllerMessenger` export which was an alias for `RestrictedMessenger`. Consumers should import `RestrictedMessenger` directly - Remove `RestrictedControllerMessengerConstraint` type export which was an alias for `RestrictedMessengerConstraint`. Consumers should use `RestrictedMessengerConstraint` type directly - Simplify `RestrictedMessenger` constructor by removing deprecated `controllerMessenger` parameter. The messenger instance should now be passed using only the `messenger` parameter instead of supporting both options -- Widen input parameter for type guard `isBaseController` from `ControllerInstance` to `unknown` ([#5018](https://github.com/MetaMask/core/pull/5018)) +- Widen input parameter for type guard `isBaseController` from `ControllerInstance` to `unknown` ([#5018](https://github.com/MetaMask/core/pull/5018/)) - Bump `@metamask/json-rpc-engine` from `^10.0.2` to `^10.0.3` ([#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ### Removed -- **BREAKING:** Remove class `BaseControllerV1` and type guard `isBaseControllerV1` ([#5018](https://github.com/MetaMask/core/pull/5018)) -- **BREAKING:** Remove types `BaseConfig`, `BaseControllerV1Instance`, `BaseState`, `ConfigConstraintV1`, `Listener`, `StateConstraintV1`, `LegacyControllerStateConstraint`, `ControllerInstance` ([#5018](https://github.com/MetaMask/core/pull/5018)) +- **BREAKING:** Remove class `BaseControllerV1` and type guard `isBaseControllerV1` ([#5018](https://github.com/MetaMask/core/pull/5018/)) +- **BREAKING:** Remove types `BaseConfig`, `BaseControllerV1Instance`, `BaseState`, `ConfigConstraintV1`, `Listener`, `StateConstraintV1`, `LegacyControllerStateConstraint`, `ControllerInstance` ([#5018](https://github.com/MetaMask/core/pull/5018/)) ## [7.1.1] @@ -201,7 +194,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/bridge-controller/CHANGELOG.md b/packages/bridge-controller/CHANGELOG.md index cdce1db005..f2adcc6b2e 100644 --- a/packages/bridge-controller/CHANGELOG.md +++ b/packages/bridge-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [73.2.1] + ### Changed - Bump `@metamask/assets-controllers` from `^108.2.0` to `^108.4.0` ([#8941](https://github.com/MetaMask/core/pull/8941), [#8981](https://github.com/MetaMask/core/pull/8981)) @@ -1548,7 +1550,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#5317](https://github.com/MetaMask/core/pull/5317)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.2.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.2.1...HEAD +[73.2.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.2.0...@metamask/bridge-controller@73.2.1 [73.2.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.1.0...@metamask/bridge-controller@73.2.0 [73.1.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.0.1...@metamask/bridge-controller@73.1.0 [73.0.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@73.0.0...@metamask/bridge-controller@73.0.1 diff --git a/packages/bridge-controller/package.json b/packages/bridge-controller/package.json index 7fcdfa5fe0..b4c0622019 100644 --- a/packages/bridge-controller/package.json +++ b/packages/bridge-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/bridge-controller", - "version": "73.2.0", + "version": "73.2.1", "description": "Manages bridge-related quote fetching functionality for MetaMask", "keywords": [ "Ethereum", @@ -57,22 +57,22 @@ "@ethersproject/constants": "^5.7.0", "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@metamask/accounts-controller": "^38.1.2", - "@metamask/assets-controller": "^8.3.1", - "@metamask/assets-controllers": "^108.4.0", + "@metamask/accounts-controller": "^39.0.0", + "@metamask/assets-controller": "^8.3.2", + "@metamask/assets-controllers": "^108.5.0", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/gas-fee-controller": "^26.2.2", "@metamask/keyring-api": "^23.1.0", "@metamask/messenger": "^1.2.0", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/multichain-network-controller": "^3.1.2", + "@metamask/multichain-network-controller": "^3.1.3", "@metamask/network-controller": "^32.0.0", "@metamask/polling-controller": "^16.0.6", "@metamask/profile-sync-controller": "^28.1.1", "@metamask/remote-feature-flag-controller": "^4.2.2", "@metamask/snaps-controllers": "^19.0.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "bignumber.js": "^9.1.2", "reselect": "^5.1.1", diff --git a/packages/bridge-status-controller/CHANGELOG.md b/packages/bridge-status-controller/CHANGELOG.md index 11c948e4c1..f636e57719 100644 --- a/packages/bridge-status-controller/CHANGELOG.md +++ b/packages/bridge-status-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [72.0.2] + ## [72.0.1] ### Fixed @@ -1247,7 +1249,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#5317](https://github.com/MetaMask/core/pull/5317)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@72.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@72.0.2...HEAD +[72.0.2]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@72.0.1...@metamask/bridge-status-controller@72.0.2 [72.0.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@72.0.0...@metamask/bridge-status-controller@72.0.1 [72.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@71.2.1...@metamask/bridge-status-controller@72.0.0 [71.2.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@71.2.0...@metamask/bridge-status-controller@71.2.1 diff --git a/packages/bridge-status-controller/package.json b/packages/bridge-status-controller/package.json index acddb1d089..d6d91744b8 100644 --- a/packages/bridge-status-controller/package.json +++ b/packages/bridge-status-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/bridge-status-controller", - "version": "72.0.1", + "version": "72.0.2", "description": "Manages bridge-related status fetching functionality for MetaMask", "keywords": [ "Ethereum", @@ -52,9 +52,9 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", - "@metamask/bridge-controller": "^73.2.0", + "@metamask/bridge-controller": "^73.2.1", "@metamask/controller-utils": "^12.1.0", "@metamask/gas-fee-controller": "^26.2.2", "@metamask/keyring-controller": "^26.0.0", @@ -64,7 +64,7 @@ "@metamask/profile-sync-controller": "^28.1.1", "@metamask/snaps-controllers": "^19.0.0", "@metamask/superstruct": "^3.1.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "bignumber.js": "^9.1.2", "uuid": "^8.3.2" diff --git a/packages/build-utils/CHANGELOG.md b/packages/build-utils/CHANGELOG.md index a007a93d91..e7d9bee939 100644 --- a/packages/build-utils/CHANGELOG.md +++ b/packages/build-utils/CHANGELOG.md @@ -7,22 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) -- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) -- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) -- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) -- chore(lint): Fix suppressed ESLint errors in `build-utils` package ([#7460](https://github.com/MetaMask/core/pull/7460)) -- chore: Re-enable `@typescript-eslint/no-unnecessary-type-assertions` ([#7296](https://github.com/MetaMask/core/pull/7296)) -- chore: Fix all auto-fixable ESLint warnings ([#7105](https://github.com/MetaMask/core/pull/7105)) -- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) -- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) - ### Changed - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511)) @@ -37,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [3.0.2] @@ -63,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -105,7 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Initial release ([#3577](https://github.com/MetaMask/core/pull/3577), [#3588](https://github.com/MetaMask/core/pull/3588)) +- 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@3.0.4...HEAD [3.0.4]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.3...@metamask/build-utils@3.0.4 diff --git a/packages/client-controller/CHANGELOG.md b/packages/client-controller/CHANGELOG.md index 8c29474a16..85bdd90982 100644 --- a/packages/client-controller/CHANGELOG.md +++ b/packages/client-controller/CHANGELOG.md @@ -7,17 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/composable-controller/CHANGELOG.md b/packages/composable-controller/CHANGELOG.md index 5cf9ee4ec5..24f50341c7 100644 --- a/packages/composable-controller/CHANGELOG.md +++ b/packages/composable-controller/CHANGELOG.md @@ -7,16 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) -- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) - ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.3.0` ([#8661](https://github.com/MetaMask/core/pull/8661)) @@ -58,16 +48,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632), [#6807](https://github.com/MetaMask/core/pull/6807)) +- Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632),[#6807](https://github.com/MetaMask/core/pull/6807)) ## [11.0.0] ### Changed -- **BREAKING:** Re-define `ComposableControllerStateConstraint` type using `StateConstraint` instead of `LegacyControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018)) -- **BREAKING:** Constrain the `ComposableControllerState` generic argument for the `ComposableController` class using `ComposableControllerStateConstraint` instead of `LegacyComposableControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018)) -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082), [#5272](https://github.com/MetaMask/core/pull/5272)) +- **BREAKING:** Re-define `ComposableControllerStateConstraint` type using `StateConstraint` instead of `LegacyControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018/)) +- **BREAKING:** Constrain the `ComposableControllerState` generic argument for the `ComposableController` class using `ComposableControllerStateConstraint` instead of `LegacyComposableControllerStateConstraint` ([#5018](https://github.com/MetaMask/core/pull/5018/)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082)), ([#5272](https://github.com/MetaMask/core/pull/5272)) ## [10.0.0] @@ -94,7 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -153,9 +143,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** The `ComposableController` class is now a generic class that expects one generic argument `ComposableControllerState`. ([#3952](https://github.com/MetaMask/core/pull/3952)) +- **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)) +- **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)) diff --git a/packages/connectivity-controller/CHANGELOG.md b/packages/connectivity-controller/CHANGELOG.md index 490fbd6cd5..e7d226e25b 100644 --- a/packages/connectivity-controller/CHANGELOG.md +++ b/packages/connectivity-controller/CHANGELOG.md @@ -7,17 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Added - Add `connectivityControllerSelectors` with `selectConnectivityStatus` and `selectIsOffline` selectors ([#7701](https://github.com/MetaMask/core/pull/7701)) diff --git a/packages/core-backend/CHANGELOG.md b/packages/core-backend/CHANGELOG.md index b5b8e1809d..dee87ee923 100644 --- a/packages/core-backend/CHANGELOG.md +++ b/packages/core-backend/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.3.2] + ## [6.3.1] ### Changed @@ -292,7 +294,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Type definitions** - Comprehensive TypeScript types for transactions, balances, WebSocket messages, and service configurations - **Logging infrastructure** - Structured logging with module-specific loggers for debugging and monitoring -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.3.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.3.2...HEAD +[6.3.2]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.3.1...@metamask/core-backend@6.3.2 [6.3.1]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.3.0...@metamask/core-backend@6.3.1 [6.3.0]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.2.2...@metamask/core-backend@6.3.0 [6.2.2]: https://github.com/MetaMask/core/compare/@metamask/core-backend@6.2.1...@metamask/core-backend@6.2.2 diff --git a/packages/core-backend/package.json b/packages/core-backend/package.json index e4a777feba..78f81d2c5f 100644 --- a/packages/core-backend/package.json +++ b/packages/core-backend/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/core-backend", - "version": "6.3.1", + "version": "6.3.2", "description": "Core backend services for MetaMask", "keywords": [ "Ethereum", @@ -53,7 +53,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/controller-utils": "^12.1.0", "@metamask/keyring-controller": "^26.0.0", "@metamask/messenger": "^1.2.0", diff --git a/packages/earn-controller/package.json b/packages/earn-controller/package.json index c975fd93a5..c9a4a0880b 100644 --- a/packages/earn-controller/package.json +++ b/packages/earn-controller/package.json @@ -55,7 +55,7 @@ "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@metamask/account-tree-controller": "^7.5.0", + "@metamask/account-tree-controller": "^7.5.1", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/keyring-api": "^23.1.0", @@ -66,7 +66,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^6.1.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@ts-bridge/cli": "^0.6.4", "@types/jest": "^29.5.14", "deepmerge": "^4.2.2", diff --git a/packages/eip-5792-middleware/CHANGELOG.md b/packages/eip-5792-middleware/CHANGELOG.md index 44f8e3cdf0..efe85d6134 100644 --- a/packages/eip-5792-middleware/CHANGELOG.md +++ b/packages/eip-5792-middleware/CHANGELOG.md @@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release/1003.0.0 ([#8912](https://github.com/MetaMask/core/pull/8912)) - ### Changed - Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.0` ([#8848](https://github.com/MetaMask/core/pull/8848)) @@ -64,7 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/transaction-controller` from `^61.3.0` to `^62.7.0` ([#7007](https://github.com/MetaMask/core/pull/7007), [#7126](https://github.com/MetaMask/core/pull/7126), [#7153](https://github.com/MetaMask/core/pull/7153), [#7202](https://github.com/MetaMask/core/pull/7202), [#7215](https://github.com/MetaMask/core/pull/7215), [#7220](https://github.com/MetaMask/core/pull/7220), [#7236](https://github.com/MetaMask/core/pull/7236), [#7257](https://github.com/MetaMask/core/pull/7257), [#7289](https://github.com/MetaMask/core/pull/7289), [#7325](https://github.com/MetaMask/core/pull/7325), [#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) +- Bump `@metamask/transaction-controller` from `^61.3.0` to `^62.7.0` ([#7007](https://github.com/MetaMask/core/pull/7007), [#7126](https://github.com/MetaMask/core/pull/7126), [#7153](https://github.com/MetaMask/core/pull/7153), [#7202](https://github.com/MetaMask/core/pull/7202), [#7215](https://github.com/MetaMask/core/pull/7202), [#7220](https://github.com/MetaMask/core/pull/7220), [#7236](https://github.com/MetaMask/core/pull/7236), [#7257](https://github.com/MetaMask/core/pull/7257), [#7289](https://github.com/MetaMask/core/pull/7289), [#7325](https://github.com/MetaMask/core/pull/7325), [#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) ## [2.0.0] @@ -98,7 +94,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708)) -- Bump `@metamask/transaction-controller` from `^60.4.0` to `^60.6.0` ([#6708](https://github.com/MetaMask/core/pull/6708), [#6771](https://github.com/MetaMask/core/pull/6771)) +- Bump `@metamask/transaction-controller` from `^60.4.0` to `^60.6.0` ([#6708](https://github.com/MetaMask/core/pull/6733), [#6771](https://github.com/MetaMask/core/pull/6771)) - Remove dependency `@metamask/eth-json-rpc-middleware` ([#6714](https://github.com/MetaMask/core/pull/6714)) ## [1.2.0] diff --git a/packages/eip-5792-middleware/package.json b/packages/eip-5792-middleware/package.json index 82e1468f7b..b7f36aab8f 100644 --- a/packages/eip-5792-middleware/package.json +++ b/packages/eip-5792-middleware/package.json @@ -53,7 +53,7 @@ "dependencies": { "@metamask/messenger": "^1.2.0", "@metamask/superstruct": "^3.1.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "lodash": "^4.17.21", "uuid": "^8.3.2" diff --git a/packages/eth-block-tracker/CHANGELOG.md b/packages/eth-block-tracker/CHANGELOG.md index 4140d23aa4..a5245d8834 100644 --- a/packages/eth-block-tracker/CHANGELOG.md +++ b/packages/eth-block-tracker/CHANGELOG.md @@ -7,20 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release 973.0.0 ([#8753](https://github.com/MetaMask/core/pull/8753)) -- Release 970.0.0 ([#8746](https://github.com/MetaMask/core/pull/8746)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- Release 840.0.0 ([#8078](https://github.com/MetaMask/core/pull/8078)) -- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) -- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) -- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) -- Release 795.0.0 ([#7856](https://github.com/MetaMask/core/pull/7856)) -- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) - ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.3.0` ([#8661](https://github.com/MetaMask/core/pull/8661)) diff --git a/packages/eth-json-rpc-middleware/CHANGELOG.md b/packages/eth-json-rpc-middleware/CHANGELOG.md index 39d6f822b2..3ddc7b7fd2 100644 --- a/packages/eth-json-rpc-middleware/CHANGELOG.md +++ b/packages/eth-json-rpc-middleware/CHANGELOG.md @@ -7,13 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release 978.0.0 ([#8774](https://github.com/MetaMask/core/pull/8774)) -- Release 975.0.0 ([#8765](https://github.com/MetaMask/core/pull/8765)) -- feat(gator-permissions-controller): Added redeemer rule ([#8537](https://github.com/MetaMask/core/pull/8537)) -- Release 947.0.0 ([#8636](https://github.com/MetaMask/core/pull/8636)) - ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) diff --git a/packages/eth-json-rpc-provider/CHANGELOG.md b/packages/eth-json-rpc-provider/CHANGELOG.md index 35d1b32c25..a23945cd76 100644 --- a/packages/eth-json-rpc-provider/CHANGELOG.md +++ b/packages/eth-json-rpc-provider/CHANGELOG.md @@ -7,12 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) - ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) @@ -109,7 +103,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/foundryup/CHANGELOG.md b/packages/foundryup/CHANGELOG.md index ac20139361..f6ce1417dc 100644 --- a/packages/foundryup/CHANGELOG.md +++ b/packages/foundryup/CHANGELOG.md @@ -7,20 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) -- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) -- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) -- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) -- chore: Update ESLint config packages to v15 ([#7305](https://github.com/MetaMask/core/pull/7305)) -- chore: Re-enable `@typescript-eslint/no-unnecessary-type-assertions` ([#7296](https://github.com/MetaMask/core/pull/7296)) -- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) -- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) - ## [1.0.1] ### Fixed diff --git a/packages/gator-permissions-controller/package.json b/packages/gator-permissions-controller/package.json index 0c07187308..1c6210e4a4 100644 --- a/packages/gator-permissions-controller/package.json +++ b/packages/gator-permissions-controller/package.json @@ -63,7 +63,7 @@ "@metamask/snaps-controllers": "^19.0.0", "@metamask/snaps-sdk": "^11.0.0", "@metamask/snaps-utils": "^12.1.2", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0" }, "devDependencies": { diff --git a/packages/json-rpc-middleware-stream/CHANGELOG.md b/packages/json-rpc-middleware-stream/CHANGELOG.md index 3fd7cfa490..d7cdd1f041 100644 --- a/packages/json-rpc-middleware-stream/CHANGELOG.md +++ b/packages/json-rpc-middleware-stream/CHANGELOG.md @@ -7,23 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment ([#8011](https://github.com/MetaMask/core/pull/8011)) -- chore: upgrade `typedoc` from `^0.24.8` to `^0.25.13` ([#7898](https://github.com/MetaMask/core/pull/7898)) -- chore: migrate Jest from v27 to v29 ([#7894](https://github.com/MetaMask/core/pull/7894)) -- chore: upgrade Jest-related packages to latest 27.x versions ([#7792](https://github.com/MetaMask/core/pull/7792)) -- chore(lint): Fix suppressed ESLint errors in `json-rpc-middleware-stream` package ([#7463](https://github.com/MetaMask/core/pull/7463)) -- chore: Update ESLint config packages to v15 ([#7305](https://github.com/MetaMask/core/pull/7305)) -- Revert "Release 687.0.0" ([#7201](https://github.com/MetaMask/core/pull/7201)) -- Release 687.0.0 ([#7190](https://github.com/MetaMask/core/pull/7190)) -- chore: Fix all auto-fixable ESLint warnings ([#7105](https://github.com/MetaMask/core/pull/7105)) -- chore: Update `typescript` to v5.3 ([#7081](https://github.com/MetaMask/core/pull/7081)) -- fix: Fix build script not working because of missing `@ts-bridge/cli` dependency ([#7040](https://github.com/MetaMask/core/pull/7040)) - ### Changed - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511)) @@ -78,7 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -241,13 +224,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [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 [6.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@6.0.0...@metamask/json-rpc-middleware-stream@6.0.1 -[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@5.0.1...@metamask/json-rpc-middleware-stream@6.0.0 -[5.0.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@5.0.0...@metamask/json-rpc-middleware-stream@5.0.1 -[5.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.3...@metamask/json-rpc-middleware-stream@5.0.0 -[4.2.3]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.2...@metamask/json-rpc-middleware-stream@4.2.3 -[4.2.2]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.1...@metamask/json-rpc-middleware-stream@4.2.2 -[4.2.1]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.2.0...@metamask/json-rpc-middleware-stream@4.2.1 -[4.2.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.1.0...@metamask/json-rpc-middleware-stream@4.2.0 -[4.1.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@4.0.0...@metamask/json-rpc-middleware-stream@4.1.0 -[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/json-rpc-middleware-stream@3.0.0...@metamask/json-rpc-middleware-stream@4.0.0 -[3.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/json-rpc-middleware-stream@3.0.0 +[6.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@5.0.1...@metamask/json-rpc-middleware-stream@6.0.0 +[5.0.1]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@5.0.0...json-rpc-middleware-stream@5.0.1 +[5.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.3...json-rpc-middleware-stream@5.0.0 +[4.2.3]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.2...json-rpc-middleware-stream@4.2.3 +[4.2.2]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.1...json-rpc-middleware-stream@4.2.2 +[4.2.1]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.2.0...json-rpc-middleware-stream@4.2.1 +[4.2.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.1.0...json-rpc-middleware-stream@4.2.0 +[4.1.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@4.0.0...json-rpc-middleware-stream@4.1.0 +[4.0.0]: https://github.com/MetaMask/core/compare/json-rpc-middleware-stream@3.0.0...json-rpc-middleware-stream@4.0.0 +[3.0.0]: https://github.com/MetaMask/core/releases/tag/json-rpc-middleware-stream@3.0.0 diff --git a/packages/logging-controller/CHANGELOG.md b/packages/logging-controller/CHANGELOG.md index 1fc8bed5f7..414e6703f2 100644 --- a/packages/logging-controller/CHANGELOG.md +++ b/packages/logging-controller/CHANGELOG.md @@ -78,8 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) ## [6.0.3] @@ -106,7 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/message-manager/CHANGELOG.md b/packages/message-manager/CHANGELOG.md index cf81902acb..c00daf76cb 100644 --- a/packages/message-manager/CHANGELOG.md +++ b/packages/message-manager/CHANGELOG.md @@ -91,8 +91,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) - Bump `@metamask/utils` from `^11.0.1` to `^11.1.0` ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [12.0.0] @@ -153,7 +153,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/money-account-controller/CHANGELOG.md b/packages/money-account-controller/CHANGELOG.md index d4d49a0123..bb30aa91e0 100644 --- a/packages/money-account-controller/CHANGELOG.md +++ b/packages/money-account-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.2] + ## [0.3.1] ### Changed @@ -42,7 +44,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `MoneyAccountController` ([#8361](https://github.com/MetaMask/core/pull/8361)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.3.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.3.2...HEAD +[0.3.2]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.3.1...@metamask/money-account-controller@0.3.2 [0.3.1]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.3.0...@metamask/money-account-controller@0.3.1 [0.3.0]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.2.0...@metamask/money-account-controller@0.3.0 [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/money-account-controller@0.1.0...@metamask/money-account-controller@0.2.0 diff --git a/packages/money-account-controller/package.json b/packages/money-account-controller/package.json index 159d239f7d..c7f36f087e 100644 --- a/packages/money-account-controller/package.json +++ b/packages/money-account-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/money-account-controller", - "version": "0.3.1", + "version": "0.3.2", "description": "MetaMask Money account controller", "keywords": [ "Ethereum", @@ -53,7 +53,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/eth-money-keyring": "^2.0.4", "@metamask/keyring-api": "^23.1.0", diff --git a/packages/multichain-account-service/CHANGELOG.md b/packages/multichain-account-service/CHANGELOG.md index 00664d768c..ce4a425a78 100644 --- a/packages/multichain-account-service/CHANGELOG.md +++ b/packages/multichain-account-service/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.0.2] + ## [10.0.1] ### Changed @@ -493,7 +495,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `MultichainAccountService` ([#6141](https://github.com/MetaMask/core/pull/6141), [#6165](https://github.com/MetaMask/core/pull/6165)) - This service manages multichain accounts/wallets. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@10.0.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@10.0.2...HEAD +[10.0.2]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@10.0.1...@metamask/multichain-account-service@10.0.2 [10.0.1]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@10.0.0...@metamask/multichain-account-service@10.0.1 [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@9.0.0...@metamask/multichain-account-service@10.0.0 [9.0.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@8.0.1...@metamask/multichain-account-service@9.0.0 diff --git a/packages/multichain-account-service/package.json b/packages/multichain-account-service/package.json index 480e829ea9..24ae18b444 100644 --- a/packages/multichain-account-service/package.json +++ b/packages/multichain-account-service/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/multichain-account-service", - "version": "10.0.1", + "version": "10.0.2", "description": "Service to manage multichain accounts", "keywords": [ "Ethereum", @@ -54,7 +54,7 @@ }, "dependencies": { "@ethereumjs/util": "^9.1.0", - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/eth-snap-keyring": "^22.0.1", "@metamask/key-tree": "^10.1.1", @@ -64,7 +64,7 @@ "@metamask/keyring-snap-client": "^9.0.2", "@metamask/keyring-utils": "^3.2.1", "@metamask/messenger": "^1.2.0", - "@metamask/snap-account-service": "^0.2.1", + "@metamask/snap-account-service": "^0.3.0", "@metamask/snaps-controllers": "^19.0.0", "@metamask/snaps-sdk": "^11.0.0", "@metamask/snaps-utils": "^12.1.2", diff --git a/packages/multichain-api-middleware/CHANGELOG.md b/packages/multichain-api-middleware/CHANGELOG.md index 65210d378d..7cc61b6218 100644 --- a/packages/multichain-api-middleware/CHANGELOG.md +++ b/packages/multichain-api-middleware/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.1.3] + ### Changed - Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) @@ -233,7 +235,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.1.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.1.3...HEAD +[3.1.3]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.1.2...@metamask/multichain-api-middleware@3.1.3 [3.1.2]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.1.1...@metamask/multichain-api-middleware@3.1.2 [3.1.1]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.1.0...@metamask/multichain-api-middleware@3.1.1 [3.1.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-api-middleware@3.0.0...@metamask/multichain-api-middleware@3.1.0 diff --git a/packages/multichain-api-middleware/package.json b/packages/multichain-api-middleware/package.json index 10ed6274a1..9a8ea57a28 100644 --- a/packages/multichain-api-middleware/package.json +++ b/packages/multichain-api-middleware/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/multichain-api-middleware", - "version": "3.1.2", + "version": "3.1.3", "description": "JSON-RPC methods and middleware to support the MetaMask Multichain API", "keywords": [ "Ethereum", @@ -51,7 +51,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/api-specs": "^0.14.0", "@metamask/chain-agnostic-permission": "^1.6.1", "@metamask/controller-utils": "^12.1.0", @@ -68,7 +68,7 @@ "devDependencies": { "@metamask/auto-changelog": "^6.1.0", "@metamask/eth-json-rpc-filters": "^9.0.0", - "@metamask/multichain-transactions-controller": "^7.1.0", + "@metamask/multichain-transactions-controller": "^7.1.1", "@metamask/safe-event-emitter": "^3.0.0", "@ts-bridge/cli": "^0.6.4", "@types/jest": "^29.5.14", diff --git a/packages/multichain-network-controller/CHANGELOG.md b/packages/multichain-network-controller/CHANGELOG.md index f4295d30a2..cb1b99fafe 100644 --- a/packages/multichain-network-controller/CHANGELOG.md +++ b/packages/multichain-network-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.1.3] + ### Changed - Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) @@ -286,7 +288,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Handle both EVM and non-EVM network and account switching for the associated network. - Act as a proxy for the `NetworkController` (for EVM network changes). -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.1.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.1.3...HEAD +[3.1.3]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.1.2...@metamask/multichain-network-controller@3.1.3 [3.1.2]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.1.1...@metamask/multichain-network-controller@3.1.2 [3.1.1]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.1.0...@metamask/multichain-network-controller@3.1.1 [3.1.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@3.0.6...@metamask/multichain-network-controller@3.1.0 diff --git a/packages/multichain-network-controller/package.json b/packages/multichain-network-controller/package.json index 2a152b4816..b7aa7dd7a8 100644 --- a/packages/multichain-network-controller/package.json +++ b/packages/multichain-network-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/multichain-network-controller", - "version": "3.1.2", + "version": "3.1.3", "description": "Multichain network controller", "keywords": [ "Ethereum", @@ -53,7 +53,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/keyring-api": "^23.1.0", diff --git a/packages/multichain-transactions-controller/CHANGELOG.md b/packages/multichain-transactions-controller/CHANGELOG.md index 3e9dc4ace9..e5a37e24c7 100644 --- a/packages/multichain-transactions-controller/CHANGELOG.md +++ b/packages/multichain-transactions-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.1.1] + ### Uncategorized - Release `964.0.0` ([#8722](https://github.com/MetaMask/core/pull/8722)) @@ -293,7 +295,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#5133](https://github.com/MetaMask/core/pull/5133), [#5177](https://github.com/MetaMask/core/pull/5177)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.1.1...HEAD +[7.1.1]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.1.0...@metamask/multichain-transactions-controller@7.1.1 [7.1.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.0.4...@metamask/multichain-transactions-controller@7.1.0 [7.0.4]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.0.3...@metamask/multichain-transactions-controller@7.0.4 [7.0.3]: https://github.com/MetaMask/core/compare/@metamask/multichain-transactions-controller@7.0.2...@metamask/multichain-transactions-controller@7.0.3 diff --git a/packages/multichain-transactions-controller/package.json b/packages/multichain-transactions-controller/package.json index 00359f1ba4..48aab69eae 100644 --- a/packages/multichain-transactions-controller/package.json +++ b/packages/multichain-transactions-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/multichain-transactions-controller", - "version": "7.1.0", + "version": "7.1.1", "description": "This package is responsible for getting transactions from our Bitcoin and Solana snaps", "keywords": [ "Ethereum", @@ -53,7 +53,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-internal-api": "^11.0.1", diff --git a/packages/name-controller/CHANGELOG.md b/packages/name-controller/CHANGELOG.md index 04affc8e86..68aeac2afa 100644 --- a/packages/name-controller/CHANGELOG.md +++ b/packages/name-controller/CHANGELOG.md @@ -64,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/utils` from `^11.2.0` to `^11.8.1` ([#6054](https://github.com/MetaMask/core/pull/6054), [#6588](https://github.com/MetaMask/core/pull/6588), [#6708](https://github.com/MetaMask/core/pull/6708)) +- Bump `@metamask/utils` from `^11.2.0` to `^11.8.1` ([#6054](https://github.com/MetaMask/core/pull/6054)[#6588](https://github.com/MetaMask/core/pull/6588), [#6708](https://github.com/MetaMask/core/pull/6708)) - Bump `@metamask/base-controller` from `^8.0.0` to `^8.4.1` ([#5722](https://github.com/MetaMask/core/pull/5722), [#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632), [#6807](https://github.com/MetaMask/core/pull/6807)) - Bump `@metamask/controller-utils` from `^11.5.0` to `^11.14.1` ([#5439](https://github.com/MetaMask/core/pull/5439), [#5583](https://github.com/MetaMask/core/pull/5583), [#5765](https://github.com/MetaMask/core/pull/5765), [#5812](https://github.com/MetaMask/core/pull/5812), [#5935](https://github.com/MetaMask/core/pull/5935), [#6069](https://github.com/MetaMask/core/pull/6069), [#6303](https://github.com/MetaMask/core/pull/6303), [#6620](https://github.com/MetaMask/core/pull/6620), [#6629](https://github.com/MetaMask/core/pull/6629), [#6807](https://github.com/MetaMask/core/pull/6807)) @@ -72,9 +72,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/base-controller` from `^7.1.0` to `^8.0.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) - Bump `@metamask/base-controller` from `^7.0.0` to `^7.1.0` ([#5079](https://github.com/MetaMask/core/pull/5079)) ## [8.0.2] @@ -103,7 +103,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/network-enablement-controller/package.json b/packages/network-enablement-controller/package.json index 06e8086824..dbcf19f3f0 100644 --- a/packages/network-enablement-controller/package.json +++ b/packages/network-enablement-controller/package.json @@ -57,10 +57,10 @@ "@metamask/controller-utils": "^12.1.0", "@metamask/keyring-api": "^23.1.0", "@metamask/messenger": "^1.2.0", - "@metamask/multichain-network-controller": "^3.1.2", + "@metamask/multichain-network-controller": "^3.1.3", "@metamask/network-controller": "^32.0.0", "@metamask/slip44": "^4.3.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "reselect": "^5.1.1" }, diff --git a/packages/permission-log-controller/CHANGELOG.md b/packages/permission-log-controller/CHANGELOG.md index 76586a5353..6109a43f09 100644 --- a/packages/permission-log-controller/CHANGELOG.md +++ b/packages/permission-log-controller/CHANGELOG.md @@ -7,18 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Use Oxfmt for import sorting instead of `import-x/order` ([#8438](https://github.com/MetaMask/core/pull/8438)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.5.0` ([#8661](https://github.com/MetaMask/core/pull/8661), [#8746](https://github.com/MetaMask/core/pull/8746), [#8753](https://github.com/MetaMask/core/pull/8753)) @@ -88,9 +76,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.0` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082), [#5272](https://github.com/MetaMask/core/pull/5272)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/base-controller` from `^7.0.0` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/json-rpc-engine` from `^10.0.1` to `^10.0.3` ([#5082](https://github.com/MetaMask/core/pull/5082)), ([#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) - Bump `nanoid` from `^3.1.31` to `^3.3.8` ([#5073](https://github.com/MetaMask/core/pull/5073)) ## [3.0.2] @@ -124,7 +112,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our diff --git a/packages/perps-controller/CHANGELOG.md b/packages/perps-controller/CHANGELOG.md index 7feb123ece..8af2f9c01a 100644 --- a/packages/perps-controller/CHANGELOG.md +++ b/packages/perps-controller/CHANGELOG.md @@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Release/1017.0.0 ([#8986](https://github.com/MetaMask/core/pull/8986)) - ## [7.0.0] ### Added diff --git a/packages/perps-controller/package.json b/packages/perps-controller/package.json index f61e6ec659..0ed7be9b37 100644 --- a/packages/perps-controller/package.json +++ b/packages/perps-controller/package.json @@ -107,7 +107,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/account-tree-controller": "^7.5.0", + "@metamask/account-tree-controller": "^7.5.1", "@metamask/auto-changelog": "^6.1.0", "@metamask/geolocation-controller": "^0.1.3", "@metamask/keyring-controller": "^26.0.0", @@ -115,7 +115,7 @@ "@metamask/network-controller": "^32.0.0", "@metamask/profile-sync-controller": "^28.1.1", "@metamask/remote-feature-flag-controller": "^4.2.2", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@ts-bridge/cli": "^0.6.4", "@types/jest": "^29.5.14", "@types/uuid": "^8.3.0", diff --git a/packages/phishing-controller/package.json b/packages/phishing-controller/package.json index 1d9f958038..3d296a697d 100644 --- a/packages/phishing-controller/package.json +++ b/packages/phishing-controller/package.json @@ -57,7 +57,7 @@ "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/messenger": "^1.2.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@noble/hashes": "^1.8.0", "@types/punycode": "^2.1.0", "ethereum-cryptography": "^2.1.2", diff --git a/packages/preferences-controller/CHANGELOG.md b/packages/preferences-controller/CHANGELOG.md index 642cbdd9e9..1a469c357a 100644 --- a/packages/preferences-controller/CHANGELOG.md +++ b/packages/preferences-controller/CHANGELOG.md @@ -7,17 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -62,7 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Remove legacy methods and state ([#8115](https://github.com/MetaMask/core/pull/8115)) - `identities`, `lostIdentities` and `selectedAddress` along with any associated methods and types were removed. - `setSmartAccountOptInForAccounts` was also removed as it is deprecated and not used in the clients. -- Removed `@metamask/keyring-controller` and `@metamask/controller-utils` dependencies ([#7995](https://github.com/MetaMask/core/pull/7995), [#8115](https://github.com/MetaMask/core/pull/8115)) +- Removed `@metamask/keyring-controller` and `@metamask/controller-utils` dependencies ([#7995](https://github.com/MetaMask/core/pull/7995)), ([#8115](https://github.com/MetaMask/core/pull/8115)) ## [22.1.0] @@ -221,8 +210,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) -- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135), [#5272](https://github.com/MetaMask/core/pull/5272)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/controller-utils` from `^11.4.4` to `^11.5.0` ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5272](https://github.com/MetaMask/core/pull/5272)) ## [15.0.1] @@ -234,7 +223,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) ## [14.0.0] @@ -287,7 +276,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -515,7 +504,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `disabledRpcMethodPreferences` state to PreferencesController. See [this PR on extension](https://github.com/MetaMask/metamask-extension/pull/17308) and [this ticket](https://github.com/MetaMask/metamask-mobile/issues/5676) ([#1109](https://github.com/MetaMask/core/pull/1109)) +- `disabledRpcMethodPreferences` state to PreferencesController ([#1109](https://github.com/MetaMask/core/pull/1109)). See [this PR on extension](https://github.com/MetaMask/metamask-extension/pull/17308) and [this ticket](https://github.com/MetaMask/metamask-mobile/issues/5676) ## [2.0.0] diff --git a/packages/profile-metrics-controller/CHANGELOG.md b/packages/profile-metrics-controller/CHANGELOG.md index 554b776484..cce9e0620e 100644 --- a/packages/profile-metrics-controller/CHANGELOG.md +++ b/packages/profile-metrics-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.1.6] + ## [3.1.5] ### Changed @@ -139,7 +141,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#7194](https://github.com/MetaMask/core/pull/7194), [#7196](https://github.com/MetaMask/core/pull/7196), [#7263](https://github.com/MetaMask/core/pull/7263)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.5...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.6...HEAD +[3.1.6]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.5...@metamask/profile-metrics-controller@3.1.6 [3.1.5]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.4...@metamask/profile-metrics-controller@3.1.5 [3.1.4]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.3...@metamask/profile-metrics-controller@3.1.4 [3.1.3]: https://github.com/MetaMask/core/compare/@metamask/profile-metrics-controller@3.1.2...@metamask/profile-metrics-controller@3.1.3 diff --git a/packages/profile-metrics-controller/package.json b/packages/profile-metrics-controller/package.json index 444dbad76b..f3710e6a32 100644 --- a/packages/profile-metrics-controller/package.json +++ b/packages/profile-metrics-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/profile-metrics-controller", - "version": "3.1.5", + "version": "3.1.6", "description": "Manages user profile metrics", "keywords": [ "Ethereum", @@ -53,14 +53,14 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/keyring-controller": "^26.0.0", "@metamask/messenger": "^1.2.0", "@metamask/polling-controller": "^16.0.6", "@metamask/profile-sync-controller": "^28.1.1", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "async-mutex": "^0.5.0" }, diff --git a/packages/profile-sync-controller/CHANGELOG.md b/packages/profile-sync-controller/CHANGELOG.md index 1b14006fa7..ea74007481 100644 --- a/packages/profile-sync-controller/CHANGELOG.md +++ b/packages/profile-sync-controller/CHANGELOG.md @@ -67,7 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Expose missing public `UserStorageController` methods through its messenger ([#7976](https://github.com/MetaMask/core/pull/7976)) +- Expose missing public `UserStorageController` methods through its messenger ([#7976](https://github.com/MetaMask/core/pull/7976/)) - The following actions are now available: - `UserStorageController:performDeleteStorageAllFeatureEntries` - `UserStorageController:listEntropySources` @@ -81,7 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Add client-side JWT `exp` claim validation to prevent stale cached tokens from being returned ([#8144](https://github.com/MetaMask/core/pull/8144)) - `validateLoginResponse` now decodes the JWT `exp` claim and rejects tokens that have actually expired, regardless of client-side TTL tracking (`obtainedAt`/`expiresIn`) - Non-JWT access tokens are now rejected as invalid. In production this has no effect (access tokens are always JWTs from the OIDC server), but E2E test mocks that use raw identifier strings as access tokens must be updated. `getMockAuthAccessTokenResponse` now wraps identifiers in a JWT; consumers should use `getE2EIdentifierFromJwt` (newly exported) to extract the identifier from the bearer token in mock servers. -- **BREAKING:** Standardize names of `AuthenticationController` and `UserStorageController` messenger action types ([#7976](https://github.com/MetaMask/core/pull/7976)) +- **BREAKING:** Standardize names of `AuthenticationController` and `UserStorageController` messenger action types ([#7976](https://github.com/MetaMask/core/pull/7976/)) - All existing types for messenger actions have been renamed so they end in `Action` (e.g. `AuthenticationControllerPerformSignIn` -> `AuthenticationControllerPerformSignInAction`). You will need to update imports appropriately. - This change only affects the types. The action type strings themselves have not changed, so you do not need to update the list of actions you pass when initializing `AuthenticationController` and `UserStorageController` messengers. @@ -355,7 +355,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Peer dependencies `@metamask/keyring-controller` and `@metamask/network-controller` are no longer also direct dependencies) ([#5464](https://github.com/MetaMask/core/pull/5464)) +- Peer dependencies `@metamask/keyring-controller` and `@metamask/network-controller` are no longer also direct dependencies ([#5464](https://github.com/MetaMask/core/pull/5464))) ## [10.1.0] @@ -455,7 +455,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^21.0.0` to `^22.0.0` ([#5218](https://github.com/MetaMask/core/pull/5218)) -- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190), [#5208](https://github.com/MetaMask/core/pull/5208)) +- Bump `@metamask/keyring-api` from `^14.0.0` to `^16.1.0` ([#5190](https://github.com/MetaMask/core/pull/5190)), ([#5208](https://github.com/MetaMask/core/pull/5208)) ## [4.1.1] @@ -482,7 +482,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^20.0.0` to `^21.0.0` ([#5140](https://github.com/MetaMask/core/pull/5140)) - Bump `@metamask/base-controller` from `7.1.0` to `^7.1.1` ([#5135](https://github.com/MetaMask/core/pull/5135)) - Bump `@metamask/keyring-api` from `^12.0.0` to `^13.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066)) -- Bump `@metamask/keyring-internal-api` from `^1.0.0` to `^2.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066), [#5136](https://github.com/MetaMask/core/pull/5136)) +- Bump `@metamask/keyring-internal-api` from `^1.0.0` to `^2.0.0` ([#5066](https://github.com/MetaMask/core/pull/5066)), ([#5136](https://github.com/MetaMask/core/pull/5136)) - Bump `@metamask/keyring-controller` from `^19.0.2` to `^19.0.3` ([#5140](https://github.com/MetaMask/core/pull/5140)) ## [3.3.0] @@ -561,8 +561,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) -- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4195)) +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) ## [1.0.2] @@ -649,7 +649,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump accounts related packages ([#4713](https://github.com/MetaMask/core/pull/4713), [#4728](https://github.com/MetaMask/core/pull/4728)) +- Bump accounts related packages ([#4713](https://github.com/MetaMask/core/pull/4713)), ([#4728](https://github.com/MetaMask/core/pull/4728)) - Those packages are now built slightly differently and are part of the [accounts monorepo](https://github.com/MetaMask/accounts). - Bump `@metamask/keyring-api` from `^8.1.0` to `^8.1.4` @@ -728,7 +728,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -833,6 +833,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - added `LoginResponse` validation in profile syncing SDK ([#4541](https://github.com/MetaMask/core/pull/4541)) + - added snap caching when calling the message signing snap ([#4532](https://github.com/MetaMask/core/pull/4532)) ### Removed @@ -854,6 +855,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - added platform field when logging in to receive correct OIDC access token ([#4480](https://github.com/MetaMask/core/pull/4480)) + - added metametrics validation in constructor ([#4480](https://github.com/MetaMask/core/pull/4480)) ### Changed diff --git a/packages/rate-limit-controller/CHANGELOG.md b/packages/rate-limit-controller/CHANGELOG.md index 345aea1afc..3942b766e7 100644 --- a/packages/rate-limit-controller/CHANGELOG.md +++ b/packages/rate-limit-controller/CHANGELOG.md @@ -7,14 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- Revert "Release 912.0.0 (#8451)" ([#8451](https://github.com/MetaMask/core/pull/8451)) -- Release 912.0.0 ([#8451](https://github.com/MetaMask/core/pull/8451)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) @@ -58,9 +50,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079), [#5135](https://github.com/MetaMask/core/pull/5135), [#5305](https://github.com/MetaMask/core/pull/5305)) +- Bump `@metamask/base-controller` from `^7.0.2` to `^8.0.0` ([#5079](https://github.com/MetaMask/core/pull/5079)), ([#5135](https://github.com/MetaMask/core/pull/5135)), ([#5305](https://github.com/MetaMask/core/pull/5305)) - Bump `@metamask/rpc-errors` from `^7.0.1` to `^7.0.2` ([#5080](https://github.com/MetaMask/core/pull/5080)) -- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223)) +- Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223)) ## [6.0.2] @@ -88,7 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. -- Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648)) +- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)). - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our @@ -105,7 +97,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.com/MetaMask/core/pull/4232)) +- Bump `@metamask/base-controller` to `^5.0.2` ([#4232](https://github.comMetaMask/core/pull/4232)) ## [5.0.1] diff --git a/packages/react-data-query/CHANGELOG.md b/packages/react-data-query/CHANGELOG.md index 2bea48614e..3e75ea4b24 100644 --- a/packages/react-data-query/CHANGELOG.md +++ b/packages/react-data-query/CHANGELOG.md @@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore(react-data-query): declare @metamask/messenger as a devDep ([#8971](https://github.com/MetaMask/core/pull/8971)) - ## [0.2.1] ### Changed diff --git a/packages/shield-controller/CHANGELOG.md b/packages/shield-controller/CHANGELOG.md index 0c8a3cfdcc..9c12f10371 100644 --- a/packages/shield-controller/CHANGELOG.md +++ b/packages/shield-controller/CHANGELOG.md @@ -135,13 +135,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added metrics in the Shield coverage response to track the latency ([#7133](https://github.com/MetaMask/core/pull/7133)) +- Added metrics in the Shield coverage response to track the latency ( [#7133](https://github.com/MetaMask/core/pull/7133)) ## [2.0.0] ### Changed -- **BREAKING:** Bump `@metamask/signature-controller` from `^35.0.0` to `^36.0.0` ([#4651](https://github.com/MetaMask/core/pull/4651)) +- **BREAKING:** Bump `@metamask/signature-controller` from `^35.0.0` to `^36.0.0` ( [#4651](https://github.com/MetaMask/core/pull/4651)) ## [1.2.0] diff --git a/packages/shield-controller/package.json b/packages/shield-controller/package.json index e50648de1d..91bf808844 100644 --- a/packages/shield-controller/package.json +++ b/packages/shield-controller/package.json @@ -56,8 +56,8 @@ "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", "@metamask/messenger": "^1.2.0", - "@metamask/signature-controller": "^39.2.3", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/signature-controller": "^39.2.4", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "cockatiel": "^3.1.2" }, diff --git a/packages/signature-controller/CHANGELOG.md b/packages/signature-controller/CHANGELOG.md index bf5ac219af..98806502c4 100644 --- a/packages/signature-controller/CHANGELOG.md +++ b/packages/signature-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [39.2.4] + ## [39.2.3] ### Changed @@ -772,7 +774,8 @@ 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@39.2.3...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@39.2.4...HEAD +[39.2.4]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@39.2.3...@metamask/signature-controller@39.2.4 [39.2.3]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@39.2.2...@metamask/signature-controller@39.2.3 [39.2.2]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@39.2.1...@metamask/signature-controller@39.2.2 [39.2.1]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@39.2.0...@metamask/signature-controller@39.2.1 diff --git a/packages/signature-controller/package.json b/packages/signature-controller/package.json index 232a599572..8865d2b8d6 100644 --- a/packages/signature-controller/package.json +++ b/packages/signature-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/signature-controller", - "version": "39.2.3", + "version": "39.2.4", "description": "Processes signing requests in order to sign arbitrary and typed data", "keywords": [ "Ethereum", @@ -53,7 +53,7 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "dependencies": { - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/approval-controller": "^9.0.1", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index c5f061a97c..bc55961c65 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.0] + ### Added - Add `SnapAccountService:account{AssetList,Balances,Transactions}Updated` events ([#8916](https://github.com/MetaMask/core/pull/8916)) @@ -75,7 +77,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632)) - Bump `@metamask/account-tree-controller` from `^7.3.0` to `^7.4.0` ([#8783](https://github.com/MetaMask/core/pull/8783)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.2.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.3.0...HEAD +[0.3.0]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.2.1...@metamask/snap-account-service@0.3.0 [0.2.1]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.2.0...@metamask/snap-account-service@0.2.1 [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/snap-account-service@0.1.0...@metamask/snap-account-service@0.2.0 [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/snap-account-service@0.1.0 diff --git a/packages/snap-account-service/package.json b/packages/snap-account-service/package.json index ce7cfcfe53..54cef1189f 100644 --- a/packages/snap-account-service/package.json +++ b/packages/snap-account-service/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/snap-account-service", - "version": "0.2.1", + "version": "0.3.0", "description": "Service for Account Management Snaps", "keywords": [ "Ethereum", @@ -54,7 +54,7 @@ }, "dependencies": { "@metamask/account-api": "^1.0.4", - "@metamask/account-tree-controller": "^7.5.0", + "@metamask/account-tree-controller": "^7.5.1", "@metamask/eth-snap-keyring": "^22.0.1", "@metamask/keyring-api": "^23.1.0", "@metamask/keyring-controller": "^26.0.0", diff --git a/packages/storage-service/CHANGELOG.md b/packages/storage-service/CHANGELOG.md index 89de265d13..4b5852c090 100644 --- a/packages/storage-service/CHANGELOG.md +++ b/packages/storage-service/CHANGELOG.md @@ -7,15 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- chore: Enable Oxfmt for generating method action types files ([#8498](https://github.com/MetaMask/core/pull/8498)) -- chore: Format changelogs with Oxfmt ([#8442](https://github.com/MetaMask/core/pull/8442)) -- chore: bump `@metamask/auto-changelog` to `^6.0.0` ([#8441](https://github.com/MetaMask/core/pull/8441)) -- chore: Replace Prettier with Oxfmt ([#8434](https://github.com/MetaMask/core/pull/8434)) -- feat: extract generate-action-types CLI into @metamask/messenger-cli ([#8378](https://github.com/MetaMask/core/pull/8378)) -- feat(messenger): add `generate-action-types` CLI tool as subpath export ([#8264](https://github.com/MetaMask/core/pull/8264)) - ### Changed - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632)) diff --git a/packages/subscription-controller/package.json b/packages/subscription-controller/package.json index b18b4a9e45..de933fca97 100644 --- a/packages/subscription-controller/package.json +++ b/packages/subscription-controller/package.json @@ -58,7 +58,7 @@ "@metamask/messenger": "^1.2.0", "@metamask/polling-controller": "^16.0.6", "@metamask/profile-sync-controller": "^28.1.1", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "bignumber.js": "^9.1.2" }, diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 54e87d9566..d66fd132f5 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [66.0.1] + ### Changed - Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) @@ -2456,7 +2458,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/transaction-controller@66.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@66.0.1...HEAD +[66.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@66.0.0...@metamask/transaction-controller@66.0.1 [66.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@65.4.0...@metamask/transaction-controller@66.0.0 [65.4.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@65.3.0...@metamask/transaction-controller@65.4.0 [65.3.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@65.2.0...@metamask/transaction-controller@65.3.0 diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index bf390c1086..a2fa78d178 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/transaction-controller", - "version": "66.0.0", + "version": "66.0.1", "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation", "keywords": [ "Ethereum", @@ -60,11 +60,11 @@ "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", "@ethersproject/wallet": "^5.7.0", - "@metamask/accounts-controller": "^38.1.2", + "@metamask/accounts-controller": "^39.0.0", "@metamask/approval-controller": "^9.0.1", "@metamask/base-controller": "^9.1.0", "@metamask/controller-utils": "^12.1.0", - "@metamask/core-backend": "^6.3.1", + "@metamask/core-backend": "^6.3.2", "@metamask/gas-fee-controller": "^26.2.2", "@metamask/messenger": "^1.2.0", "@metamask/metamask-eth-abis": "^3.1.1", diff --git a/packages/transaction-pay-controller/package.json b/packages/transaction-pay-controller/package.json index 9df6391658..75c5755361 100644 --- a/packages/transaction-pay-controller/package.json +++ b/packages/transaction-pay-controller/package.json @@ -57,11 +57,11 @@ "@ethersproject/abi": "^5.7.0", "@ethersproject/contracts": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@metamask/assets-controller": "^8.3.1", - "@metamask/assets-controllers": "^108.4.0", + "@metamask/assets-controller": "^8.3.2", + "@metamask/assets-controllers": "^108.5.0", "@metamask/base-controller": "^9.1.0", - "@metamask/bridge-controller": "^73.2.0", - "@metamask/bridge-status-controller": "^72.0.1", + "@metamask/bridge-controller": "^73.2.1", + "@metamask/bridge-status-controller": "^72.0.2", "@metamask/controller-utils": "^12.1.0", "@metamask/gas-fee-controller": "^26.2.2", "@metamask/keyring-controller": "^26.0.0", @@ -70,7 +70,7 @@ "@metamask/network-controller": "^32.0.0", "@metamask/ramps-controller": "^14.1.1", "@metamask/remote-feature-flag-controller": "^4.2.2", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "bignumber.js": "^9.1.2", "bn.js": "^5.2.1", diff --git a/packages/user-operation-controller/package.json b/packages/user-operation-controller/package.json index 5534ed940a..05cee5137d 100644 --- a/packages/user-operation-controller/package.json +++ b/packages/user-operation-controller/package.json @@ -65,7 +65,7 @@ "@metamask/polling-controller": "^16.0.6", "@metamask/rpc-errors": "^7.0.2", "@metamask/superstruct": "^3.1.0", - "@metamask/transaction-controller": "^66.0.0", + "@metamask/transaction-controller": "^66.0.1", "@metamask/utils": "^11.9.0", "bn.js": "^5.2.1", "immer": "^9.0.6", diff --git a/packages/wallet-framework-docs/CHANGELOG.md b/packages/wallet-framework-docs/CHANGELOG.md index 8cf5726c6c..b518709c7b 100644 --- a/packages/wallet-framework-docs/CHANGELOG.md +++ b/packages/wallet-framework-docs/CHANGELOG.md @@ -7,8 +7,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- Initialize Wallet Framework documentation ([#8927](https://github.com/MetaMask/core/pull/8927)) - [Unreleased]: https://github.com/MetaMask/core/ diff --git a/packages/wallet/CHANGELOG.md b/packages/wallet/CHANGELOG.md index d95d3e0500..787705fe66 100644 --- a/packages/wallet/CHANGELOG.md +++ b/packages/wallet/CHANGELOG.md @@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Uncategorized - -- refactor(wallet): migrate keyring + storage instances to directory convention ([#8977](https://github.com/MetaMask/core/pull/8977)) - ### Added - **BREAKING:** Wire `ApprovalController` into the default wallet initialization ([#8953](https://github.com/MetaMask/core/pull/8953)) diff --git a/yarn.lock b/yarn.lock index a2fa848dfd..c64fc1177d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5438,18 +5438,18 @@ __metadata: languageName: node linkType: hard -"@metamask/account-tree-controller@npm:^7.5.0, @metamask/account-tree-controller@workspace:packages/account-tree-controller": +"@metamask/account-tree-controller@npm:^7.5.1, @metamask/account-tree-controller@workspace:packages/account-tree-controller": version: 0.0.0-use.local resolution: "@metamask/account-tree-controller@workspace:packages/account-tree-controller" dependencies: "@metamask/account-api": "npm:^1.0.4" - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^26.0.0" "@metamask/messenger": "npm:^1.2.0" - "@metamask/multichain-account-service": "npm:^10.0.1" + "@metamask/multichain-account-service": "npm:^10.0.2" "@metamask/profile-sync-controller": "npm:^28.1.1" "@metamask/providers": "npm:^22.1.0" "@metamask/snaps-controllers": "npm:^19.0.0" @@ -5475,7 +5475,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/accounts-controller@npm:^38.1.2, @metamask/accounts-controller@workspace:packages/accounts-controller": +"@metamask/accounts-controller@npm:^39.0.0, @metamask/accounts-controller@workspace:packages/accounts-controller": version: 0.0.0-use.local resolution: "@metamask/accounts-controller@workspace:packages/accounts-controller" dependencies: @@ -5679,21 +5679,21 @@ __metadata: languageName: unknown linkType: soft -"@metamask/assets-controller@npm:^8.3.1, @metamask/assets-controller@workspace:packages/assets-controller": +"@metamask/assets-controller@npm:^8.3.2, @metamask/assets-controller@workspace:packages/assets-controller": version: 0.0.0-use.local resolution: "@metamask/assets-controller@workspace:packages/assets-controller" dependencies: "@ethereumjs/util": "npm:^9.1.0" "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/account-tree-controller": "npm:^7.5.0" - "@metamask/accounts-controller": "npm:^38.1.2" - "@metamask/assets-controllers": "npm:^108.4.0" + "@metamask/account-tree-controller": "npm:^7.5.1" + "@metamask/accounts-controller": "npm:^39.0.0" + "@metamask/assets-controllers": "npm:^108.5.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/client-controller": "npm:^1.0.1" "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/core-backend": "npm:^6.3.1" + "@metamask/core-backend": "npm:^6.3.2" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/keyring-controller": "npm:^26.0.0" "@metamask/keyring-internal-api": "npm:^11.0.1" @@ -5707,7 +5707,7 @@ __metadata: "@metamask/preferences-controller": "npm:^23.1.0" "@metamask/snaps-controllers": "npm:^19.0.0" "@metamask/snaps-utils": "npm:^12.1.2" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -5726,7 +5726,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/assets-controllers@npm:^108.4.0, @metamask/assets-controllers@workspace:packages/assets-controllers": +"@metamask/assets-controllers@npm:^108.5.0, @metamask/assets-controllers@workspace:packages/assets-controllers": version: 0.0.0-use.local resolution: "@metamask/assets-controllers@workspace:packages/assets-controllers" dependencies: @@ -5739,14 +5739,14 @@ __metadata: "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" "@metamask/account-api": "npm:^1.0.4" - "@metamask/account-tree-controller": "npm:^7.5.0" - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/account-tree-controller": "npm:^7.5.1" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/approval-controller": "npm:^9.0.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/contract-metadata": "npm:^2.4.0" "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/core-backend": "npm:^6.3.1" + "@metamask/core-backend": "npm:^6.3.2" "@metamask/eth-query": "npm:^4.0.0" "@metamask/ethjs-provider-http": "npm:^0.3.0" "@metamask/keyring-api": "npm:^23.1.0" @@ -5755,7 +5755,7 @@ __metadata: "@metamask/keyring-snap-client": "npm:^9.0.2" "@metamask/messenger": "npm:^1.2.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/multichain-account-service": "npm:^10.0.1" + "@metamask/multichain-account-service": "npm:^10.0.2" "@metamask/network-controller": "npm:^32.0.0" "@metamask/network-enablement-controller": "npm:^5.2.0" "@metamask/permission-controller": "npm:^13.1.1" @@ -5769,7 +5769,7 @@ __metadata: "@metamask/snaps-sdk": "npm:^11.0.0" "@metamask/snaps-utils": "npm:^12.1.2" "@metamask/storage-service": "npm:^1.0.1" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@tanstack/query-core": "npm:^5.62.16" "@ts-bridge/cli": "npm:^0.6.4" @@ -5926,7 +5926,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/bridge-controller@npm:^73.2.0, @metamask/bridge-controller@workspace:packages/bridge-controller": +"@metamask/bridge-controller@npm:^73.2.1, @metamask/bridge-controller@workspace:packages/bridge-controller": version: 0.0.0-use.local resolution: "@metamask/bridge-controller@workspace:packages/bridge-controller" dependencies: @@ -5935,9 +5935,9 @@ __metadata: "@ethersproject/constants": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/accounts-controller": "npm:^38.1.2" - "@metamask/assets-controller": "npm:^8.3.1" - "@metamask/assets-controllers": "npm:^108.4.0" + "@metamask/accounts-controller": "npm:^39.0.0" + "@metamask/assets-controller": "npm:^8.3.2" + "@metamask/assets-controllers": "npm:^108.5.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -5946,14 +5946,14 @@ __metadata: "@metamask/keyring-api": "npm:^23.1.0" "@metamask/messenger": "npm:^1.2.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/multichain-network-controller": "npm:^3.1.2" + "@metamask/multichain-network-controller": "npm:^3.1.3" "@metamask/network-controller": "npm:^32.0.0" "@metamask/polling-controller": "npm:^16.0.6" "@metamask/profile-sync-controller": "npm:^28.1.1" "@metamask/remote-feature-flag-controller": "npm:^4.2.2" "@metamask/snaps-controllers": "npm:^19.0.0" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -5973,14 +5973,14 @@ __metadata: languageName: unknown linkType: soft -"@metamask/bridge-status-controller@npm:^72.0.1, @metamask/bridge-status-controller@workspace:packages/bridge-status-controller": +"@metamask/bridge-status-controller@npm:^72.0.2, @metamask/bridge-status-controller@workspace:packages/bridge-status-controller": version: 0.0.0-use.local resolution: "@metamask/bridge-status-controller@workspace:packages/bridge-status-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" - "@metamask/bridge-controller": "npm:^73.2.0" + "@metamask/bridge-controller": "npm:^73.2.1" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/gas-fee-controller": "npm:^26.2.2" "@metamask/keyring-controller": "npm:^26.0.0" @@ -5990,7 +5990,7 @@ __metadata: "@metamask/profile-sync-controller": "npm:^28.1.1" "@metamask/snaps-controllers": "npm:^19.0.0" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -6279,11 +6279,11 @@ __metadata: languageName: unknown linkType: soft -"@metamask/core-backend@npm:^6.3.1, @metamask/core-backend@workspace:packages/core-backend": +"@metamask/core-backend@npm:^6.3.2, @metamask/core-backend@workspace:packages/core-backend": version: 0.0.0-use.local resolution: "@metamask/core-backend@workspace:packages/core-backend" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/keyring-controller": "npm:^26.0.0" @@ -6437,7 +6437,7 @@ __metadata: dependencies: "@ethersproject/bignumber": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/account-tree-controller": "npm:^7.5.0" + "@metamask/account-tree-controller": "npm:^7.5.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -6445,7 +6445,7 @@ __metadata: "@metamask/messenger": "npm:^1.2.0" "@metamask/network-controller": "npm:^32.0.0" "@metamask/stake-sdk": "npm:^3.2.1" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" deepmerge: "npm:^4.2.2" @@ -6468,7 +6468,7 @@ __metadata: "@metamask/messenger": "npm:^1.2.0" "@metamask/rpc-errors": "npm:^7.0.2" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -7050,7 +7050,7 @@ __metadata: "@metamask/snaps-controllers": "npm:^19.0.0" "@metamask/snaps-sdk": "npm:^11.0.0" "@metamask/snaps-utils": "npm:^12.1.2" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -7426,7 +7426,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/money-account-controller@workspace:packages/money-account-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/eth-money-keyring": "npm:^2.0.4" @@ -7476,13 +7476,13 @@ __metadata: languageName: unknown linkType: soft -"@metamask/multichain-account-service@npm:^10.0.1, @metamask/multichain-account-service@workspace:packages/multichain-account-service": +"@metamask/multichain-account-service@npm:^10.0.2, @metamask/multichain-account-service@workspace:packages/multichain-account-service": version: 0.0.0-use.local resolution: "@metamask/multichain-account-service@workspace:packages/multichain-account-service" dependencies: "@ethereumjs/util": "npm:^9.1.0" "@metamask/account-api": "npm:^1.0.4" - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -7496,7 +7496,7 @@ __metadata: "@metamask/keyring-utils": "npm:^3.2.1" "@metamask/messenger": "npm:^1.2.0" "@metamask/providers": "npm:^22.1.0" - "@metamask/snap-account-service": "npm:^0.2.1" + "@metamask/snap-account-service": "npm:^0.3.0" "@metamask/snaps-controllers": "npm:^19.0.0" "@metamask/snaps-sdk": "npm:^11.0.0" "@metamask/snaps-utils": "npm:^12.1.2" @@ -7527,14 +7527,14 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/multichain-api-middleware@workspace:packages/multichain-api-middleware" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/api-specs": "npm:^0.14.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/chain-agnostic-permission": "npm:^1.6.1" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/eth-json-rpc-filters": "npm:^9.0.0" "@metamask/json-rpc-engine": "npm:^10.5.0" - "@metamask/multichain-transactions-controller": "npm:^7.1.0" + "@metamask/multichain-transactions-controller": "npm:^7.1.1" "@metamask/network-controller": "npm:^32.0.0" "@metamask/permission-controller": "npm:^13.1.1" "@metamask/rpc-errors": "npm:^7.0.2" @@ -7555,11 +7555,11 @@ __metadata: languageName: unknown linkType: soft -"@metamask/multichain-network-controller@npm:^3.1.2, @metamask/multichain-network-controller@workspace:packages/multichain-network-controller": +"@metamask/multichain-network-controller@npm:^3.1.3, @metamask/multichain-network-controller@workspace:packages/multichain-network-controller": version: 0.0.0-use.local resolution: "@metamask/multichain-network-controller@workspace:packages/multichain-network-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -7588,11 +7588,11 @@ __metadata: languageName: unknown linkType: soft -"@metamask/multichain-transactions-controller@npm:^7.1.0, @metamask/multichain-transactions-controller@workspace:packages/multichain-transactions-controller": +"@metamask/multichain-transactions-controller@npm:^7.1.1, @metamask/multichain-transactions-controller@workspace:packages/multichain-transactions-controller": version: 0.0.0-use.local resolution: "@metamask/multichain-transactions-controller@workspace:packages/multichain-transactions-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/keyring-api": "npm:^23.1.0" @@ -7700,10 +7700,10 @@ __metadata: "@metamask/controller-utils": "npm:^12.1.0" "@metamask/keyring-api": "npm:^23.1.0" "@metamask/messenger": "npm:^1.2.0" - "@metamask/multichain-network-controller": "npm:^3.1.2" + "@metamask/multichain-network-controller": "npm:^3.1.3" "@metamask/network-controller": "npm:^32.0.0" "@metamask/slip44": "npm:^4.3.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -7889,7 +7889,7 @@ __metadata: resolution: "@metamask/perps-controller@workspace:packages/perps-controller" dependencies: "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/account-tree-controller": "npm:^7.5.0" + "@metamask/account-tree-controller": "npm:^7.5.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -7900,7 +7900,7 @@ __metadata: "@metamask/network-controller": "npm:^32.0.0" "@metamask/profile-sync-controller": "npm:^28.1.1" "@metamask/remote-feature-flag-controller": "npm:^4.2.2" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@myx-trade/sdk": "npm:^0.1.265" "@nktkas/hyperliquid": "npm:^0.32.2" @@ -7932,7 +7932,7 @@ __metadata: "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/messenger": "npm:^1.2.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@noble/hashes": "npm:^1.8.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -8009,7 +8009,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/profile-metrics-controller@workspace:packages/profile-metrics-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" @@ -8018,7 +8018,7 @@ __metadata: "@metamask/messenger": "npm:^1.2.0" "@metamask/polling-controller": "npm:^16.0.6" "@metamask/profile-sync-controller": "npm:^28.1.1" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -8314,8 +8314,8 @@ __metadata: "@metamask/base-controller": "npm:^9.1.0" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/messenger": "npm:^1.2.0" - "@metamask/signature-controller": "npm:^39.2.3" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/signature-controller": "npm:^39.2.4" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -8332,11 +8332,11 @@ __metadata: languageName: unknown linkType: soft -"@metamask/signature-controller@npm:^39.2.3, @metamask/signature-controller@workspace:packages/signature-controller": +"@metamask/signature-controller@npm:^39.2.4, @metamask/signature-controller@workspace:packages/signature-controller": version: 0.0.0-use.local resolution: "@metamask/signature-controller@workspace:packages/signature-controller" dependencies: - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/approval-controller": "npm:^9.0.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" @@ -8370,12 +8370,12 @@ __metadata: languageName: node linkType: hard -"@metamask/snap-account-service@npm:^0.2.1, @metamask/snap-account-service@workspace:packages/snap-account-service": +"@metamask/snap-account-service@npm:^0.3.0, @metamask/snap-account-service@workspace:packages/snap-account-service": version: 0.0.0-use.local resolution: "@metamask/snap-account-service@workspace:packages/snap-account-service" dependencies: "@metamask/account-api": "npm:^1.0.4" - "@metamask/account-tree-controller": "npm:^7.5.0" + "@metamask/account-tree-controller": "npm:^7.5.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/eth-snap-keyring": "npm:^22.0.1" "@metamask/keyring-api": "npm:^23.1.0" @@ -8575,7 +8575,7 @@ __metadata: "@metamask/messenger": "npm:^1.2.0" "@metamask/polling-controller": "npm:^16.0.6" "@metamask/profile-sync-controller": "npm:^28.1.1" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -8622,7 +8622,7 @@ __metadata: languageName: node linkType: hard -"@metamask/transaction-controller@npm:^66.0.0, @metamask/transaction-controller@workspace:packages/transaction-controller": +"@metamask/transaction-controller@npm:^66.0.1, @metamask/transaction-controller@workspace:packages/transaction-controller": version: 0.0.0-use.local resolution: "@metamask/transaction-controller@workspace:packages/transaction-controller" dependencies: @@ -8634,13 +8634,13 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@ethersproject/wallet": "npm:^5.7.0" - "@metamask/accounts-controller": "npm:^38.1.2" + "@metamask/accounts-controller": "npm:^39.0.0" "@metamask/approval-controller": "npm:^9.0.1" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" "@metamask/connectivity-controller": "npm:^0.2.0" "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/core-backend": "npm:^6.3.1" + "@metamask/core-backend": "npm:^6.3.2" "@metamask/eth-block-tracker": "npm:^15.0.0" "@metamask/eth-json-rpc-provider": "npm:^6.0.1" "@metamask/ethjs-provider-http": "npm:^0.3.0" @@ -8686,12 +8686,12 @@ __metadata: "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/assets-controller": "npm:^8.3.1" - "@metamask/assets-controllers": "npm:^108.4.0" + "@metamask/assets-controller": "npm:^8.3.2" + "@metamask/assets-controllers": "npm:^108.5.0" "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/base-controller": "npm:^9.1.0" - "@metamask/bridge-controller": "npm:^73.2.0" - "@metamask/bridge-status-controller": "npm:^72.0.1" + "@metamask/bridge-controller": "npm:^73.2.1" + "@metamask/bridge-status-controller": "npm:^72.0.2" "@metamask/controller-utils": "npm:^12.1.0" "@metamask/gas-fee-controller": "npm:^26.2.2" "@metamask/keyring-controller": "npm:^26.0.0" @@ -8700,7 +8700,7 @@ __metadata: "@metamask/network-controller": "npm:^32.0.0" "@metamask/ramps-controller": "npm:^14.1.1" "@metamask/remote-feature-flag-controller": "npm:^4.2.2" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" @@ -8735,7 +8735,7 @@ __metadata: "@metamask/polling-controller": "npm:^16.0.6" "@metamask/rpc-errors": "npm:^7.0.2" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/transaction-controller": "npm:^66.0.0" + "@metamask/transaction-controller": "npm:^66.0.1" "@metamask/utils": "npm:^11.9.0" "@ts-bridge/cli": "npm:^0.6.4" "@types/jest": "npm:^29.5.14" From 3b1d708c19d9391cd2a0edcd79a6931a2fc7945d Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 10:23:23 +0200 Subject: [PATCH 26/45] chore: update changelogs --- packages/account-tree-controller/CHANGELOG.md | 5 +++++ packages/assets-controller/CHANGELOG.md | 8 ++++++++ packages/assets-controllers/CHANGELOG.md | 8 ++++++++ packages/bridge-controller/CHANGELOG.md | 7 +++++-- packages/bridge-status-controller/CHANGELOG.md | 6 ++++++ packages/core-backend/CHANGELOG.md | 4 ++++ packages/earn-controller/CHANGELOG.md | 2 +- packages/eip-5792-middleware/CHANGELOG.md | 2 +- packages/gator-permissions-controller/CHANGELOG.md | 4 ++++ packages/money-account-controller/CHANGELOG.md | 4 ++++ packages/multichain-account-service/CHANGELOG.md | 5 +++++ packages/multichain-api-middleware/CHANGELOG.md | 2 +- packages/multichain-network-controller/CHANGELOG.md | 2 +- packages/multichain-transactions-controller/CHANGELOG.md | 6 +----- packages/network-enablement-controller/CHANGELOG.md | 3 ++- packages/phishing-controller/CHANGELOG.md | 2 +- packages/profile-metrics-controller/CHANGELOG.md | 5 +++++ packages/shield-controller/CHANGELOG.md | 4 ++-- packages/signature-controller/CHANGELOG.md | 4 ++++ packages/snap-account-service/CHANGELOG.md | 1 + packages/subscription-controller/CHANGELOG.md | 2 +- packages/transaction-controller/CHANGELOG.md | 4 ++-- packages/transaction-pay-controller/CHANGELOG.md | 8 +++++--- packages/user-operation-controller/CHANGELOG.md | 4 ++++ 24 files changed, 81 insertions(+), 21 deletions(-) diff --git a/packages/account-tree-controller/CHANGELOG.md b/packages/account-tree-controller/CHANGELOG.md index 20763cb035..6c07a2ff6e 100644 --- a/packages/account-tree-controller/CHANGELOG.md +++ b/packages/account-tree-controller/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [7.5.1] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/multichain-account-service` from `^10.0.1` to `^10.0.2` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [7.5.0] ### Added diff --git a/packages/assets-controller/CHANGELOG.md b/packages/assets-controller/CHANGELOG.md index a80f2bd73b..7571d045b9 100644 --- a/packages/assets-controller/CHANGELOG.md +++ b/packages/assets-controller/CHANGELOG.md @@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [8.3.2] +### Changed + +- Bump `@metamask/account-tree-controller` from `^7.5.0` to `^7.5.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/assets-controllers` from `^108.4.0` to `^108.5.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/core-backend` from `^6.3.1` to `^6.3.2` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [8.3.1] ### Fixed diff --git a/packages/assets-controllers/CHANGELOG.md b/packages/assets-controllers/CHANGELOG.md index 6c06d0619b..bbba0ca337 100644 --- a/packages/assets-controllers/CHANGELOG.md +++ b/packages/assets-controllers/CHANGELOG.md @@ -15,6 +15,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - When `isDeprecated()` returns `true`, every fetching entry point (`initialize()`, `start()`, `restart()`, `_executePoll()`, and `fetchTokenList()`) resets `tokensChainsCache` to `{}`, cancels any pending debounced persist (so a stale entry can't write old data after the in-memory reset), and overwrites every persisted `tokensChainsCache:*` entry in `StorageService` with `{ data: {}, timestamp: 0 }`. No HTTP calls are issued to the token API. - The function is re-evaluated on each entry point so it can be toggled at runtime without reconstructing the controller — including from inside any deprecated `setInterval` already running from a prior `start()`. +### Changed + +- Bump `@metamask/account-tree-controller` from `^7.5.0` to `^7.5.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/core-backend` from `^6.3.1` to `^6.3.2` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/multichain-account-service` from `^10.0.1` to `^10.0.2` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [108.4.0] ### Added diff --git a/packages/bridge-controller/CHANGELOG.md b/packages/bridge-controller/CHANGELOG.md index f2adcc6b2e..6bf793fa2b 100644 --- a/packages/bridge-controller/CHANGELOG.md +++ b/packages/bridge-controller/CHANGELOG.md @@ -11,9 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/assets-controllers` from `^108.2.0` to `^108.4.0` ([#8941](https://github.com/MetaMask/core/pull/8941), [#8981](https://github.com/MetaMask/core/pull/8981)) -- Bump `@metamask/assets-controller` from `^8.1.0` to `^8.3.1` ([#8943](https://github.com/MetaMask/core/pull/8943), [#8981](https://github.com/MetaMask/core/pull/8981), [#8985](https://github.com/MetaMask/core/pull/8985)) +- Bump `@metamask/assets-controllers` from `^108.2.0` to `^108.5.0` ([#8941](https://github.com/MetaMask/core/pull/8941), [#8981](https://github.com/MetaMask/core/pull/8981), [#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/assets-controller` from `^8.1.0` to `^8.3.2` ([#8943](https://github.com/MetaMask/core/pull/8943), [#8981](https://github.com/MetaMask/core/pull/8981), [#8985](https://github.com/MetaMask/core/pull/8985), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/remote-feature-flag-controller` from `^4.2.1` to `^4.2.2` ([#8986](https://github.com/MetaMask/core/pull/8986)) +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/multichain-network-controller` from `^3.1.2` to `^3.1.3` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) ## [73.2.0] diff --git a/packages/bridge-status-controller/CHANGELOG.md b/packages/bridge-status-controller/CHANGELOG.md index f636e57719..c9702e5796 100644 --- a/packages/bridge-status-controller/CHANGELOG.md +++ b/packages/bridge-status-controller/CHANGELOG.md @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [72.0.2] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/bridge-controller` from `^73.2.0` to `^73.2.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [72.0.1] ### Fixed diff --git a/packages/core-backend/CHANGELOG.md b/packages/core-backend/CHANGELOG.md index dee87ee923..773cdd187c 100644 --- a/packages/core-backend/CHANGELOG.md +++ b/packages/core-backend/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [6.3.2] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [6.3.1] ### Changed diff --git a/packages/earn-controller/CHANGELOG.md b/packages/earn-controller/CHANGELOG.md index 2ec5c3ddb4..0da4212c6f 100644 --- a/packages/earn-controller/CHANGELOG.md +++ b/packages/earn-controller/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/account-tree-controller` from `^7.4.0` to `^7.5.0` ([#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/account-tree-controller` from `^7.4.0` to `^7.5.1` ([#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [12.2.0] diff --git a/packages/eip-5792-middleware/CHANGELOG.md b/packages/eip-5792-middleware/CHANGELOG.md index efe85d6134..857ca7c032 100644 --- a/packages/eip-5792-middleware/CHANGELOG.md +++ b/packages/eip-5792-middleware/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.0` ([#8848](https://github.com/MetaMask/core/pull/8848)) +- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.1` ([#8848](https://github.com/MetaMask/core/pull/8848), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [3.0.4] diff --git a/packages/gator-permissions-controller/CHANGELOG.md b/packages/gator-permissions-controller/CHANGELOG.md index 87002bfa5e..9c046319ff 100644 --- a/packages/gator-permissions-controller/CHANGELOG.md +++ b/packages/gator-permissions-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [4.2.0] ### Added diff --git a/packages/money-account-controller/CHANGELOG.md b/packages/money-account-controller/CHANGELOG.md index bb30aa91e0..0b2dcd34bb 100644 --- a/packages/money-account-controller/CHANGELOG.md +++ b/packages/money-account-controller/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.2] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [0.3.1] ### Changed diff --git a/packages/multichain-account-service/CHANGELOG.md b/packages/multichain-account-service/CHANGELOG.md index ce4a425a78..6f02a18671 100644 --- a/packages/multichain-account-service/CHANGELOG.md +++ b/packages/multichain-account-service/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [10.0.2] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/snap-account-service` from `^0.2.1` to `^0.3.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [10.0.1] ### Changed diff --git a/packages/multichain-api-middleware/CHANGELOG.md b/packages/multichain-api-middleware/CHANGELOG.md index 7cc61b6218..b5904a2275 100644 --- a/packages/multichain-api-middleware/CHANGELOG.md +++ b/packages/multichain-api-middleware/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/accounts-controller` from `^38.1.1` to `^39.0.0` ([#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [3.1.2] diff --git a/packages/multichain-network-controller/CHANGELOG.md b/packages/multichain-network-controller/CHANGELOG.md index cb1b99fafe..04ecc3d982 100644 --- a/packages/multichain-network-controller/CHANGELOG.md +++ b/packages/multichain-network-controller/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/accounts-controller` from `^38.1.1` to `^39.0.0` ([#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [3.1.2] diff --git a/packages/multichain-transactions-controller/CHANGELOG.md b/packages/multichain-transactions-controller/CHANGELOG.md index e5a37e24c7..92a8a2400b 100644 --- a/packages/multichain-transactions-controller/CHANGELOG.md +++ b/packages/multichain-transactions-controller/CHANGELOG.md @@ -9,13 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [7.1.1] -### Uncategorized - -- Release `964.0.0` ([#8722](https://github.com/MetaMask/core/pull/8722)) - ### Changed -- Bump `@metamask/accounts-controller` from `^38.0.0` to `^38.1.2` ([#8755](https://github.com/MetaMask/core/pull/8755), [#8774](https://github.com/MetaMask/core/pull/8774), [#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/accounts-controller` from `^38.0.0` to `^39.0.0` ([#8755](https://github.com/MetaMask/core/pull/8755), [#8774](https://github.com/MetaMask/core/pull/8774), [#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/polling-controller` from `^16.0.4` to `^16.0.6` ([#8755](https://github.com/MetaMask/core/pull/8755), [#8834](https://github.com/MetaMask/core/pull/8834)) ## [7.1.0] diff --git a/packages/network-enablement-controller/CHANGELOG.md b/packages/network-enablement-controller/CHANGELOG.md index 1b91614f13..fa5d4df3ec 100644 --- a/packages/network-enablement-controller/CHANGELOG.md +++ b/packages/network-enablement-controller/CHANGELOG.md @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.0` ([#8848](https://github.com/MetaMask/core/pull/8848)) +- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.1` ([#8848](https://github.com/MetaMask/core/pull/8848), [#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/multichain-network-controller` from `^3.1.2` to `^3.1.3` ([#8999](https://github.com/MetaMask/core/pull/8999)) ## [5.2.0] diff --git a/packages/phishing-controller/CHANGELOG.md b/packages/phishing-controller/CHANGELOG.md index faa23e48f3..ea27bbcb3c 100644 --- a/packages/phishing-controller/CHANGELOG.md +++ b/packages/phishing-controller/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.0` ([#8848](https://github.com/MetaMask/core/pull/8848)) +- Bump `@metamask/transaction-controller` from `^65.4.0` to `^66.0.1` ([#8848](https://github.com/MetaMask/core/pull/8848), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [17.2.0] diff --git a/packages/profile-metrics-controller/CHANGELOG.md b/packages/profile-metrics-controller/CHANGELOG.md index cce9e0620e..ff603339e3 100644 --- a/packages/profile-metrics-controller/CHANGELOG.md +++ b/packages/profile-metrics-controller/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [3.1.6] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [3.1.5] ### Changed diff --git a/packages/shield-controller/CHANGELOG.md b/packages/shield-controller/CHANGELOG.md index 9c12f10371..8f06069d0d 100644 --- a/packages/shield-controller/CHANGELOG.md +++ b/packages/shield-controller/CHANGELOG.md @@ -9,9 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/signature-controller` from `^39.2.1` to `^39.2.3` ([#8774](https://github.com/MetaMask/core/pull/8774), [#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/signature-controller` from `^39.2.1` to `^39.2.4` ([#8774](https://github.com/MetaMask/core/pull/8774), [#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/controller-utils` from `^12.0.0` to `^12.1.0` ([#8774](https://github.com/MetaMask/core/pull/8774)) -- Bump `@metamask/transaction-controller` from `^65.3.0` to `^66.0.0` ([#8796](https://github.com/MetaMask/core/pull/8796), [#8848](https://github.com/MetaMask/core/pull/8848)) +- Bump `@metamask/transaction-controller` from `^65.3.0` to `^66.0.1` ([#8796](https://github.com/MetaMask/core/pull/8796), [#8848](https://github.com/MetaMask/core/pull/8848), [#8999](https://github.com/MetaMask/core/pull/8999)) ## [5.1.2] diff --git a/packages/signature-controller/CHANGELOG.md b/packages/signature-controller/CHANGELOG.md index 98806502c4..10e8e23ab9 100644 --- a/packages/signature-controller/CHANGELOG.md +++ b/packages/signature-controller/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [39.2.4] +### Changed + +- Bump `@metamask/accounts-controller` from `^38.1.2` to `^39.0.0` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [39.2.3] ### Changed diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index bc55961c65..4d2f358916 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Faster `:getLegacySnapKeyring` ([#8865](https://github.com/MetaMask/core/pull/8865)) - We now check if the keyring exists with `:withKeyringUnsafe` and returns it right away. - If the keyring does not exist yet, we do create it with `:withController` (next calls will then be faster thanks to `:withKeyringUnsafe` pre-check). +- Bump `@metamask/account-tree-controller` from `^7.5.0` to `^7.5.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) ### Fixed diff --git a/packages/subscription-controller/CHANGELOG.md b/packages/subscription-controller/CHANGELOG.md index 11e1c16431..e6c8a530b2 100644 --- a/packages/subscription-controller/CHANGELOG.md +++ b/packages/subscription-controller/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/controller-utils` from `^12.0.0` to `^12.1.0` ([#8774](https://github.com/MetaMask/core/pull/8774)) - Bump `@metamask/profile-sync-controller` from `^28.0.2` to `^28.1.1` ([#8783](https://github.com/MetaMask/core/pull/8783), [#8912](https://github.com/MetaMask/core/pull/8912)) -- Bump `@metamask/transaction-controller` from `^65.3.0` to `^66.0.0` ([#8796](https://github.com/MetaMask/core/pull/8796), [#8848](https://github.com/MetaMask/core/pull/8848)) +- Bump `@metamask/transaction-controller` from `^65.3.0` to `^66.0.1` ([#8796](https://github.com/MetaMask/core/pull/8796), [#8848](https://github.com/MetaMask/core/pull/8848), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/polling-controller` from `^16.0.5` to `^16.0.6` ([#8834](https://github.com/MetaMask/core/pull/8834)) ## [6.1.3] diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index d66fd132f5..fd3aeac4a5 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -11,8 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/accounts-controller` from `^38.1.1` to `^38.1.2` ([#8912](https://github.com/MetaMask/core/pull/8912)) -- Bump `@metamask/core-backend` from `^6.3.0` to `^6.3.1` ([#8912](https://github.com/MetaMask/core/pull/8912)) +- Bump `@metamask/accounts-controller` from `^38.1.1` to `^39.0.0` ([#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/core-backend` from `^6.3.0` to `^6.3.2` ([#8912](https://github.com/MetaMask/core/pull/8912), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/remote-feature-flag-controller` from `^4.2.1` to `^4.2.2` ([#8986](https://github.com/MetaMask/core/pull/8986)) ### Fixed diff --git a/packages/transaction-pay-controller/CHANGELOG.md b/packages/transaction-pay-controller/CHANGELOG.md index ea400a52ba..10ef887e4b 100644 --- a/packages/transaction-pay-controller/CHANGELOG.md +++ b/packages/transaction-pay-controller/CHANGELOG.md @@ -14,11 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bump `@metamask/assets-controllers` from `^108.3.0` to `^108.4.0` ([#8981](https://github.com/MetaMask/core/pull/8981)) -- Bump `@metamask/assets-controller` from `^8.0.2` to `^8.3.1` ([#8981](https://github.com/MetaMask/core/pull/8981), [#8985](https://github.com/MetaMask/core/pull/8985)) +- Bump `@metamask/assets-controllers` from `^108.3.0` to `^108.5.0` ([#8981](https://github.com/MetaMask/core/pull/8981), [#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/assets-controller` from `^8.0.2` to `^8.3.2` ([#8981](https://github.com/MetaMask/core/pull/8981), [#8985](https://github.com/MetaMask/core/pull/8985), [#8999](https://github.com/MetaMask/core/pull/8999)) - Bump `@metamask/remote-feature-flag-controller` from `^4.2.1` to `^4.2.2` ([#8986](https://github.com/MetaMask/core/pull/8986)) - Bump `@metamask/ramps-controller` from `^14.1.0` to `^14.1.1` ([#8989](https://github.com/MetaMask/core/pull/8989)) -- Bump `@metamask/bridge-status-controller` from `^72.0.0` to `^72.0.1` ([#8990](https://github.com/MetaMask/core/pull/8990)) +- Bump `@metamask/bridge-status-controller` from `^72.0.0` to `^72.0.2` ([#8990](https://github.com/MetaMask/core/pull/8990), [#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/bridge-controller` from `^73.2.0` to `^73.2.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) ## [23.1.0] diff --git a/packages/user-operation-controller/CHANGELOG.md b/packages/user-operation-controller/CHANGELOG.md index 50d4e3e201..c9849cc4e3 100644 --- a/packages/user-operation-controller/CHANGELOG.md +++ b/packages/user-operation-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Bump `@metamask/transaction-controller` from `^66.0.0` to `^66.0.1` ([#8999](https://github.com/MetaMask/core/pull/8999)) + ## [41.2.3] ### Changed From 2114b8ec5848f0bd2ae22fb43e04187af9722982 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:36:53 +0200 Subject: [PATCH 27/45] fix: fix tests + remove dead code --- .../src/SnapAccountService.test.ts | 129 ++++++++++++++---- .../src/SnapAccountService.ts | 34 ----- 2 files changed, 100 insertions(+), 63 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 680c41789c..108c9f8a88 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -2,6 +2,11 @@ import type { AccountGroupId } from '@metamask/account-api'; import { SNAP_KEYRING_TYPE } from '@metamask/eth-snap-keyring'; import type { SnapMessage } from '@metamask/eth-snap-keyring'; import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2'; +import type { + AccountAssetListUpdatedEventPayload, + AccountBalancesUpdatedEventPayload, + AccountTransactionsUpdatedEventPayload, +} from '@metamask/keyring-api'; import { KeyringEvent } from '@metamask/keyring-api'; import { KeyringType } from '@metamask/keyring-api/v2'; import { @@ -354,26 +359,22 @@ function mockWithKeyringV2Unsafe( } /** - * Constructs the service under test with sensible defaults. Calls - * `service.init()` before returning unless `init: false` is passed. + * Constructs the service under test with sensible defaults. * * @param args - The arguments to this function. * @param args.snapIsReady - Initial value of `SnapController.isReady`. * @param args.runnableSnaps - Snaps returned by `SnapController:getRunnableSnaps`. * @param args.config - Optional service config. - * @param args.init - Whether to call `service.init()` before returning (default: `true`). * @returns The new service, root messenger, service messenger, and mocks. */ async function setup({ snapIsReady = true, runnableSnaps = [], config, - init = true, }: { snapIsReady?: boolean; runnableSnaps?: TruncatedSnap[]; config?: SnapAccountServiceOptions['config']; - init?: boolean; } = {}): Promise<{ service: SnapAccountService; rootMessenger: RootMessenger; @@ -437,10 +438,6 @@ async function setup({ const service = new SnapAccountService({ messenger, config }); - if (init) { - await service.init(); - } - return { service, rootMessenger, messenger, mocks }; } @@ -448,16 +445,8 @@ const MOCK_SNAP_ID = 'npm:@metamask/mock-snap' as SnapId; const MOCK_OTHER_SNAP_ID = 'npm:@metamask/other-snap' as SnapId; describe('SnapAccountService', () => { - describe('init', () => { - it('resolves without throwing', async () => { - const { service } = await setup({ init: false }); - - expect(await service.init()).toBeUndefined(); - }); - }); - describe('getSnaps', () => { - it('exposes tracked Snaps seeded by init', async () => { + it('exposes tracked Snaps seeded during construction', async () => { const { service } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); @@ -604,17 +593,6 @@ describe('SnapAccountService', () => { ); }); - it('throws before init even for runnable Snaps', async () => { - const { service } = await setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID)], - init: false, - }); - - await expect(service.ensureReady(MOCK_SNAP_ID)).rejects.toThrow( - `Unknown snap: "${MOCK_SNAP_ID}"`, - ); - }); - it('resolves when platform is already ready', async () => { const { service } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], @@ -809,6 +787,48 @@ describe('SnapAccountService', () => { expect(result).toStrictEqual([]); }); + it('returns an empty array for GetSelectedAccounts when the v2 keyring does not exist yet', async () => { + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( + MOCK_GROUP_ID, + ); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + // No keyring configured for the Snap → withKeyringV2Unsafe throws KeyringNotFound. + mockWithKeyringV2Unsafe(mocks, {}); + + const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { + method: SnapManageAccountsMethod.GetSelectedAccounts, + params: {}, + } as unknown as SnapMessage); + + expect(result).toStrictEqual([]); + }); + + it('propagates non-KeyringNotFound errors from GetSelectedAccounts', async () => { + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( + MOCK_GROUP_ID, + ); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + const error = new Error('unexpected failure'); + mocks.KeyringController.withKeyringV2Unsafe.mockRejectedValue(error); + + await expect( + service.handleKeyringSnapMessage(MOCK_SNAP_ID, { + method: SnapManageAccountsMethod.GetSelectedAccounts, + params: {}, + } as unknown as SnapMessage), + ).rejects.toThrow(error); + }); + it('throws a dedicated error when no v2 Snap keyring exists for the given Snap', async () => { const { service, mocks } = await setup(); mockWithKeyringV2Unsafe(mocks, {}); @@ -877,6 +897,57 @@ describe('SnapAccountService', () => { expect(handleKeyringSnapMessage).toHaveBeenCalledWith(MOCK_MESSAGE); expect(result).toBe('pong'); }); + + const MOCK_ACCOUNT_ID = '00000000-0000-4000-8000-000000000001'; + + it.each([ + [ + KeyringEvent.AccountBalancesUpdated, + 'SnapAccountService:accountBalancesUpdated' as const, + { + balances: { + [MOCK_ACCOUNT_ID]: { + 'eip155:1/slip44:60': { amount: '1', unit: 'ETH' }, + }, + }, + } satisfies AccountBalancesUpdatedEventPayload, + ], + [ + KeyringEvent.AccountAssetListUpdated, + 'SnapAccountService:accountAssetListUpdated' as const, + { + assets: { + [MOCK_ACCOUNT_ID]: { added: ['eip155:1/slip44:60'], removed: [] }, + }, + } satisfies AccountAssetListUpdatedEventPayload, + ], + [ + KeyringEvent.AccountTransactionsUpdated, + 'SnapAccountService:accountTransactionsUpdated' as const, + { + transactions: { [MOCK_ACCOUNT_ID]: [] }, + } satisfies AccountTransactionsUpdatedEventPayload, + ], + ] as const)( + 'publishes %s as a service event without touching the keyring', + async (method, event, payload) => { + const { service, rootMessenger, mocks } = await setup(); + const listener = jest.fn(); + rootMessenger.subscribe(event, listener); + + expect(service).toBeDefined(); + + const result = await service.handleKeyringSnapMessage(MOCK_SNAP_ID, { + method, + params: payload, + } as unknown as SnapMessage); + + expect(result).toBeNull(); + expect(listener).toHaveBeenCalledWith(payload); + expect(mocks.KeyringController.withKeyringV2Unsafe).not.toHaveBeenCalled(); + expect(mocks.KeyringController.withController).not.toHaveBeenCalled(); + }, + ); }); describe('on AccountTreeController:selectedAccountGroupChange', () => { diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 24acdc5241..583e0a3959 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -33,7 +33,6 @@ import { isKeyringNotFoundError, KeyringTypes, } from '@metamask/keyring-controller'; -import { KeyringControllerWithKeyringUnsafeAction } from '@metamask/keyring-controller'; import { SnapManageAccountsMethod } from '@metamask/keyring-snap-sdk'; import type { AccountId, BaseKeyring } from '@metamask/keyring-utils'; import type { Messenger } from '@metamask/messenger'; @@ -550,39 +549,6 @@ export class SnapAccountService { ); } - /** - * Gets the legacy (v1) Snap keyring but do not auto-create it if it doesn't exist. - * - * @returns The existing Snap keyring instance, or undefined if it doesn't exist. - */ - async #getLegacySnapKeyringIfAvailable(): Promise< - LegacySnapKeyring | undefined - > { - type Result = { - snapKeyring: LegacySnapKeyring; - }; - - try { - const result = await this.#messenger.call( - 'KeyringController:withKeyringUnsafe', - { filter: isLegacySnapKeyring }, - async ({ keyring }): Promise => { - // The legacy Snap keyring is not compatible with `EthKeyring`, so we need to cast here. - return { snapKeyring: keyring } as unknown as Result; - }, - ); - - return (result as Result).snapKeyring; - } catch (error) { - if (isKeyringNotFoundError(error)) { - log('Legacy Snap keyring not available yet.'); - return undefined; - } - - throw error; - } - } - /** * Handle a message from a Snap. * From f82f0bd9f187a47d382b213920866cd78e7fb469 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:45:02 +0200 Subject: [PATCH 28/45] chore: fix changelog --- packages/accounts-controller/CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/accounts-controller/CHANGELOG.md b/packages/accounts-controller/CHANGELOG.md index 724c165b50..1357ccfbf7 100644 --- a/packages/accounts-controller/CHANGELOG.md +++ b/packages/accounts-controller/CHANGELOG.md @@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [39.0.0] - ### Changed - Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732)) From 72d7937c4b79d2e7383544265c4d556824ea5e4e Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:45:22 +0200 Subject: [PATCH 29/45] chore: cosmetic --- packages/snap-account-service/src/SnapAccountService.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 583e0a3959..c2d5c63c4d 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -733,8 +733,7 @@ export class SnapAccountService { ); }; - // There is nothing we can do if forwarding fails. This will auto-recover on - // the next relevant event. + // There is nothing we can do if forwarding fails. This will auto-recover on the next relevant event. forwardSelectedAccounts().catch((error) => { console.error('Error forwarding selected accounts:', error); }); From 769c610cebc4706f45a8118689e8a8db9c309dad Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:46:01 +0200 Subject: [PATCH 30/45] refactor: move log inside fire-and-forget callback --- .../src/SnapAccountService.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index c2d5c63c4d..bfda59fab9 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -694,15 +694,15 @@ export class SnapAccountService { return; } - if (accounts.length) { - log( - `Forwarding selected accounts (from "${groupId}"): ${accounts.join(', ')}`, - ); - } else { - log(`Clearing selected accounts (from "${groupId}")`); - } - const forwardSelectedAccounts = async (): Promise => { + if (accounts.length) { + log( + `Forwarding selected accounts (from "${groupId}"): ${accounts.join(', ')}`, + ); + } else { + log(`Clearing selected accounts (from "${groupId}")`); + } + await Promise.all( this.#tracker.getSnaps().map(async (snapId) => { try { From da5e9dd74297da5f80485727bee73c9622e3964a Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:49:11 +0200 Subject: [PATCH 31/45] chore: dedupe --- yarn.lock | 452 +++--------------------------------------------------- 1 file changed, 25 insertions(+), 427 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3ac9cd1ee9..1407789add 100644 --- a/yarn.lock +++ b/yarn.lock @@ -253,17 +253,6 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": - version: 7.29.0 - resolution: "@babel/code-frame@npm:7.29.0" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.28.5" - js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.1.1" - checksum: 10/199e15ff89007dd30675655eec52481cb245c9fdf4f81e4dc1f866603b0217b57aff25f5ffa0a95bbc8e31eb861695330cd7869ad52cc211aa63016320ef72c5 - languageName: node - linkType: hard - "@babel/compat-data@npm:^7.28.6, @babel/compat-data@npm:^7.29.7": version: 7.29.7 resolution: "@babel/compat-data@npm:7.29.7" @@ -271,30 +260,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.9": - version: 7.29.0 - resolution: "@babel/core@npm:7.29.0" - dependencies: - "@babel/code-frame": "npm:^7.29.0" - "@babel/generator": "npm:^7.29.0" - "@babel/helper-compilation-targets": "npm:^7.28.6" - "@babel/helper-module-transforms": "npm:^7.28.6" - "@babel/helpers": "npm:^7.28.6" - "@babel/parser": "npm:^7.29.0" - "@babel/template": "npm:^7.28.6" - "@babel/traverse": "npm:^7.29.0" - "@babel/types": "npm:^7.29.0" - "@jridgewell/remapping": "npm:^2.3.5" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10/25f4e91688cdfbaf1365831f4f245b436cdaabe63d59389b75752013b8d61819ee4257101b52fc328b0546159fd7d0e74457ed7cf12c365fea54be4fb0a40229 - languageName: node - linkType: hard - -"@babel/core@npm:^7.21.3, @babel/core@npm:^7.25.9": +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.9, @babel/core@npm:^7.25.9": version: 7.29.7 resolution: "@babel/core@npm:7.29.7" dependencies: @@ -317,7 +283,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.25.9, @babel/generator@npm:^7.29.7": +"@babel/generator@npm:^7.25.9, @babel/generator@npm:^7.29.7, @babel/generator@npm:^7.7.2": version: 7.29.7 resolution: "@babel/generator@npm:7.29.7" dependencies: @@ -330,19 +296,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.29.0, @babel/generator@npm:^7.7.2": - version: 7.29.1 - resolution: "@babel/generator@npm:7.29.1" - dependencies: - "@babel/parser": "npm:^7.29.0" - "@babel/types": "npm:^7.29.0" - "@jridgewell/gen-mapping": "npm:^0.3.12" - "@jridgewell/trace-mapping": "npm:^0.3.28" - jsesc: "npm:^3.0.2" - checksum: 10/61fe4ddd6e817aa312a14963ccdbb5c9a8c57e8b97b98d19a8a99ccab2215fda1a5f52bc8dd8d2e3c064497ddeb3ab8ceb55c76fa0f58f8169c34679d2256fe0 - languageName: node - linkType: hard - "@babel/helper-annotate-as-pure@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-annotate-as-pure@npm:7.29.7" @@ -410,13 +363,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-globals@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/helper-globals@npm:7.28.0" - checksum: 10/91445f7edfde9b65dcac47f4f858f68dc1661bf73332060ab67ad7cc7b313421099a2bfc4bda30c3db3842cfa1e86fffbb0d7b2c5205a177d91b22c8d7d9cb47 - languageName: node - linkType: hard - "@babel/helper-globals@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-globals@npm:7.29.7" @@ -434,16 +380,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-module-imports@npm:7.28.6" - dependencies: - "@babel/traverse": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10/64b1380d74425566a3c288074d7ce4dea56d775d2d3325a3d4a6df1dca702916c1d268133b6f385de9ba5b822b3c6e2af5d3b11ac88e5453d5698d77264f0ec0 - languageName: node - linkType: hard - "@babel/helper-module-imports@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-module-imports@npm:7.29.7" @@ -454,19 +390,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-module-transforms@npm:7.28.6" - dependencies: - "@babel/helper-module-imports": "npm:^7.28.6" - "@babel/helper-validator-identifier": "npm:^7.28.5" - "@babel/traverse": "npm:^7.28.6" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/2e421c7db743249819ee51e83054952709dc2e197c7d5d415b4bdddc718580195704bfcdf38544b3f674efc2eccd4d29a65d38678fc827ed3934a7690984cd8b - languageName: node - linkType: hard - "@babel/helper-module-transforms@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-module-transforms@npm:7.29.7" @@ -489,14 +412,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.28.6 - resolution: "@babel/helper-plugin-utils@npm:7.28.6" - checksum: 10/21c853bbc13dbdddf03309c9a0477270124ad48989e1ad6524b83e83a77524b333f92edd2caae645c5a7ecf264ec6d04a9ebe15aeb54c7f33c037b71ec521e4a - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.29.7": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.29.7, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.29.7 resolution: "@babel/helper-plugin-utils@npm:7.29.7" checksum: 10/6d16929fe5c792bbc8e4d67e18d7c1be69d2f18992deaa3d94dc26541fec662e83cbeeaf7553c6867d068eb7aed4e0d5e3e137c1dd4d5bcfa286f8d772f1f457 @@ -539,13 +455,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-string-parser@npm:7.27.1" - checksum: 10/0ae29cc2005084abdae2966afdb86ed14d41c9c37db02c3693d5022fba9f5d59b011d039380b8e537c34daf117c549f52b452398f576e908fb9db3c7abbb3a00 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-string-parser@npm:7.29.7" @@ -553,13 +462,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.28.5": - version: 7.28.5 - resolution: "@babel/helper-validator-identifier@npm:7.28.5" - checksum: 10/8e5d9b0133702cfacc7f368bf792f0f8ac0483794877c6dca5fcb73810ee138e27527701826fb58a40a004f3a5ec0a2f3c3dd5e326d262530b119918f3132ba7 - languageName: node - linkType: hard - "@babel/helper-validator-identifier@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-validator-identifier@npm:7.29.7" @@ -585,16 +487,6 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helpers@npm:7.28.6" - dependencies: - "@babel/template": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10/213485cdfffc4deb81fc1bf2cefed61bc825049322590ef69690e223faa300a2a4d1e7d806c723bb1f1f538226b9b1b6c356ca94eb47fa7c6d9e9f251ee425e6 - languageName: node - linkType: hard - "@babel/helpers@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helpers@npm:7.29.7" @@ -616,17 +508,6 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": - version: 7.29.0 - resolution: "@babel/parser@npm:7.29.0" - dependencies: - "@babel/types": "npm:^7.29.0" - bin: - parser: ./bin/babel-parser.js - checksum: 10/b1576dca41074997a33ee740d87b330ae2e647f4b7da9e8d2abd3772b18385d303b0cee962b9b88425e0f30d58358dbb8d63792c1a2d005c823d335f6a029747 - languageName: node - linkType: hard - "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.29.7" @@ -806,7 +687,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.29.7": +"@babel/plugin-syntax-jsx@npm:^7.29.7, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.29.7 resolution: "@babel/plugin-syntax-jsx@npm:7.29.7" dependencies: @@ -817,17 +698,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.28.6 - resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.28.6" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/572e38f5c1bb4b8124300e7e3dd13e82ae84a21f90d3f0786c98cd05e63c78ca1f32d1cfe462dfbaf5e7d5102fa7cd8fd741dfe4f3afc2e01a3b2877dcc8c866 - languageName: node - linkType: hard - "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -916,7 +786,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.29.7": +"@babel/plugin-syntax-typescript@npm:^7.29.7, @babel/plugin-syntax-typescript@npm:^7.7.2": version: 7.29.7 resolution: "@babel/plugin-syntax-typescript@npm:7.29.7" dependencies: @@ -927,17 +797,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.25.4 - resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/0771b45a35fd536cd3b3a48e5eda0f53e2d4f4a0ca07377cc247efa39eaf6002ed1c478106aad2650e54aefaebcb4f34f3284c4ae9252695dbd944bf66addfb0 - languageName: node - linkType: hard - "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1767,33 +1626,13 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.25.9": +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.9": version: 7.29.7 resolution: "@babel/runtime@npm:7.29.7" checksum: 10/9883b4951787779fd382b121f22f92966d85f19434841f65fb00b2dfec232107e139683f47c6f252891826ad8ee18317b46c3a0e4819116a9885f47b46d7126a languageName: node linkType: hard -"@babel/runtime@npm:^7.23.9": - version: 7.25.4 - resolution: "@babel/runtime@npm:7.25.4" - dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10/70d2a420c24a3289ea6c4addaf3a1c4186bc3d001c92445faa3cd7601d7d2fbdb32c63b3a26b9771e20ff2f511fa76b726bf256f823cdb95bc37b8eadbd02f70 - languageName: node - linkType: hard - -"@babel/template@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/template@npm:7.28.6" - dependencies: - "@babel/code-frame": "npm:^7.28.6" - "@babel/parser": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10/0ad6e32bf1e7e31bf6b52c20d15391f541ddd645cbd488a77fe537a15b280ee91acd3a777062c52e03eedbc2e1f41548791f6a3697c02476ec5daf49faa38533 - languageName: node - linkType: hard - "@babel/template@npm:^7.29.7, @babel/template@npm:^7.3.3": version: 7.29.7 resolution: "@babel/template@npm:7.29.7" @@ -1805,22 +1644,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": - version: 7.29.0 - resolution: "@babel/traverse@npm:7.29.0" - dependencies: - "@babel/code-frame": "npm:^7.29.0" - "@babel/generator": "npm:^7.29.0" - "@babel/helper-globals": "npm:^7.28.0" - "@babel/parser": "npm:^7.29.0" - "@babel/template": "npm:^7.28.6" - "@babel/types": "npm:^7.29.0" - debug: "npm:^4.3.1" - checksum: 10/3a0d0438f1ba9fed4fbe1706ea598a865f9af655a16ca9517ab57bda526e224569ca1b980b473fb68feea5e08deafbbf2cf9febb941f92f2d2533310c3fc4abc - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.29.7": +"@babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.29.7": version: 7.29.7 resolution: "@babel/traverse@npm:7.29.7" dependencies: @@ -1835,17 +1659,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.23.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0, @babel/types@npm:^7.3.3": - version: 7.29.0 - resolution: "@babel/types@npm:7.29.0" - dependencies: - "@babel/helper-string-parser": "npm:^7.27.1" - "@babel/helper-validator-identifier": "npm:^7.28.5" - checksum: 10/bfc2b211210f3894dcd7e6a33b2d1c32c93495dc1e36b547376aa33441abe551ab4bc1640d4154ee2acd8e46d3bbc925c7224caae02fcaf0e6a771e97fccc661 - languageName: node - linkType: hard - -"@babel/types@npm:^7.21.3, @babel/types@npm:^7.29.7, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.23.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.29.7, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.29.7 resolution: "@babel/types@npm:7.29.7" dependencies: @@ -10655,7 +10469,7 @@ __metadata: languageName: node linkType: hard -"@types/debug@npm:^4.0.0": +"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.7": version: 4.1.13 resolution: "@types/debug@npm:4.1.13" dependencies: @@ -10664,15 +10478,6 @@ __metadata: languageName: node linkType: hard -"@types/debug@npm:^4.1.7": - version: 4.1.12 - resolution: "@types/debug@npm:4.1.12" - dependencies: - "@types/ms": "npm:*" - checksum: 10/47876a852de8240bfdaf7481357af2b88cb660d30c72e73789abf00c499d6bc7cd5e52f41c915d1b9cd8ec9fef5b05688d7b7aef17f7f272c2d04679508d1053 - languageName: node - linkType: hard - "@types/deep-freeze-strict@npm:^1.1.0": version: 1.1.2 resolution: "@types/deep-freeze-strict@npm:1.1.2" @@ -10725,14 +10530,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.6": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d - languageName: node - linkType: hard - -"@types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": +"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": version: 1.0.9 resolution: "@types/estree@npm:1.0.9" checksum: 10/16aabfa703b5bdac83f719b07ce92a11b2d3c9b8628eacc92889d8af46cab2d78fc45c7b5378de383d0500585cea5c2f79125eeddfe5fbc6bd6a27eb0c8ccee5 @@ -11770,7 +11568,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.0": +"acorn-walk@npm:^8.0.0, acorn-walk@npm:^8.0.2": version: 8.3.5 resolution: "acorn-walk@npm:8.3.5" dependencies: @@ -11779,15 +11577,6 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2": - version: 8.3.4 - resolution: "acorn-walk@npm:8.3.4" - dependencies: - acorn: "npm:^8.11.0" - checksum: 10/871386764e1451c637bb8ab9f76f4995d408057e9909be6fb5ad68537ae3375d85e6a6f170b98989f44ab3ff6c74ad120bc2779a3d577606e7a0cd2b4efcaf77 - languageName: node - linkType: hard - "acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0, acorn@npm:^8.8.1": version: 8.16.0 resolution: "acorn@npm:8.16.0" @@ -12656,7 +12445,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.23.0, browserslist@npm:^4.28.1, browserslist@npm:^4.28.2": +"browserslist@npm:^4.0.0, browserslist@npm:^4.23.0, browserslist@npm:^4.24.0, browserslist@npm:^4.28.1, browserslist@npm:^4.28.2": version: 4.28.2 resolution: "browserslist@npm:4.28.2" dependencies: @@ -12671,20 +12460,6 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.24.0": - version: 4.24.4 - resolution: "browserslist@npm:4.24.4" - dependencies: - caniuse-lite: "npm:^1.0.30001688" - electron-to-chromium: "npm:^1.5.73" - node-releases: "npm:^2.0.19" - update-browserslist-db: "npm:^1.1.1" - bin: - browserslist: cli.js - checksum: 10/11fda105e803d891311a21a1f962d83599319165faf471c2d70e045dff82a12128f5b50b1fcba665a2352ad66147aaa248a9d2355a80aadc3f53375eb3de2e48 - languageName: node - linkType: hard - "bs-logger@npm:^0.2.6": version: 0.2.6 resolution: "bs-logger@npm:0.2.6" @@ -12926,13 +12701,6 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001688": - version: 1.0.30001690 - resolution: "caniuse-lite@npm:1.0.30001690" - checksum: 10/9fb4659eb09a298601b9593739072c481e2f5cc524bd0530e5e0f002e66246da5e866669854dfc0d53195ee36b201dab02f7933a7cdf60ccba7adb2d4a304caf - languageName: node - linkType: hard - "ccount@npm:^2.0.0": version: 2.0.1 resolution: "ccount@npm:2.0.1" @@ -12950,20 +12718,13 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.0.1, chalk@npm:^5.2.0": +"chalk@npm:^5.0.1, chalk@npm:^5.2.0, chalk@npm:^5.3.0": version: 5.6.2 resolution: "chalk@npm:5.6.2" checksum: 10/1b2f48f6fba1370670d5610f9cd54c391d6ede28f4b7062dd38244ea5768777af72e5be6b74fb6c6d54cb84c4a2dff3f3afa9b7cb5948f7f022cfd3d087989e0 languageName: node linkType: hard -"chalk@npm:^5.3.0": - version: 5.3.0 - resolution: "chalk@npm:5.3.0" - checksum: 10/6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea - languageName: node - linkType: hard - "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -14529,13 +14290,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.73": - version: 1.5.79 - resolution: "electron-to-chromium@npm:1.5.79" - checksum: 10/c5b25ba04b4f4b46c4024b96e00e43adcd6c321b48c74c8d2660f69704901da5a6592009cbf96c36c89e3f6b53d7742e2b89514477fddbccf4e5c4caebed9d49 - languageName: node - linkType: hard - "elliptic@npm:6.6.1, elliptic@npm:^6.5.7, elliptic@npm:^6.6.1": version: 6.6.1 resolution: "elliptic@npm:6.6.1" @@ -16005,7 +15759,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": version: 1.16.0 resolution: "follow-redirects@npm:1.16.0" peerDependenciesMeta: @@ -16015,16 +15769,6 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.15.6": - version: 1.15.6 - resolution: "follow-redirects@npm:1.15.6" - peerDependenciesMeta: - debug: - optional: true - checksum: 10/70c7612c4cab18e546e36b991bbf8009a1a41cf85354afe04b113d1117569abf760269409cb3eb842d9f7b03d62826687086b081c566ea7b1e6613cf29030bf7 - languageName: node - linkType: hard - "foreach@npm:^2.0.4": version: 2.0.6 resolution: "foreach@npm:2.0.6" @@ -16099,7 +15843,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.1": +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": version: 11.3.5 resolution: "fs-extra@npm:11.3.5" dependencies: @@ -16110,17 +15854,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.2.0": - version: 11.3.0 - resolution: "fs-extra@npm:11.3.0" - dependencies: - graceful-fs: "npm:^4.2.0" - jsonfile: "npm:^6.0.1" - universalify: "npm:^2.0.0" - checksum: 10/c9fe7b23dded1efe7bbae528d685c3206477e20cc60e9aaceb3f024f9b9ff2ee1f62413c161cb88546cc564009ab516dec99e9781ba782d869bb37e4fe04a97f - languageName: node - linkType: hard - "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -17378,15 +17111,6 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.16.0": - version: 2.16.1 - resolution: "is-core-module@npm:2.16.1" - dependencies: - hasown: "npm:^2.0.2" - checksum: 10/452b2c2fb7f889cbbf7e54609ef92cf6c24637c568acc7e63d166812a0fb365ae8a504c333a29add8bdb1686704068caa7f4e4b639b650dde4f00a038b8941fb - languageName: node - linkType: hard - "is-decimal@npm:^2.0.0": version: 2.0.1 resolution: "is-decimal@npm:2.0.1" @@ -19961,7 +19685,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:3.1.5": +"minimatch@npm:3.1.5, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.5 resolution: "minimatch@npm:3.1.5" dependencies: @@ -19970,15 +19694,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 - languageName: node - linkType: hard - "minimatch@npm:^7.4.6": version: 7.4.6 resolution: "minimatch@npm:7.4.6" @@ -20200,16 +19915,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.10, nanoid@npm:^3.3.7, nanoid@npm:^3.3.8": - version: 3.3.11 - resolution: "nanoid@npm:3.3.11" - bin: - nanoid: bin/nanoid.cjs - checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48 - languageName: node - linkType: hard - -"nanoid@npm:^3.3.12": +"nanoid@npm:^3.3.10, nanoid@npm:^3.3.12, nanoid@npm:^3.3.8": version: 3.3.12 resolution: "nanoid@npm:3.3.12" bin: @@ -20349,13 +20055,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.19": - version: 2.0.19 - resolution: "node-releases@npm:2.0.19" - checksum: 10/c2b33b4f0c40445aee56141f13ca692fa6805db88510e5bbb3baadb2da13e1293b738e638e15e4a8eb668bb9e97debb08e7a35409b477b5cc18f171d35a83045 - languageName: node - linkType: hard - "node-releases@npm:^2.0.36": version: 2.0.46 resolution: "node-releases@npm:2.0.46" @@ -20611,7 +20310,7 @@ __metadata: languageName: node linkType: hard -"open@npm:^10.0.3": +"open@npm:^10.0.3, open@npm:^10.1.0": version: 10.2.0 resolution: "open@npm:10.2.0" dependencies: @@ -20623,18 +20322,6 @@ __metadata: languageName: node linkType: hard -"open@npm:^10.1.0": - version: 10.1.0 - resolution: "open@npm:10.1.0" - dependencies: - default-browser: "npm:^5.2.1" - define-lazy-prop: "npm:^3.0.0" - is-inside-container: "npm:^1.0.0" - is-wsl: "npm:^3.1.0" - checksum: 10/a9c4105243a1b3c5312bf2aeb678f78d31f00618b5100088ee01eed2769963ea1f2dd464ac8d93cef51bba2d911e1a9c0c34a753ec7b91d6b22795903ea6647a - languageName: node - linkType: hard - "open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -21123,7 +20810,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -22029,7 +21716,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.21, postcss@npm:^8.4.24, postcss@npm:^8.4.33, postcss@npm:^8.5.4": +"postcss@npm:^8.4.21, postcss@npm:^8.4.24, postcss@npm:^8.4.33, postcss@npm:^8.4.40, postcss@npm:^8.5.4": version: 8.5.15 resolution: "postcss@npm:8.5.15" dependencies: @@ -22040,17 +21727,6 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.40": - version: 8.4.41 - resolution: "postcss@npm:8.4.41" - dependencies: - nanoid: "npm:^3.3.7" - picocolors: "npm:^1.0.1" - source-map-js: "npm:^1.2.0" - checksum: 10/6e6176c2407eff60493ca60a706c6b7def20a722c3adda94ea1ece38345eb99964191336fd62b62652279cec6938e79e0b1e1d477142c8d3516e7a725a74ee37 - languageName: node - linkType: hard - "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -22736,13 +22412,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10/5db3161abb311eef8c45bcf6565f4f378f785900ed3945acf740a9888c792f75b98ecb77f0775f3bf95502ff423529d23e94f41d80c8256e8fa05ed4b07cf471 - languageName: node - linkType: hard - "regexpu-core@npm:^6.3.1": version: 6.4.0 resolution: "regexpu-core@npm:6.4.0" @@ -23048,20 +22717,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.20.0, resolve@npm:^1.22.3, resolve@npm:^1.22.4": - version: 1.22.10 - resolution: "resolve@npm:1.22.10" - dependencies: - is-core-module: "npm:^2.16.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/0a398b44da5c05e6e421d70108822c327675febb880eebe905587628de401854c61d5df02866ff34fc4cb1173a51c9f0e84a94702738df3611a62e2acdc68181 - languageName: node - linkType: hard - -"resolve@npm:^1.22.11": +"resolve@npm:^1.10.0, resolve@npm:^1.20.0, resolve@npm:^1.22.11, resolve@npm:^1.22.3, resolve@npm:^1.22.4": version: 1.22.12 resolution: "resolve@npm:1.22.12" dependencies: @@ -23088,20 +22744,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": - version: 1.22.10 - resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" - dependencies: - is-core-module: "npm:^2.16.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/d4d878bfe3702d215ea23e75e0e9caf99468e3db76f5ca100d27ebdc527366fee3877e54bce7d47cc72ca8952fc2782a070d238bfa79a550eeb0082384c3b81a - languageName: node - linkType: hard - -"resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": +"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": version: 1.22.12 resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=c3c19d" dependencies: @@ -23398,16 +23041,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.3": - version: 7.7.4 - resolution: "semver@npm:7.7.4" - bin: - semver: bin/semver.js - checksum: 10/26bdc6d58b29528f4142d29afb8526bc335f4fc04c4a10f2b98b217f277a031c66736bf82d3d3bb354a2f6a3ae50f18fd62b053c4ac3f294a3d10a61f5075b75 - languageName: node - linkType: hard - -"semver@npm:^7.3.7": +"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.3": version: 7.8.1 resolution: "semver@npm:7.8.1" bin: @@ -23814,20 +23448,13 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1": +"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 languageName: node linkType: hard -"source-map-js@npm:^1.2.0": - version: 1.2.0 - resolution: "source-map-js@npm:1.2.0" - checksum: 10/74f331cfd2d121c50790c8dd6d3c9de6be21926de80583b23b37029b0f37aefc3e019fa91f9a10a5e120c08135297e1ecf312d561459c45908cb1e0e365f49e5 - languageName: node - linkType: hard - "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -25025,20 +24652,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.1": - version: 1.1.2 - resolution: "update-browserslist-db@npm:1.1.2" - dependencies: - escalade: "npm:^3.2.0" - picocolors: "npm:^1.1.1" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10/e7bf8221dfb21eba4a770cd803df94625bb04f65a706aa94c567de9600fe4eb6133fda016ec471dad43b9e7959c1bffb6580b5e20a87808d2e8a13e3892699a9 - languageName: node - linkType: hard - "update-browserslist-db@npm:^1.2.3": version: 1.2.3 resolution: "update-browserslist-db@npm:1.2.3" @@ -25830,22 +25443,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.11.0, ws@npm:^8.18.3": - version: 8.19.0 - resolution: "ws@npm:8.19.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10/26e4901e93abaf73af9f26a93707c95b4845e91a7a347ec8c569e6e9be7f9df066f6c2b817b2d685544e208207898a750b78461e6e8d810c11a370771450c31b - languageName: node - linkType: hard - -"ws@npm:^8.18.0": +"ws@npm:^8.11.0, ws@npm:^8.18.0, ws@npm:^8.18.3": version: 8.21.0 resolution: "ws@npm:8.21.0" peerDependencies: From d1c675ae3c53ef532bb8478c4ac871328d482440 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 12:55:05 +0200 Subject: [PATCH 32/45] chore: lint --- packages/snap-account-service/src/SnapAccountService.test.ts | 4 +++- packages/snap-account-service/src/SnapAccountService.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 108c9f8a88..05e9fc09f3 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -944,7 +944,9 @@ describe('SnapAccountService', () => { expect(result).toBeNull(); expect(listener).toHaveBeenCalledWith(payload); - expect(mocks.KeyringController.withKeyringV2Unsafe).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); expect(mocks.KeyringController.withController).not.toHaveBeenCalled(); }, ); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index bfda59fab9..f06e4f635b 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -9,7 +9,6 @@ import { isSnapKeyring, } from '@metamask/eth-snap-keyring/v2'; import { KeyringEvent } from '@metamask/keyring-api'; -import { KeyringType } from '@metamask/keyring-api/v2'; import type { AccountAssetListUpdatedEventPayload, AccountBalancesUpdatedEventPayload, @@ -21,6 +20,7 @@ import { AccountTransactionsUpdatedEventStruct, KeyringEvent, } from '@metamask/keyring-api'; +import { KeyringType } from '@metamask/keyring-api/v2'; import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, From b6d787f42afc98352a6406f9e3d84732168f785d Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 13:01:04 +0200 Subject: [PATCH 33/45] chore: fix changelog --- packages/snap-account-service/CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 824b039673..3b34f0509e 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.3.0] - ### Added - Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) From 9aa7357a343f00c67772b4f35decf92aa191d7e6 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 4 Jun 2026 14:36:03 +0200 Subject: [PATCH 34/45] chore: lint --- packages/snap-account-service/src/SnapAccountService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index f06e4f635b..42f0b75473 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -8,7 +8,6 @@ import { SnapKeyringState, isSnapKeyring, } from '@metamask/eth-snap-keyring/v2'; -import { KeyringEvent } from '@metamask/keyring-api'; import type { AccountAssetListUpdatedEventPayload, AccountBalancesUpdatedEventPayload, From 40eba45f92f91d42fa4560df647ce6d856ebf48b Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 5 Jun 2026 14:56:33 +0200 Subject: [PATCH 35/45] refactor: run migration on :unlock --- packages/snap-account-service/CHANGELOG.md | 14 ++- .../SnapAccountService-method-action-types.ts | 14 ++- .../src/SnapAccountService.test.ts | 114 +++++++++++++++--- .../src/SnapAccountService.ts | 50 ++++++-- packages/snap-account-service/src/index.ts | 2 +- 5 files changed, 154 insertions(+), 40 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 3b34f0509e..6bc20688b8 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -9,16 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add `migrate` ([#8732](https://github.com/MetaMask/core/pull/8732)) - - The migration is guaranteed to be run when using `ensureReady`. - - If the migration is not successful, it will get retried everytime we need to interact with any Snap keyring (v2) instances. - - It is conccurent-free and can safely be called by multiple execution flows. - - Once the migration has ran, the legacy Snap keyring will be emptied, thus, consumers are expected to use the new per-Snap keyring (v2) instances instead. +- Add `ensureMigrated` ([#8732](https://github.com/MetaMask/core/pull/8732)) + - Migrates the legacy global Snap keyring (v1) to per-Snap keyrings (v2). + - The migration is triggered automatically at `KeyringController:unlock` time. + - If the migration is not successful, it will get retried on the next call. + - It is concurrent-free and can safely be called by multiple execution flows. + - Once the migration has run, the legacy Snap keyring will be removed. - Selected-account forwarding now targets v2 Snap keyrings. - The service messenger now requires the `KeyringController:withKeyringV2Unsafe`. ### Changed +- **BREAKING:** `SnapAccountService:migrate` messenger action renamed to `SnapAccountService:ensureMigrated` ([#8732](https://github.com/MetaMask/core/pull/8732)) +- **BREAKING:** `SnapAccountService.ensureReady` now throws if called before the wallet is unlocked ([#8732](https://github.com/MetaMask/core/pull/8732)) + - Previously, `ensureReady` triggered migration itself. Now migration is expected to be triggered at `KeyringController:unlock` time via `ensureMigrated`. - `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available ([#8732](https://github.com/MetaMask/core/pull/8732)) - Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732)) diff --git a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts index 1c08a74df2..8434c285eb 100644 --- a/packages/snap-account-service/src/SnapAccountService-method-action-types.ts +++ b/packages/snap-account-service/src/SnapAccountService-method-action-types.ts @@ -20,8 +20,8 @@ export type SnapAccountServiceGetSnapsAction = { /** * Ensures everything is ready to use Snap accounts for the given Snap. * 1. Validates that `snapId` is a tracked account-management Snap. - * 2. Runs the legacy -> v2 Snap keyring migration (cached — no-op if - * already done). + * 2. Asserts that the legacy -> v2 migration has been triggered (expected to + * happen at `KeyringController:unlock` time). * 3. Atomically creates the v2 keyring for this Snap if it doesn't exist * yet. * 4. Waits for the Snap platform to be fully started. @@ -30,6 +30,7 @@ export type SnapAccountServiceGetSnapsAction = { * * @param snapId - ID of the Snap to ensure readiness for. * @throws If `snapId` is not a tracked account-management Snap. + * @throws If the migration has not been triggered yet (wallet not unlocked). */ export type SnapAccountServiceEnsureReadyAction = { type: `SnapAccountService:ensureReady`; @@ -38,14 +39,15 @@ export type SnapAccountServiceEnsureReadyAction = { /** * Migrate the legacy Snap keyring to the new (per-snap) Snap keyring v2. + * Expected to be triggered at `KeyringController:unlock` time. * Safe to call concurrently — the migration runs only once; all callers * await the same promise. * * @returns A promise that resolves when the migration is complete. */ -export type SnapAccountServiceMigrateAction = { - type: `SnapAccountService:migrate`; - handler: SnapAccountService['migrate']; +export type SnapAccountServiceEnsureMigratedAction = { + type: `SnapAccountService:ensureMigrated`; + handler: SnapAccountService['ensureMigrated']; }; /** @@ -66,5 +68,5 @@ export type SnapAccountServiceHandleKeyringSnapMessageAction = { export type SnapAccountServiceMethodActions = | SnapAccountServiceGetSnapsAction | SnapAccountServiceEnsureReadyAction - | SnapAccountServiceMigrateAction + | SnapAccountServiceEnsureMigratedAction | SnapAccountServiceHandleKeyringSnapMessageAction; diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 05e9fc09f3..93c628f507 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -455,12 +455,12 @@ describe('SnapAccountService', () => { }); }); - describe('migrate', () => { + describe('ensureMigrated', () => { it('runs the migration only once when called concurrently', async () => { const { service, mocks } = await setup(); mocks.KeyringController.withController.mockResolvedValue(undefined); - await Promise.all([service.migrate(), service.migrate()]); + await Promise.all([service.ensureMigrated(), service.ensureMigrated()]); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); }); @@ -474,7 +474,7 @@ describe('SnapAccountService', () => { operation({ keyrings: [], addNewKeyring, removeKeyring }), ); - await service.migrate(); + await service.ensureMigrated(); expect(addNewKeyring).not.toHaveBeenCalled(); expect(removeKeyring).not.toHaveBeenCalled(); @@ -522,7 +522,7 @@ describe('SnapAccountService', () => { }), ); - await service.migrate(); + await service.ensureMigrated(); expect(addNewKeyring).toHaveBeenCalledTimes(2); expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { @@ -545,8 +545,8 @@ describe('SnapAccountService', () => { const { service, mocks } = await setup(); mocks.KeyringController.withController.mockResolvedValue(undefined); - await service.migrate(); - await service.migrate(); + await service.ensureMigrated(); + await service.ensureMigrated(); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); }); @@ -558,8 +558,8 @@ describe('SnapAccountService', () => { .mockRejectedValueOnce(error) .mockResolvedValueOnce(undefined); - await expect(service.migrate()).rejects.toThrow(error); - expect(await service.migrate()).toBeUndefined(); + await expect(service.ensureMigrated()).rejects.toThrow(error); + expect(await service.ensureMigrated()).toBeUndefined(); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); }); @@ -572,14 +572,14 @@ describe('SnapAccountService', () => { .mockResolvedValueOnce(undefined); const [first, second] = await Promise.allSettled([ - service.migrate(), - service.migrate(), + service.ensureMigrated(), + service.ensureMigrated(), ]); expect(first).toStrictEqual({ status: 'rejected', reason: error }); expect(second).toStrictEqual({ status: 'rejected', reason: error }); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); - expect(await service.migrate()).toBeUndefined(); + expect(await service.ensureMigrated()).toBeUndefined(); expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); }); }); @@ -597,21 +597,69 @@ describe('SnapAccountService', () => { const { service } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); + await service.ensureMigrated(); expect(await service.ensureReady(MOCK_SNAP_ID)).toBeUndefined(); }); - it('runs the migration before checking platform readiness', async () => { + it('throws when migration has not been triggered', async () => { + const { service } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + + await expect(service.ensureReady(MOCK_SNAP_ID)).rejects.toThrow( + 'Snap account service migration has not been triggered', + ); + }); + + it('awaits in-flight migration triggered at unlock time', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + + let resolveMigration!: () => void; + mocks.KeyringController.withController + .mockReturnValueOnce( + new Promise((resolve) => { + resolveMigration = resolve; + }), + ) + .mockResolvedValue(undefined); + + publishUnlock(rootMessenger); + // Migration is in-flight (#migratePromise is set synchronously) + + let resolved = false; + const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { + resolved = true; + return undefined; + }); + + await flushMicrotasks(); + expect(resolved).toBe(false); + + resolveMigration(); + await flushMicrotasks(); + + await ensurePromise; + expect(resolved).toBe(true); + }); + + it('does not invoke migration itself', async () => { const { service, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); mocks.KeyringController.withController.mockResolvedValue(undefined); - // `migrate` is invoked once + `#createKeyringForSnap` is invoked once - // (the cached migrate call is a no-op on subsequent calls). + await service.ensureMigrated(); + // Reset the call count so we can assert ensureReady doesn't add to it + mocks.KeyringController.withController.mockClear(); + mocks.KeyringController.withController.mockResolvedValue(undefined); + await service.ensureReady(MOCK_SNAP_ID); - expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(2); + // Only `#ensureKeyringIsReady` should call withController, not migration + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); }); it('creates a v2 keyring for the Snap when one does not exist yet', async () => { @@ -625,6 +673,7 @@ describe('SnapAccountService', () => { operation({ keyrings: [], addNewKeyring, removeKeyring }), ); + await service.ensureMigrated(); await service.ensureReady(MOCK_SNAP_ID); expect(addNewKeyring).toHaveBeenCalledWith(KeyringType.Snap, { @@ -639,7 +688,7 @@ describe('SnapAccountService', () => { const { service, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); - // First call: migration (no legacy snap keyring → early return). + // First call: ensureMigrated (no legacy snap keyring → early return). // Second call: ensureReady keyring check (snap keyring already exists). mocks.KeyringController.withController .mockImplementationOnce(async (operation) => @@ -660,6 +709,7 @@ describe('SnapAccountService', () => { }), ); + await service.ensureMigrated(); await service.ensureReady(MOCK_SNAP_ID); expect(addNewKeyring).not.toHaveBeenCalled(); @@ -670,6 +720,7 @@ describe('SnapAccountService', () => { snapIsReady: false, runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); + await service.ensureMigrated(); let resolved = false; const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { @@ -698,6 +749,7 @@ describe('SnapAccountService', () => { runnableSnaps: [buildSnap(MOCK_SNAP_ID)], config: { snapPlatformWatcher: { ensureOnboardingComplete } }, }); + await service.ensureMigrated(); let resolved = false; const ensurePromise = service.ensureReady(MOCK_SNAP_ID).then(() => { @@ -1164,6 +1216,36 @@ describe('SnapAccountService', () => { '00000000-0000-0000-0000-000000000002', ]; + it('triggers migration', async () => { + const { service, rootMessenger, mocks } = await setup(); + mocks.KeyringController.withController.mockResolvedValue(undefined); + + publishUnlock(rootMessenger); + await flushMicrotasks(); + + expect(mocks.KeyringController.withController).toHaveBeenCalledTimes(1); + expect(service).toBeDefined(); + }); + + it('logs an error when migration fails', async () => { + const { service, rootMessenger, mocks } = await setup(); + const error = new Error('migration boom'); + mocks.KeyringController.withController.mockRejectedValueOnce(error); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementation(() => undefined); + + publishUnlock(rootMessenger); + await flushMicrotasks(); + + expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Migration failed after unlock:', + error, + ); + expect(service).toBeDefined(); + consoleErrorSpy.mockRestore(); + }); + it('forwards the currently selected account group to every tracked v2 Snap keyring', async () => { const { service, rootMessenger, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 42f0b75473..bc4f9084a1 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -54,9 +54,9 @@ import { assertStruct } from '@metamask/utils'; import { projectLogger as log } from './logger'; import type { SnapAccountServiceEnsureReadyAction, + SnapAccountServiceEnsureMigratedAction, SnapAccountServiceGetSnapsAction, SnapAccountServiceHandleKeyringSnapMessageAction, - SnapAccountServiceMigrateAction, } from './SnapAccountService-method-action-types'; import { SnapPlatformWatcher } from './SnapPlatformWatcher'; import type { SnapPlatformWatcherConfig } from './SnapPlatformWatcher'; @@ -82,20 +82,20 @@ export const serviceName = 'SnapAccountService'; * the messenger. */ const MESSENGER_EXPOSED_METHODS = [ + 'ensureMigrated', 'ensureReady', 'getSnaps', 'handleKeyringSnapMessage', - 'migrate', ] as const; /** * Actions that {@link SnapAccountService} exposes to other consumers. */ export type SnapAccountServiceActions = + | SnapAccountServiceEnsureMigratedAction | SnapAccountServiceEnsureReadyAction | SnapAccountServiceGetSnapsAction - | SnapAccountServiceHandleKeyringSnapMessageAction - | SnapAccountServiceMigrateAction; + | SnapAccountServiceHandleKeyringSnapMessageAction; /** * Actions from other messengers that {@link SnapAccountService} calls. @@ -295,10 +295,15 @@ export class SnapAccountService { } /** - * Handles the keyring controller unlock event by forwarding the currently - * selected account group's accounts to the Snap keyring. + * Handles the keyring controller unlock event by triggering the migration + * and forwarding the currently selected account group's accounts to the Snap + * keyring. */ #handleUnlock(): void { + this.ensureMigrated().catch((error) => { + console.error('Migration failed after unlock:', error); + }); + const groupId = this.#getSelectedAccountGroupId(); this.#forwardSelectedAccounts( groupId, @@ -347,8 +352,8 @@ export class SnapAccountService { /** * Ensures everything is ready to use Snap accounts for the given Snap. * 1. Validates that `snapId` is a tracked account-management Snap. - * 2. Runs the legacy -> v2 Snap keyring migration (cached — no-op if - * already done). + * 2. Asserts that the legacy -> v2 migration has been triggered (expected to + * happen at `KeyringController:unlock` time). * 3. Atomically creates the v2 keyring for this Snap if it doesn't exist * yet. * 4. Waits for the Snap platform to be fully started. @@ -357,15 +362,14 @@ export class SnapAccountService { * * @param snapId - ID of the Snap to ensure readiness for. * @throws If `snapId` is not a tracked account-management Snap. + * @throws If the migration has not been triggered yet (wallet not unlocked). */ async ensureReady(snapId: SnapId): Promise { if (!this.#tracker.canUse(snapId)) { throw new Error(`Unknown snap: "${snapId}"`); } - // Migrate from the global v1 Snap keyring to the per-Snap v2 keyring - // before doing anything else. - await this.migrate(); + await this.#ensureHasBeenMigrated(); // We still try to create the keyring for the Snap here, since we might // want to use a new Snap that never had accounts before. @@ -376,14 +380,36 @@ export class SnapAccountService { await this.#watcher.ensureCanUseSnapPlatform(); } + /** + * Asserts that the migration has been triggered and waits for it to complete + * if it is still in-flight. The migration is expected to be triggered at + * `KeyringController:unlock` time. + * + * @throws If the migration has not been triggered yet. + */ + async #ensureHasBeenMigrated(): Promise { + if (this.#migrated) { + return; + } + if (this.#migratePromise) { + await this.#migratePromise; + } else { + throw new Error( + 'Snap account service migration has not been triggered. ' + + 'The wallet must be unlocked before using Snap accounts.', + ); + } + } + /** * Migrate the legacy Snap keyring to the new (per-snap) Snap keyring v2. + * Expected to be triggered at `KeyringController:unlock` time. * Safe to call concurrently — the migration runs only once; all callers * await the same promise. * * @returns A promise that resolves when the migration is complete. */ - async migrate(): Promise { + async ensureMigrated(): Promise { if (this.#migrated) { return; } diff --git a/packages/snap-account-service/src/index.ts b/packages/snap-account-service/src/index.ts index 48f692b28e..6cda8e7a67 100644 --- a/packages/snap-account-service/src/index.ts +++ b/packages/snap-account-service/src/index.ts @@ -10,10 +10,10 @@ export type { SnapAccountServiceOptions, } from './SnapAccountService'; export type { + SnapAccountServiceEnsureMigratedAction, SnapAccountServiceEnsureReadyAction, SnapAccountServiceGetSnapsAction, SnapAccountServiceHandleKeyringSnapMessageAction, - SnapAccountServiceMigrateAction, } from './SnapAccountService-method-action-types'; export { SnapPlatformWatcher } from './SnapPlatformWatcher'; export type { SnapPlatformWatcherConfig } from './SnapPlatformWatcher'; From 6bb8189c769bcf195e187009e222dc35777da662 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 5 Jun 2026 17:43:25 +0200 Subject: [PATCH 36/45] fix: only clear promise on error (migrate) --- .../src/SnapAccountService.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index bc4f9084a1..999f0b74e8 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -414,17 +414,15 @@ export class SnapAccountService { return; } if (!this.#migratePromise) { - this.#migratePromise = this.#migrate(); - - try { - await this.#migratePromise; - - // Only mark it as migrated after the migration logic completes successfully. If - // it fails, we want future calls to retry the migration. - this.#migrated = true; - } finally { - this.#migratePromise = null; - } + this.#migratePromise = this.#migrate() + .then(() => { + this.#migrated = true; + }) + .catch((error) => { + // Clear the promise so the next call can retry. + this.#migratePromise = null; + throw error; + }); } await this.#migratePromise; } From 16db124b7333b421c2763a4f82ee3eeb89c9711c Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 12:50:44 +0200 Subject: [PATCH 37/45] chore: lint --- packages/snap-account-service/src/SnapAccountService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 999f0b74e8..5ef4d67115 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -417,6 +417,7 @@ export class SnapAccountService { this.#migratePromise = this.#migrate() .then(() => { this.#migrated = true; + return undefined; }) .catch((error) => { // Clear the promise so the next call can retry. From 2158caec3b4cea9f5b1da80e03c65b08458f67cd Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 14:35:26 +0200 Subject: [PATCH 38/45] fix: only forward selected account groups after succesful migration --- .../src/SnapAccountService.test.ts | 35 ++++++++++++++++++ .../src/SnapAccountService.ts | 37 +++++++++++-------- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 93c628f507..0e8160d3cf 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -1246,6 +1246,41 @@ describe('SnapAccountService', () => { consoleErrorSpy.mockRestore(); }); + it('does not forward the selected account group when migration fails', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); + mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( + MOCK_GROUP_ID, + ); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + const error = new Error('migration boom'); + mocks.KeyringController.withController.mockRejectedValueOnce(error); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementation(() => undefined); + + publishUnlock(rootMessenger); + await flushMicrotasks(); + + expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect( + mocks.KeyringController.withKeyringV2Unsafe, + ).not.toHaveBeenCalled(); + expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Migration failed after unlock:', + error, + ); + expect(service).toBeDefined(); + consoleErrorSpy.mockRestore(); + }); + it('forwards the currently selected account group to every tracked v2 Snap keyring', async () => { const { service, rootMessenger, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 5ef4d67115..d23a96dba7 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -288,7 +288,8 @@ export class SnapAccountService { * @param groupId - The ID of the newly selected account group. */ #handleSelectedAccountGroupChange(groupId: AccountGroupId | ''): void { - this.#forwardSelectedAccounts( + // eslint-disable-next-line no-void + void this.#forwardSelectedAccounts( groupId, this.#getAccountGroup(groupId)?.accounts, ); @@ -300,15 +301,19 @@ export class SnapAccountService { * keyring. */ #handleUnlock(): void { - this.ensureMigrated().catch((error) => { - console.error('Migration failed after unlock:', error); - }); - - const groupId = this.#getSelectedAccountGroupId(); - this.#forwardSelectedAccounts( - groupId, - this.#getAccountGroup(groupId)?.accounts, - ); + // eslint-disable-next-line no-void + void this.ensureMigrated() + .then(async () => { + // If the migration is successful, we re-forward the current groups to each new keyrings! + const groupId = this.#getSelectedAccountGroupId(); + return await this.#forwardSelectedAccounts( + groupId, + this.#getAccountGroup(groupId)?.accounts, + ); + }) + .catch((error) => { + console.error('Migration failed after unlock:', error); + }); } /** @@ -319,7 +324,8 @@ export class SnapAccountService { */ #handleAccountGroupCreatedOrUpdated(group: AccountGroupObject): void { if (group.id === this.#getSelectedAccountGroupId()) { - this.#forwardSelectedAccounts(group.id, group.accounts); + // eslint-disable-next-line no-void + void this.#forwardSelectedAccounts(group.id, group.accounts); } } @@ -331,7 +337,8 @@ export class SnapAccountService { */ #handleAccountGroupRemoved(groupId: AccountGroupId): void { if (groupId === this.#getSelectedAccountGroupId()) { - this.#forwardSelectedAccounts( + // eslint-disable-next-line no-void + void this.#forwardSelectedAccounts( groupId, [], // Clearing accounts since the group is removed ); @@ -700,10 +707,10 @@ export class SnapAccountService { * forwarded. If empty, this is a no-op. * @param accounts - The accounts to forward. If not defined, this is a no-op. */ - #forwardSelectedAccounts( + async #forwardSelectedAccounts( groupId: AccountGroupId | '', accounts: AccountId[] | undefined, - ): void { + ): Promise { if (!groupId) { log( 'No selected account group, skipping forwarding selected accounts to Snap keyring.', @@ -758,7 +765,7 @@ export class SnapAccountService { }; // There is nothing we can do if forwarding fails. This will auto-recover on the next relevant event. - forwardSelectedAccounts().catch((error) => { + await forwardSelectedAccounts().catch((error) => { console.error('Error forwarding selected accounts:', error); }); } From d84d38af853846ef0f3fd6accceae188cece4a36 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 15:22:03 +0200 Subject: [PATCH 39/45] fix: make sure migration has ran before processing AccountCreated events --- packages/snap-account-service/src/SnapAccountService.test.ts | 5 ++++- packages/snap-account-service/src/SnapAccountService.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 0e8160d3cf..6fb4996eaa 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -906,7 +906,9 @@ describe('SnapAccountService', () => { }); it('ensures the v2 keyring exists before forwarding an AccountCreated event', async () => { - const { service, mocks } = await setup(); + const { service, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); // `#ensureKeyringIsReady` uses `withController` — start with no keyring // so it must create one. const { addNewKeyring } = mockWithController(mocks, []); @@ -915,6 +917,7 @@ describe('SnapAccountService', () => { [MOCK_SNAP_ID]: { handleKeyringSnapMessage }, }); + await service.ensureMigrated(); await service.handleKeyringSnapMessage( MOCK_SNAP_ID, MOCK_ACCOUNT_CREATED_MESSAGE, diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index d23a96dba7..ec27095340 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -627,7 +627,7 @@ export class SnapAccountService { // the keyring exists (e.g for the MMI Snap). // NOTE: We only auto-create it for v1 account creation flows. if (isAccountCreatedMessage) { - await this.#ensureKeyringIsReady(snapId); + await this.ensureReady(snapId); } // This part of the flow relies on v1 flows, but v2 keyrings are compatible with those messages From e477208b4fdf104d925998536dfb8a5bb87b803e Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 17:51:52 +0200 Subject: [PATCH 40/45] fix: prevent forward accounts if migration has not ran yet --- .../src/SnapAccountService.test.ts | 46 ++++++++++++++++++- .../src/SnapAccountService.ts | 19 ++++---- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 6fb4996eaa..acd3dc29ae 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -257,6 +257,22 @@ function publishAccountGroupRemoved( rootMessenger.publish('AccountTreeController:accountGroupRemoved', groupId); } +/** + * Triggers the migration on the given service by mocking the controller call + * to resolve immediately (no legacy keyring present) and calling + * {@link SnapAccountService.ensureMigrated}. + * + * @param service - The service under test. + * @param mocks - The mocks object from {@link setup}. + */ +async function triggerMigration( + service: SnapAccountService, + mocks: Mocks, +): Promise { + mocks.KeyringController.withController.mockResolvedValue(undefined); + await service.ensureMigrated(); +} + /** * Builds a fake {@link KeyringEntry} with the given type. * @@ -1015,7 +1031,7 @@ describe('SnapAccountService', () => { ]; it('forwards owned accounts to every tracked v2 Snap keyring in parallel', async () => { - const { rootMessenger, mocks } = await setup({ + const { service, rootMessenger, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID), buildSnap(MOCK_OTHER_SNAP_ID)], }); const setSelectedAccounts1 = jest.fn().mockResolvedValue(undefined); @@ -1034,6 +1050,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + await triggerMigration(service, mocks); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1046,7 +1063,7 @@ describe('SnapAccountService', () => { }); it('forwards an empty list to a tracked Snap that owns none of the selected accounts', async () => { - const { rootMessenger, mocks } = await setup({ + const { service, rootMessenger, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], }); const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); @@ -1059,6 +1076,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + await triggerMigration(service, mocks); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); @@ -1066,6 +1084,25 @@ describe('SnapAccountService', () => { expect(setSelectedAccounts).toHaveBeenCalledWith([]); }); + it('does nothing when not yet migrated', async () => { + const { service, rootMessenger, mocks } = await setup({ + runnableSnaps: [buildSnap(MOCK_SNAP_ID)], + }); + const setSelectedAccounts = jest.fn().mockResolvedValue(undefined); + mockWithKeyringV2Unsafe(mocks, { + [MOCK_SNAP_ID]: { setSelectedAccounts }, + }); + mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( + buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), + ); + + publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); + await flushMicrotasks(); + + expect(setSelectedAccounts).not.toHaveBeenCalled(); + expect(service).toBeDefined(); + }); + it('does nothing when no Snap is tracked', async () => { const { service, rootMessenger, mocks } = await setup(); mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( @@ -1090,6 +1127,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + await triggerMigration(service, mocks); const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => undefined); @@ -1159,6 +1197,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + await triggerMigration(service, mocks); const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => undefined); @@ -1189,6 +1228,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS), ); + await triggerMigration(service, mocks); // Force the per-Snap error handler itself to throw on its first // invocation, so the rejection escapes the inner try/catch and reaches // the outer `.catch` (the top-level fallback). Subsequent calls @@ -1387,6 +1427,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); + await triggerMigration(service, mocks); publishEvent(rootMessenger, buildGroup(MOCK_GROUP_ID, MOCK_ACCOUNTS)); await flushMicrotasks(); @@ -1458,6 +1499,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getSelectedAccountGroup.mockReturnValue( MOCK_GROUP_ID, ); + await triggerMigration(service, mocks); publishAccountGroupRemoved(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index ec27095340..22fb64e76c 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -700,6 +700,7 @@ export class SnapAccountService { return null; } + // eslint-disable-next-line jsdoc/require-returns /** * Forwards the accounts of the given account group to the Snap keyring. * @@ -711,18 +712,18 @@ export class SnapAccountService { groupId: AccountGroupId | '', accounts: AccountId[] | undefined, ): Promise { + const skipping = (reason: string): void => log(`${reason}, skipping forwarding selected accounts to Snap keyring`); + + if (!this.#migrated) { + return skipping('Not migrated yet'); + } + if (!groupId) { - log( - 'No selected account group, skipping forwarding selected accounts to Snap keyring.', - ); - return; + return skipping('No selected account group'); } if (!accounts) { - log( - `Account group ("${groupId}") has no accounts, skipping forwarding selected accounts to Snap keyring.`, - ); - return; + return skipping(`Account group ("${groupId}") has no accounts`); } const forwardSelectedAccounts = async (): Promise => { @@ -765,7 +766,7 @@ export class SnapAccountService { }; // There is nothing we can do if forwarding fails. This will auto-recover on the next relevant event. - await forwardSelectedAccounts().catch((error) => { + return await forwardSelectedAccounts().catch((error) => { console.error('Error forwarding selected accounts:', error); }); } From 8022ce74e25b7863f843f8e4848227a0c9436bfc Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 17:53:15 +0200 Subject: [PATCH 41/45] refactor: remove "has migrated" logic --- .../src/SnapAccountService.test.ts | 10 ------- .../src/SnapAccountService.ts | 26 +++---------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index acd3dc29ae..632901f44e 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -618,16 +618,6 @@ describe('SnapAccountService', () => { expect(await service.ensureReady(MOCK_SNAP_ID)).toBeUndefined(); }); - it('throws when migration has not been triggered', async () => { - const { service } = await setup({ - runnableSnaps: [buildSnap(MOCK_SNAP_ID)], - }); - - await expect(service.ensureReady(MOCK_SNAP_ID)).rejects.toThrow( - 'Snap account service migration has not been triggered', - ); - }); - it('awaits in-flight migration triggered at unlock time', async () => { const { service, rootMessenger, mocks } = await setup({ runnableSnaps: [buildSnap(MOCK_SNAP_ID)], diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 22fb64e76c..5d51b86074 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -376,7 +376,8 @@ export class SnapAccountService { throw new Error(`Unknown snap: "${snapId}"`); } - await this.#ensureHasBeenMigrated(); + // The migration is required to ensure the v2 keyring exists. + await this.ensureMigrated(); // We still try to create the keyring for the Snap here, since we might // want to use a new Snap that never had accounts before. @@ -387,27 +388,6 @@ export class SnapAccountService { await this.#watcher.ensureCanUseSnapPlatform(); } - /** - * Asserts that the migration has been triggered and waits for it to complete - * if it is still in-flight. The migration is expected to be triggered at - * `KeyringController:unlock` time. - * - * @throws If the migration has not been triggered yet. - */ - async #ensureHasBeenMigrated(): Promise { - if (this.#migrated) { - return; - } - if (this.#migratePromise) { - await this.#migratePromise; - } else { - throw new Error( - 'Snap account service migration has not been triggered. ' + - 'The wallet must be unlocked before using Snap accounts.', - ); - } - } - /** * Migrate the legacy Snap keyring to the new (per-snap) Snap keyring v2. * Expected to be triggered at `KeyringController:unlock` time. @@ -420,6 +400,7 @@ export class SnapAccountService { if (this.#migrated) { return; } + if (!this.#migratePromise) { this.#migratePromise = this.#migrate() .then(() => { @@ -432,6 +413,7 @@ export class SnapAccountService { throw error; }); } + await this.#migratePromise; } From 273242cac3f81659315ab67df7382d9971ef4375 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 18:10:06 +0200 Subject: [PATCH 42/45] test: coverage --- packages/snap-account-service/src/SnapAccountService.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/snap-account-service/src/SnapAccountService.test.ts b/packages/snap-account-service/src/SnapAccountService.test.ts index 632901f44e..4beae87549 100644 --- a/packages/snap-account-service/src/SnapAccountService.test.ts +++ b/packages/snap-account-service/src/SnapAccountService.test.ts @@ -1137,6 +1137,7 @@ describe('SnapAccountService', () => { mockWithKeyringV2Unsafe(mocks, { [MOCK_SNAP_ID]: { setSelectedAccounts: jest.fn() }, }); + await triggerMigration(service, mocks); publishSelectedAccountGroupChange(rootMessenger, ''); await flushMicrotasks(); @@ -1160,6 +1161,7 @@ describe('SnapAccountService', () => { mocks.AccountTreeController.getAccountGroupObject.mockReturnValue( undefined, ); + await triggerMigration(service, mocks); publishSelectedAccountGroupChange(rootMessenger, MOCK_GROUP_ID); await flushMicrotasks(); From 993d9f3cb4e8963f6c1cba7849b39c85889006c2 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 18:23:57 +0200 Subject: [PATCH 43/45] chore: lint --- packages/snap-account-service/src/SnapAccountService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/snap-account-service/src/SnapAccountService.ts b/packages/snap-account-service/src/SnapAccountService.ts index 5d51b86074..d3e369ad23 100644 --- a/packages/snap-account-service/src/SnapAccountService.ts +++ b/packages/snap-account-service/src/SnapAccountService.ts @@ -694,7 +694,8 @@ export class SnapAccountService { groupId: AccountGroupId | '', accounts: AccountId[] | undefined, ): Promise { - const skipping = (reason: string): void => log(`${reason}, skipping forwarding selected accounts to Snap keyring`); + const skipping = (reason: string): void => + log(`${reason}, skipping forwarding selected accounts to Snap keyring`); if (!this.#migrated) { return skipping('Not migrated yet'); From d39378185392790d5dff5febe401534c5826b6f6 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Mon, 8 Jun 2026 21:38:26 +0200 Subject: [PATCH 44/45] chore: fix changelog --- packages/snap-account-service/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index 6bc20688b8..9ac01c8ce1 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `ensureMigrated` ([#8732](https://github.com/MetaMask/core/pull/8732)) - Migrates the legacy global Snap keyring (v1) to per-Snap keyrings (v2). - - The migration is triggered automatically at `KeyringController:unlock` time. + - The migration is triggered automatically whenever a consumer request access to any Snap keyring (v2). - If the migration is not successful, it will get retried on the next call. - It is concurrent-free and can safely be called by multiple execution flows. - Once the migration has run, the legacy Snap keyring will be removed. From f188e628b6a92d4922c4e072e8e7f7778ed3f9de Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Tue, 9 Jun 2026 17:36:15 +0200 Subject: [PATCH 45/45] chore: changelog --- packages/snap-account-service/CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/snap-account-service/CHANGELOG.md b/packages/snap-account-service/CHANGELOG.md index c64e2c4f97..fc4f5a4877 100644 --- a/packages/snap-account-service/CHANGELOG.md +++ b/packages/snap-account-service/CHANGELOG.md @@ -20,9 +20,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **BREAKING:** `SnapAccountService:migrate` messenger action renamed to `SnapAccountService:ensureMigrated` ([#8732](https://github.com/MetaMask/core/pull/8732)) -- **BREAKING:** `SnapAccountService.ensureReady` now throws if called before the wallet is unlocked ([#8732](https://github.com/MetaMask/core/pull/8732)) - - Previously, `ensureReady` triggered migration itself. Now migration is expected to be triggered at `KeyringController:unlock` time via `ensureMigrated`. - `SnapAccountService.ensureReady` now automatically creates the Snap keyring (v2) for a given Snap ID if it was not available ([#8732](https://github.com/MetaMask/core/pull/8732)) - Bump `@metamask/eth-snap-keyring` from `^22.0.1` to `^22.1.0` ([#8732](https://github.com/MetaMask/core/pull/8732))