Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
91dfc0f
chore: use preview builds
ccharly Jul 6, 2026
4e6c4d3
feat(snap-account-service): expose snap-only keyring methods through …
ccharly Jul 6, 2026
3bbbc62
chore: changelog
ccharly Jul 6, 2026
3914b6f
chore: dedupe
ccharly Jul 6, 2026
03ba9a8
fix: use handleKeyringSnapMessage for v1 only
ccharly Jul 6, 2026
b81379b
chore: lint
ccharly Jul 6, 2026
15dd06f
refactor: add :setSelectedAccounts action
ccharly Jul 6, 2026
0221bce
chore: yarn.lock
ccharly Jul 6, 2026
a382725
fix: re-generate actions
ccharly Jul 6, 2026
43cf917
fix: use v1.createAccount
ccharly Jul 6, 2026
a7db836
chore: lint + cosmetic
ccharly Jul 6, 2026
c6e3490
chore: lint
ccharly Jul 6, 2026
272ce44
chore: changelog
ccharly Jul 6, 2026
bae54f6
build: remove use of preview builds
ccharly Jul 7, 2026
a5cabb7
chore: changelogs
ccharly Jul 7, 2026
ef8e6eb
fix: remove logs + add comment for setSelectedAccounts
ccharly Jul 7, 2026
21c1c32
Merge branch 'main' into cc/feat/snap-account-service-snap-rpc-methods
ccharly Jul 7, 2026
3065189
chore: yarn.lock
ccharly Jul 7, 2026
5dc0317
fix: fix missing keyring-api bump
ccharly Jul 7, 2026
803c8d6
fix: only use unsafe v1 createAccount for v1 keyrings, wrap other ope…
ccharly Jul 7, 2026
3a27acc
chore: changelogs
ccharly Jul 7, 2026
3c825b5
refactor: use import type
ccharly Jul 7, 2026
94b00b0
chore: fix changelog
ccharly Jul 7, 2026
6172557
Merge branch 'main' into cc/feat/snap-account-service-snap-rpc-methods
ccharly Jul 7, 2026
79242ae
chore: changelog
ccharly Jul 7, 2026
160b6bd
chore: fix assets-controller changelog
ccharly Jul 7, 2026
768ad9a
Merge branch 'main' into cc/feat/snap-account-service-snap-rpc-methods
ccharly Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/account-tree-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- The `Multichain Account Syncing - Full` trace is now only emitted when a backup-and-sync run actually mutates local or remote state (rolled-back local changes do not count) ([#9343](https://github.com/MetaMask/core/pull/9343))
- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.3.0` ([#9249](https://github.com/MetaMask/core/pull/9249))
- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.5.0` ([#9249](https://github.com/MetaMask/core/pull/9249), [#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/multichain-account-service` from `^11.0.0` to `^11.1.0` ([#9264](https://github.com/MetaMask/core/pull/9264))
- Bump `@metamask/accounts-controller` from `^39.0.3` to `^39.0.4` ([#9349](https://github.com/MetaMask/core/pull/9349))
- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
Expand Down
2 changes: 1 addition & 1 deletion packages/account-tree-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"dependencies": {
"@metamask/accounts-controller": "^39.0.4",
"@metamask/base-controller": "^9.1.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/messenger": "^2.0.0",
"@metamask/multichain-account-service": "^11.1.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/accounts-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/eth-snap-keyring` from `^22.3.0` to `^23.0.0` ([#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

## [39.0.4]

Expand Down
4 changes: 2 additions & 2 deletions packages/accounts-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
"dependencies": {
"@ethereumjs/util": "^9.1.0",
"@metamask/base-controller": "^9.1.0",
"@metamask/eth-snap-keyring": "^22.3.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/eth-snap-keyring": "^23.0.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/keyring-internal-api": "^11.0.1",
"@metamask/keyring-sdk": "^2.2.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/assets-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/keyring-snap-client` from `^9.0.2` to `^9.2.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions packages/assets-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@
"@metamask/client-controller": "^1.0.1",
"@metamask/controller-utils": "^12.3.0",
"@metamask/core-backend": "^6.5.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/keyring-internal-api": "^11.0.1",
"@metamask/keyring-snap-client": "^9.0.2",
"@metamask/keyring-snap-client": "^9.2.0",
"@metamask/messenger": "^2.0.0",
"@metamask/network-controller": "^34.0.0",
"@metamask/network-enablement-controller": "^5.4.1",
Expand Down
1 change: 1 addition & 0 deletions packages/assets-controllers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

## [109.3.0]

Expand Down
4 changes: 2 additions & 2 deletions packages/assets-controllers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@metamask/controller-utils": "^12.3.0",
"@metamask/core-backend": "^6.5.0",
"@metamask/eth-query": "^4.0.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/messenger": "^2.0.0",
"@metamask/metamask-eth-abis": "^3.1.1",
Expand Down Expand Up @@ -106,7 +106,7 @@
"@metamask/auto-changelog": "^6.1.0",
"@metamask/ethjs-provider-http": "^0.3.0",
"@metamask/keyring-internal-api": "^11.0.1",
"@metamask/keyring-snap-client": "^9.0.2",
"@metamask/keyring-snap-client": "^9.2.0",
"@metamask/providers": "^22.1.0",
"@ts-bridge/cli": "^0.6.4",
"@types/jest": "^29.5.14",
Expand Down
1 change: 1 addition & 0 deletions packages/bridge-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

## [77.3.2]

Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"@metamask/base-controller": "^9.1.0",
"@metamask/controller-utils": "^12.3.0",
"@metamask/gas-fee-controller": "^26.2.4",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/messenger": "^2.0.0",
"@metamask/metamask-eth-abis": "^3.1.1",
"@metamask/multichain-network-controller": "^3.2.1",
Expand Down
4 changes: 4 additions & 0 deletions packages/client-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `mapLocalTransaction` for mapping local transaction groups to activity items
- Shared activity types (`ActivityItem`, `ActivityKind`, `Status`, etc.)

### Changed

- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

[Unreleased]: https://github.com/MetaMask/core/
2 changes: 1 addition & 1 deletion packages/client-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@metamask/contract-metadata": "^2.4.0",
"@metamask/controller-utils": "^12.3.0",
"@metamask/core-backend": "^6.5.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/transaction-controller": "^68.2.2",
"@metamask/utils": "^11.11.0"
},
Expand Down
1 change: 1 addition & 0 deletions packages/earn-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

## [12.2.2]

Expand Down
2 changes: 1 addition & 1 deletion packages/earn-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"@metamask/account-tree-controller": "^7.5.3",
"@metamask/base-controller": "^9.1.0",
"@metamask/controller-utils": "^12.3.0",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/messenger": "^2.0.0",
"@metamask/network-controller": "^34.0.0",
"@metamask/stake-sdk": "^3.2.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/keyring-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.3.0` ([#9249](https://github.com/MetaMask/core/pull/9249))
- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.5.0` ([#9249](https://github.com/MetaMask/core/pull/9249), [#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))

## [27.1.0]
Expand Down
2 changes: 1 addition & 1 deletion packages/keyring-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"@metamask/eth-hd-keyring": "^14.1.1",
"@metamask/eth-sig-util": "^8.2.0",
"@metamask/eth-simple-keyring": "^12.0.2",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-internal-api": "^11.0.1",
"@metamask/messenger": "^2.0.0",
"@metamask/utils": "^11.11.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/money-account-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Bump `@metamask/utils` from `^11.9.0` to `^11.11.0` ([#9074](https://github.com/MetaMask/core/pull/9074))
- Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0` ([#9129](https://github.com/MetaMask/core/pull/9129))
- Bump `@metamask/accounts-controller` from `^39.0.1` to `^39.0.4` ([#9218](https://github.com/MetaMask/core/pull/9218), [#9231](https://github.com/MetaMask/core/pull/9231), [#9349](https://github.com/MetaMask/core/pull/9349))
- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.3.0` ([#9249](https://github.com/MetaMask/core/pull/9249))
- Bump `@metamask/keyring-api` from `^23.1.0` to `^23.5.0` ([#9249](https://github.com/MetaMask/core/pull/9249), [#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))

## [0.3.3]
Expand Down
2 changes: 1 addition & 1 deletion packages/money-account-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@metamask/accounts-controller": "^39.0.4",
"@metamask/base-controller": "^9.1.0",
"@metamask/eth-money-keyring": "^2.0.4",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/messenger": "^2.0.0",
"async-mutex": "^0.5.0"
Expand Down
5 changes: 5 additions & 0 deletions packages/multichain-account-service/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **BREAKING:** `RestrictedSnapKeyring.createAccount` has been replaced by `RestrictedSnapKeyring.v1`, which is `undefined` for v2-only Snaps ([#9390](https://github.com/MetaMask/core/pull/9390))
- Any subclass implementing `SnapAccountProvider.createAccountV1` must now check `keyring.v1` guard followed by `keyring.v1.createAccount(options)`.
- Wallet alignment now only creates the missing `(provider, group index)` pairs instead of re-creating the whole range for every provider, avoiding redundant `createAccounts` calls (and their traces) ([#9269](https://github.com/MetaMask/core/pull/9269))
- Bump `@metamask/accounts-controller` from `^39.0.3` to `^39.0.4` ([#9349](https://github.com/MetaMask/core/pull/9349))
- Bump `@metamask/messenger` from `^1.2.0` to `^2.0.0` ([#9392](https://github.com/MetaMask/core/pull/9392))
- Bump `@metamask/eth-snap-keyring` from `^22.3.0` to `^23.0.0` ([#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/keyring-api` from `^23.3.0` to `^23.5.0` ([#9390](https://github.com/MetaMask/core/pull/9390))
- Bump `@metamask/keyring-snap-client` from `^9.0.2` to `^9.2.0` ([#9390](https://github.com/MetaMask/core/pull/9390))

## [11.1.0]

Expand Down
6 changes: 3 additions & 3 deletions packages/multichain-account-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@
"@ethereumjs/util": "^9.1.0",
"@metamask/accounts-controller": "^39.0.4",
"@metamask/base-controller": "^9.1.0",
"@metamask/eth-snap-keyring": "^22.3.0",
"@metamask/eth-snap-keyring": "^23.0.0",
"@metamask/key-tree": "^10.1.1",
"@metamask/keyring-api": "^23.3.0",
"@metamask/keyring-api": "^23.5.0",
"@metamask/keyring-controller": "^27.1.0",
"@metamask/keyring-internal-api": "^11.0.1",
"@metamask/keyring-snap-client": "^9.0.2",
"@metamask/keyring-snap-client": "^9.2.0",
"@metamask/keyring-utils": "^3.3.1",
"@metamask/messenger": "^2.0.0",
"@metamask/snap-account-service": "^1.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import {
BTC_ACCOUNT_PROVIDER_NAME,
BtcAccountProvider,
} from './BtcAccountProvider';
import type { SnapAccountProviderConfig } from './SnapAccountProvider';
import type {
RestrictedSnapKeyring,
SnapAccountProviderConfig,
} from './SnapAccountProvider';

function asConfig(
partial: DeepPartial<SnapAccountProviderConfig>,
Expand Down Expand Up @@ -132,6 +135,12 @@ class MockBtcKeyring {
return account;
});
});

deleteAccount = jest.fn().mockResolvedValue(undefined);

get v1(): Required<RestrictedSnapKeyring['v1']> {
return { createAccount: this.createAccount };
}
}

class MockBtcAccountProvider extends BtcAccountProvider {
Expand Down Expand Up @@ -457,6 +466,19 @@ describe('BtcAccountProvider', () => {
// Provider should now expose one account (newly created)
expect(provider.getAccounts()).toHaveLength(1);
});

it('throws when the Snap is v2-only and does not support v1 account creation', async () => {
const { provider, keyring } = setup({ accounts: [] });
jest.spyOn(keyring, 'v1', 'get').mockReturnValue(undefined);

await expect(
provider.createAccounts({
type: AccountCreationType.Bip44DeriveIndex,
entropySource: MOCK_HD_KEYRING_1.metadata.id,
groupIndex: 0,
}),
).rejects.toThrow('is v2-only and does not support v1 account creation');
});
});

describe('v2 - batched', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ export class BtcAccountProvider extends SnapAccountProvider {
groupIndex,
}: { entropySource: EntropySourceId; groupIndex: number },
): Promise<KeyringAccount> {
return keyring.createAccount({
if (!keyring.v1) {
throw new Error(
`Snap "${BtcAccountProvider.BTC_SNAP_ID}" is v2-only and does not support v1 account creation`,
);
}
return keyring.v1.createAccount({
entropySource,
index: groupIndex,
addressType: BtcAccountType.P2wpkh,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,14 @@ class MockSnapAccountProvider extends SnapAccountProvider {
keyring: RestrictedSnapKeyring,
options: { entropySource: EntropySourceId; groupIndex: number },
): Promise<KeyringAccount> {
if (!keyring.v1) {
throw new Error(
'Snap is v2-only and does not support v1 account creation',
);
}
// Forward to the mocked keyring (no real purposes apart from implementing
// this abstract method)..
return await keyring.createAccount(options);
// this abstract method).
return await keyring.v1.createAccount(options);
}

async createAccounts(
Expand Down Expand Up @@ -244,7 +249,9 @@ const setup = ({
const keyring = {
type: keyringOverrides.type ?? 'snap',
snapId: keyringOverrides.snapId ?? TEST_SNAP_ID,
createAccount: jest.fn(),
v1: {
createAccount: jest.fn(),
},
createAccounts: jest.fn(),
deleteAccount: jest.fn().mockResolvedValue(undefined),
lookupByAddress: jest
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +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 { SnapKeyringV1 } from '@metamask/eth-snap-keyring';
import type { SnapKeyring as SnapKeyringV2 } from '@metamask/eth-snap-keyring/v2';
import { isSnapKeyring } from '@metamask/eth-snap-keyring/v2';
import {
Expand Down Expand Up @@ -33,7 +34,15 @@ import { BaseBip44AccountProvider } from './BaseBip44AccountProvider';
import { withTimeout } from './utils';

export type RestrictedSnapKeyring = {
createAccount: SnapKeyringV2['createAccount'];
/**
* V1 interface, present only when the Snap does not declare v2 capabilities.
* `undefined` for v2-only Snaps.
*
* Use this to make v1 calls explicit:
* if (!keyring.v1) { throw new Error('Snap is v2-only'); }
* keyring.v1.createAccount(options);
*/
v1?: { createAccount: SnapKeyringV1['createAccount'] };
createAccounts: SnapKeyringV2['createAccounts'];
deleteAccount: SnapKeyringV2['deleteAccount'];
};
Expand Down Expand Up @@ -154,25 +163,24 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider {
// 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: SnapKeyringV2['createAccount'];
createAccounts: SnapKeyringV2['createAccounts'];
}>(async ({ keyring }) => ({
createAccount: keyring.createAccount.bind(keyring),
createAccounts: keyring.createAccounts.bind(keyring),
}));
const createAccount = await this.#withSnapKeyring(async ({ keyring }) => {
if (keyring.v1) {
return keyring.v1.createAccount.bind(keyring.v1);
}

// This method does not exist in v2.
return undefined;
});

return {
createAccount: async (options) =>
// We use the "unguarded" account creation here (see explanation above).
await createAccount(options, {
displayAccountNameSuggestion: false,
displayConfirmation: false,
setSelectedAccount: false,
}),
createAccounts: async (options) => await createAccounts(options),
// V1 interface is only present for v1 Snaps, otherwise it's `undefined`.
v1: createAccount ? { createAccount } : undefined,
// Every v2 operations must be done through the `#withSnapKeyring` transaction:
createAccounts: async (options) =>
await this.#withSnapKeyring(
async ({ keyring }) => await keyring.createAccounts(options),
),
deleteAccount: async (id: string) =>
// Though, when removing account, we can use the normal flow.
await this.#withSnapKeyring(async ({ keyring }) => {
await keyring.deleteAccount(id);
}),
Expand Down
Loading