Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 8 additions & 3 deletions packages/snap-account-service/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ 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`, which waits for the Snap platform to be ready and for a Snap keyring to appear in `KeyringController` state before allowing Snap account operations ([#8715](https://github.com/MetaMask/core/pull/8715))
- 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).
- `SnapAccountService.ensureReady` now throws `Unknown snap: "<id>"` when called with a Snap ID that isn't tracked as an account-management Snap.
- 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))
- The service messenger now requires the `KeyringController:getState` action and `KeyringController:stateChange` event.
- Add `getSnaps` action to `SnapAccountService`, returning the IDs of installed, enabled, non-blocked Snaps that declare the `endowment:keyring` permission ([#8725](https://github.com/MetaMask/core/pull/8725))
- Export `SnapAccountServiceGetSnapsAction` type.
- The service now seeds its internal set from `SnapController:getRunnableSnaps` during `init()` and keeps it in sync via `SnapController` lifecycle events (`snapInstalled`, `snapEnabled`, `snapDisabled`, `snapBlocked`, `snapUninstalled`).
- The service messenger now requires the `SnapController:getRunnableSnaps` action and the five lifecycle events listed above.

### Changed

- Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632))
- **BREAKING:** Remove the top-level `ensureOnboardingComplete` option from `SnapAccountServiceOptions` ([#8715](https://github.com/MetaMask/core/pull/8715))
- Pass the callback via `config.snapPlatformWatcher.ensureOnboardingComplete` instead.

[Unreleased]: https://github.com/MetaMask/core/
2 changes: 2 additions & 0 deletions packages/snap-account-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
},
"dependencies": {
"@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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,57 @@

import type { SnapAccountService } from './SnapAccountService';

/**
* Returns the IDs of all currently tracked account-management Snaps —
* Snaps that are installed, enabled, not blocked, and have the
* `endowment:keyring` permission.
*
* @returns The IDs of tracked account-management Snaps.
*/
export type SnapAccountServiceGetSnapsAction = {
type: `SnapAccountService:getSnaps`;
handler: SnapAccountService['getSnaps'];
};

/**
* Ensures everything is ready to use Snap accounts for the given Snap.
* 1. Waits for the Snap platform to be fully started.
* 1. Validates that `snapId` is a tracked account-management Snap.
* 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.
*
* @param _snapId - ID of the Snap to ensure readiness for.
* @param snapId - ID of the Snap to ensure readiness for.
* @throws If `snapId` is not a tracked account-management Snap.
*/
export type SnapAccountServiceEnsureReadyAction = {
type: `SnapAccountService:ensureReady`;
handler: SnapAccountService['ensureReady'];
};

/**
* Handle a message from a Snap.
*
* Only `AccountCreated` triggers lazy keyring creation, since that is the
* single entry point for the v1 event-driven flow. All other events from
* unknown Snaps throw an error.
*
* @param snapId - ID of the Snap.
* @param message - Message sent by the Snap.
* @returns The execution result.
*/
export type SnapAccountServiceHandleKeyringSnapMessageAction = {
type: `SnapAccountService:handleKeyringSnapMessage`;
handler: SnapAccountService['handleKeyringSnapMessage'];
};

/**
* Union of all SnapAccountService action types.
*/
export type SnapAccountServiceMethodActions =
SnapAccountServiceEnsureReadyAction;
| SnapAccountServiceGetSnapsAction
| SnapAccountServiceEnsureReadyAction
| SnapAccountServiceHandleKeyringSnapMessageAction;
Loading
Loading