MetaMask / MetaMask/metamask-extension
[`MetamaskController` A.3] Extract `permission-management`
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
**Sub-epic:** [#41736 — `MetamaskController` decomposition: `wallet-services` completion](https://github.com/MetaMask/metamask-extension/issues/41736)
**Files:**
- `app/scripts/lib/wallet-services/permission-management/index.ts` (new)
- `app/scripts/lib/wallet-services/permission-management/permission-management.test.ts` (new)
- `app/scripts/metamask-controller.js`
**Size:** M
## Problem
Permission management logic lives inline on `MetamaskController`: approval / permission subject wiring, network-order and network-enablement side effects, and extension-specific wrappers sit alongside unrelated wallet concerns. Extract them into `wallet-services/permission-management/` so the responsibility is named and independently testable.
Reconciliation required during extraction: audit every `messenger.call(...)` site in the extracted methods against `@metamask/permission-controller` and `@metamask/approval-controller` registered actions, fixing wrong action names and using direct controller injection for class methods that are not yet registered as messenger actions. Extension-specific wrappers surfaced during the port should move to the extension-specific layer — flag in the PR if any are discovered.
**Verification sources:** [`app/scripts/controller-init/messengers/`](https://github.com/MetaMask/metamask-extension/tree/main/app/scripts/controller-init/messengers) (permission + approval + network-order + network-enablement messenger files), `@metamask/permission-controller`, `@metamask/approval-controller`.
## Solution
1. Create `app/scripts/lib/wallet-services/permission-management/` with `index.ts` exporting a structural `PermissionManagementMessenger` type and the extracted function bodies.
2. Port the corresponding method bodies from `metamask-controller.js` into the module, performing the per-action audit described above.
3. Export `PERMISSION_MANAGEMENT_ACTIONS` and `registerActions(messenger)`.
4. Add structural unit tests against a stub messenger.
5. Delete the moved method bodies from `metamask-controller.js`.
6. Update `MetamaskController#getApi()` entries for permission management to delegate via messenger.
## Acceptance criteria
- [ ] `app/scripts/lib/wallet-services/permission-management/index.ts` exists and owns the extracted logic
- [ ] Every `messenger.call(...)` site matches a real registered action, or is replaced with direct controller injection plus an explicit upstream-registration TODO
- [ ] Full unit-test coverage against structural messenger
- [ ] `registerActions(messenger)` covers every export
- [ ] Moved method bodies are removed from `app/scripts/metamask-controller.js`
- [ ] `getApi()` entries rewritten to call `messenger.call('Module:action', ...)` directly — no forwarding stub remains in `MetamaskController`
- [ ] `yarn test` green, `tsc` green, extension dev build boots
## Dependencies
None.
Contributor guide
Research direction
Start with the permission-management methods in app/scripts/metamask-controller.js and the permission, approval, network-order, and network-enablement messenger files under app/scripts/controller-init/messengers/. Compare each messenger action with the registered actions in @metamask/permission-controller and @metamask/approval-controller, then review the existing controller tests for patterns. Done means the new module and structural tests cover every export, getApi() delegates directly, moved bodies are removed, and yarn test, tsc, and the extension build pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- authorization, backend
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100