Skip to content

refactor!: Standardise SnapController action/event names and types#3907

Open
Mrtenz wants to merge 12 commits intocontroller-refactorsfrom
mrtenz/snap-controller-refactor
Open

refactor!: Standardise SnapController action/event names and types#3907
Mrtenz wants to merge 12 commits intocontroller-refactorsfrom
mrtenz/snap-controller-refactor

Conversation

@Mrtenz
Copy link
Member

@Mrtenz Mrtenz commented Mar 20, 2026

This renames all SnapController action and event names and types to follow the Controller...Action pattern used in most other controllers. I've also added the generate-method-actions script used in MetaMask/core to automatically generate these types.

I found numerous unrelated type errors in test files that I fixed in this pull request as well, since it was a bit difficult to determine if a type error was caused by this refactor or not, in some cases.

Breaking changes

  • All SnapController action types were renamed from DoSomething to SnapControllerDoSomethingAction.
    • GetSnap is now SnapControllerGetSnapAction.
      • Note: The method is now called getSnap instead of get.
    • HandleSnapRequest is now SnapControllerHandleRequestAction.
    • GetSnapState is now SnapControllerGetSnapStateAction.
    • HasSnap is now SnapControllerHasSnapAction.
      • Note: The method is now called hasSnap instead of has.
    • UpdateSnapState is now SnapControllerUpdateSnapStateAction.
    • ClearSnapState is now SnapControllerClearSnapStateAction.
    • UpdateRegistry is now SnapControllerUpdateRegistryAction.
    • EnableSnap is now SnapControllerEnableSnapAction.
      • Note: The method is now called enableSnap instead of enable.
    • DisableSnap is now SnapControllerDisableSnapAction.
      • Note: The method is now called disableSnap instead of disable.
    • RemoveSnap is now SnapControllerRemoveSnapAction.
      • Note: The method is now called removeSnap instead of remove.
    • GetPermittedSnaps is now SnapControllerGetPermittedSnapsAction.
      • Note: The method is now called getPermittedSnaps instead of getPermitted.
    • GetAllSnaps is now SnapControllerGetAllSnapsAction.
      • Note: The method is now called getAllSnaps instead of getAll.
    • GetRunnableSnaps is now SnapControllerGetRunnableSnapsAction.
    • StopAllSnaps is now SnapControllerStopAllSnapsAction.
    • IncrementActiveReferences is now SnapControllerIncrementActiveReferencesAction.
    • DecrementActiveReferences is now SnapControllerDecrementActiveReferencesAction.
    • InstallSnaps is now SnapControllerInstallSnapsAction.
      • Note: The method is now called installSnaps instead of install.
    • DisconnectOrigin is now SnapControllerRemoveSnapFromSubjectAction.
    • RevokeDynamicPermissions is now SnapControllerRevokeDynamicSnapPermissionsAction.
    • GetSnapFile is now SnapControllerGetSnapFileAction.
    • IsMinimumPlatformVersion is now SnapControllerIsMinimumPlatformVersionAction.
    • SetClientActive is now SnapControllerSetClientActiveAction.
  • All SnapController event types were renamed from OnSomething to SnapControllerOnSomethingEvent.
    • SnapStateChange was removed in favour of SnapControllerStateChangeEvent.
    • SnapBlocked is now SnapControllerSnapBlockedEvent.
    • SnapInstallStarted is now SnapControllerSnapInstallStartedEvent.
    • SnapInstallFailed is now SnapControllerSnapInstallFailedEvent.
    • SnapInstalled is now SnapControllerSnapInstalledEvent.
    • SnapUninstalled is now SnapControllerSnapUninstalledEvent.
    • SnapUnblocked is now `SnapControllerSnapUnblockedEvent.
    • SnapUpdated is now SnapControllerSnapUpdatedEvent.
    • SnapRolledback is now SnapControllerSnapRolledbackEvent.
    • SnapTerminated is now SnapControllerSnapTerminatedEvent.
    • SnapEnabled is now SnapControllerSnapEnabledEvent.
    • SnapDisabled is now SnapControllerSnapDisabledEvent.

Note

Medium Risk
Medium risk due to breaking renames of SnapController messenger action/event types and action string IDs (e.g., getgetSnap, getAllgetAllSnaps), which can cause widespread compile/runtime call-site breakage if any consumers aren’t updated.

Overview
BREAKING: Renames SnapController messenger action/event types to the SnapController...Action / SnapController...Event pattern and updates several action IDs/method names (notably SnapController:getSnapController:getSnap and SnapController:getAllSnapController:getAllSnaps).

Adds an auto-generated SnapController-method-action-types.ts and introduces a repo/workspace generate-method-action-types script, wiring it into root lint (with --check) and adding yargs as a dev dependency.

Updates affected controllers/tests (CronjobController, SnapInsightsController, SnapInterfaceController, MultichainRouter) to use the new SnapController action types/IDs, plus minor test util renames and removal of now-unnecessary lint-disable comments in execution services.

Written by Cursor Bugbot for commit 3b51590. This will update automatically on new commits. Configure here.

@codecov
Copy link

codecov bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.55%. Comparing base (17136ba) to head (3b51590).

Additional details and impacted files
@@                  Coverage Diff                  @@
##           controller-refactors    #3907   +/-   ##
=====================================================
  Coverage                 98.55%   98.55%           
=====================================================
  Files                       425      425           
  Lines                     12358    12360    +2     
  Branches                   1935     1935           
=====================================================
+ Hits                      12180    12182    +2     
  Misses                      178      178           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Mrtenz Mrtenz marked this pull request as ready for review March 20, 2026 13:07
@Mrtenz Mrtenz requested a review from a team as a code owner March 20, 2026 13:07
@@ -0,0 +1,773 @@
#!yarn tsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not ideal to be duplicating this file between repos

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, we can consider extracting it into a publishable package at some point.

@@ -0,0 +1,773 @@
#!yarn tsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the diff between this version and the one in core? Are we intending to sync back these changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only difference is support for nested directories. The core script assumes all controllers are in the top-level src directory, which is not the case for Snaps controllers. We can sync this with core if we decide to create a package for the script.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely don't want them to diverge.

Comment on lines +266 to 267
const allSnaps = this.#messenger.call('SnapController:getAllSnaps');
const filteredSnaps = getRunnableSnaps(allSnaps);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are making a breaking change here we could consider swapping to use SnapController: getRunnableSnaps

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do it in the follow up PR for MultichainRouter.

#getSnapsWithPermission(permissionName: string) {
const allSnaps = this.messenger.call('SnapController:getAll');
const allSnaps = this.messenger.call('SnapController:getAllSnaps');
const filteredSnaps = getRunnableSnaps(allSnaps);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as MultichainRouter

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reply 😄

@Mrtenz Mrtenz changed the base branch from main to controller-refactors March 20, 2026 13:33
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

export const MESSENGER_EXPOSED_METHODS = [
'init',
'updateRegistry',
'startSnap',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'startSnap',

TBH probably does not need to be publicly accessible

Comment on lines +233 to +234
'incrementActiveReferences',
'decrementActiveReferences',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just remove this 😄

Comment on lines +220 to +222
'getSnapExpect',
'getTruncatedSnap',
'getTruncatedSnapExpect',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if these need to be publicly accessible


messenger.delegate({
actions: [
'PermissionController:hasPermission',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this not used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently not 😅

const originalTerminateFunction = service.terminateJob.bind(service);

let promise: Promise<unknown>;
let promise: Promise<unknown> = Promise.resolve();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, TypeScript complains about promise not being assigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants