MetaMask / MetaMask/metamask-extension
Spike: `@metamask/controller-registry` promotion readiness (background cleanup)
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
## Parent
- Epic: [#40061 — Background cleanup](https://github.com/MetaMask/metamask-extension/issues/40061)
- State Sync Redesign umbrella: [#40063](https://github.com/MetaMask/metamask-extension/issues/40063)
## Context
The background cleanup PoC ([branch](https://github.com/MetaMask/metamask-extension/compare/main...jongsun/poc/state-sync-redesign/a1/background-cleanup)) extracts `ControllerRegistry` and `PatchBuffer` as aggregation-side primitives that replace extension's `ComposableObservableStore` pair. [ADR 0021](https://github.com/MetaMask/decisions/blob/main/decisions/core/0021-extract-background-wallet-primitives.md) proposes publishing these as `@metamask/controller-registry` for cross-client consumption.
This spike assesses promotion readiness: what must change in the PoC primitives before they can ship as a published `@metamask/*` package.
## Scope
1. **Type safety audit.** The PoC uses `as never` casts on messenger subscribe/unsubscribe calls ([`ControllerRegistry.ts:126-134`](https://github.com/MetaMask/metamask-extension/blob/jongsun/poc/state-sync-redesign/a1/background-cleanup/app/scripts/lib/ControllerRegistry.ts#L126-L134)). Validate that a structural `RegistryMessenger` constraint (subscribe/unsubscribe for `${string}:stateChange`) eliminates the casts while remaining satisfiable by both extension and mobile root messengers.
2. **Config shape validation.** The PoC takes two separate config maps (`uiConfig`, `persistConfig`) with ~35 overlapping entries. Validate that a unified `RegistryConfig` with `ui`/`persist` boolean flags per entry produces identical runtime behavior with half the config surface.
3. **Cross-client compilation.** Confirm the primitives compile in a Node context with only `@metamask/base-controller` as peer dependency. No browser-API, DOM, or extension-specific imports.
4. **Mobile messenger compatibility.** Verify that mobile's `controllerMessenger` (from `Engine.ts`) structurally satisfies the `RegistryMessenger` constraint without modification.
5. **Codegen feasibility.** Assess whether [`MESSENGER_FACTORIES`](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/messenger-client-init/messengers/index.ts) (87 entries) + per-controller `metadata.persist` annotations provide sufficient information to generate the config flags, eliminating the hand-built config maps in `metamask-controller.js:1341-1453`.
6. **`ComposableController` deprecation path.** Confirm mobile's sole `ComposableController:stateChange` subscriber ([`EngineService.ts:163`](https://github.com/MetaMask/metamask-mobile/blob/main/app/core/EngineService/EngineService.ts#L163)) is replaceable by `scheduleOnStateChange`.
## Output
- Type-safety gap list (what casts remain, what constraints fix them)
- Cross-client compilation result (pass/fail with any required changes)
- Codegen feasibility verdict (viable / needs X first)
- Promotion blocker list with severity
- Recommended package boundary (`src/` structure, public API surface, peer deps)
## Size
M (investigation + type experimentation, no production code to merge)
## References
- [Background cleanup PoC](https://github.com/MetaMask/metamask-extension/compare/main...jongsun/poc/state-sync-redesign/a1/background-cleanup)
- [Design spec](https://github.com/MetaMask/decisions/blob/jongsun/extension-background-cleanup/controller_registry_design.md)
- [ADR 0021](https://github.com/MetaMask/decisions/blob/main/decisions/core/0021-extract-background-wallet-primitives.md) section B
- [PoC PR #41758](https://github.com/MetaMask/metamask-extension/pull/41758) (includes both ControllerRegistry and wallet-services in one branch)
Contributor guide
Research direction
Start with the PoC ControllerRegistry.ts lines 126-134, then inspect the config maps in metamask-controller.js lines 1341-1453 and MESSENGER_FACTORIES in app/scripts/messenger-client-init/messengers/index.ts. Compare the extension and mobile messenger entry points, including Engine.ts and EngineService.ts line 163, against ADR 0021. Done means producing the requested type-safety, compilation, codegen, blocker, and package-boundary findings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100