Skip to content

refactor(snaps-rpc-methods)!: Use messenger for restricted method implementations#3968

Open
FrederikBolding wants to merge 19 commits intomainfrom
fb/restricted-methods-messenger
Open

refactor(snaps-rpc-methods)!: Use messenger for restricted method implementations#3968
FrederikBolding wants to merge 19 commits intomainfrom
fb/restricted-methods-messenger

Conversation

@FrederikBolding
Copy link
Copy Markdown
Member

@FrederikBolding FrederikBolding commented Apr 24, 2026

Migrate the restricted method implementations to use the messenger where applicable.

https://consensyssoftware.atlassian.net/browse/WPC-995


Note

Medium Risk
Refactors multiple security- and UX-sensitive restricted RPC methods (entropy/key derivation, state storage, dialogs/notifications) to route through the controller Messenger, which could change call wiring and error behavior if action names/arguments are mismatched.

Overview
Refactors restricted method implementations to use the controller Messenger instead of direct hook functions. buildSnapRestrictedMethodSpecifications now requires a root RestrictedMethodMessenger and creates per-method restricted messengers via createRestrictedMethodMessenger, using each method’s declared actionNames.

Updates the affected restricted methods (e.g., snap_dialog, snap_notify, wallet_snap, snap_manageState, and entropy/BIP derivation methods) to call controller actions like ApprovalController:addRequest, SnapController:*, SnapInterfaceController:*, RateLimitController:call, and KeyringController:withKeyring. Adds centralized action typings in src/types.ts and new utils.ts helpers (getMnemonic, getMnemonicSeed) for keyring-backed entropy access, with expanded tests and a few simulation hook removals/adjustments.

Reviewed by Cursor Bugbot for commit 91050f5. Bugbot is set up for automated code reviews on this repo. Configure here.

@FrederikBolding FrederikBolding force-pushed the fb/restricted-methods-messenger branch from e80f1b8 to bd01104 Compare May 4, 2026 09:43
@FrederikBolding FrederikBolding changed the title refactor(snaps-rpc-methods): Use messenger for method implementations refactor(snaps-rpc-methods): Use messenger for restricted method implementations May 4, 2026
Comment thread packages/snaps-rpc-methods/src/restricted/dialog.ts Outdated
Comment thread packages/snaps-rpc-methods/src/restricted/dialog.ts Outdated
Comment on lines +153 to +158
actionNames: [
'ApprovalController:addRequest',
'SnapInterfaceController:createInterface',
'SnapInterfaceController:getInterface',
'SnapInterfaceController:setInterfaceDisplayed',
],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe to match the UI messenger:

Suggested change
actionNames: [
'ApprovalController:addRequest',
'SnapInterfaceController:createInterface',
'SnapInterfaceController:getInterface',
'SnapInterfaceController:setInterfaceDisplayed',
],
capabilities: {
actions: [
'ApprovalController:addRequest',
'SnapInterfaceController:createInterface',
'SnapInterfaceController:getInterface',
'SnapInterfaceController:setInterfaceDisplayed',
],
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

createRestrictedMethodMessenger uses the actionNames naming, that's why I chose to name it like that for the specifications. Do you think it is cleaner to do: actionNames: capabilities.actions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong opinion, actionNames is fine with me.

@FrederikBolding FrederikBolding changed the title refactor(snaps-rpc-methods): Use messenger for restricted method implementations refactor(snaps-rpc-methods)!: Use messenger for restricted method implementations May 5, 2026
Comment on lines +74 to +92
(
specifications,
// @ts-expect-error TypeScript is not convinced methodHooks and actionNames exist
{ targetName, specificationBuilder, methodHooks, actionNames },
) => {
if (!excludedPermissions.includes(targetName)) {
specifications[targetName] = specificationBuilder({
// @ts-expect-error The selectHooks type is wonky
methodHooks: selectHooks(hooks, methodHooks),
// @ts-expect-error Messenger type cannot be narrowed correctly
messenger: createRestrictedMethodMessenger({
namespace: targetName,
rootMessenger: messenger,
actionNames,
}),
});
}
return specifications;
},
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Suggestions welcome for how to satisfy TypeScript here 🫠

@FrederikBolding FrederikBolding force-pushed the fb/restricted-methods-messenger branch from 37fbc73 to 5aa93a9 Compare May 5, 2026 09:34
@FrederikBolding FrederikBolding marked this pull request as ready for review May 5, 2026 09:34
@FrederikBolding FrederikBolding requested a review from a team as a code owner May 5, 2026 09:34
@FrederikBolding FrederikBolding requested a review from Mrtenz May 5, 2026 09:34
Comment thread packages/snaps-rpc-methods/src/restricted/index.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 99.07407% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.58%. Comparing base (dcb5bf9) to head (91050f5).

Files with missing lines Patch % Lines
...ackages/snaps-rpc-methods/src/restricted/notify.ts 92.30% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3968      +/-   ##
==========================================
+ Coverage   98.56%   98.58%   +0.02%     
==========================================
  Files         429      427       -2     
  Lines       12365    12399      +34     
  Branches     1944     1948       +4     
==========================================
+ Hits        12187    12223      +36     
+ Misses        178      176       -2     

☔ 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.

Comment on lines +269 to +274
const { content, message, title, footerLink } =
validatedParams as NotificationArgs & {
content?: string;
title?: string;
footerLink?: { href: string; text: string };
};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This mess is copied from the extension, suggestions for improvements welcome 🫠

Comment thread packages/snaps-rpc-methods/src/utils.ts
Comment thread packages/snaps-rpc-methods/src/utils.ts Outdated
Copy link
Copy Markdown

@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.

Reviewed by Cursor Bugbot for commit c0bd4e3. Configure here.

Comment thread packages/snaps-rpc-methods/src/utils.ts
getUnlockPromise,
getClientCryptography,
}: GetBip32EntropyMethodHooks) {
methodHooks: { getUnlockPromise, getClientCryptography },
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wondering if we should add an action to the Snap controller for this, so we can fully remove the hooks?

| ManageStateMessengerActions
| NotifyMessengerActions;

export type RestrictedMethodMessenger = Messenger<
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this mean we create a messenger that has access to all the actions used by these methods? Should it be scoped to individual methods?

Comment on lines 76 to 78
isOnPhishingList: (url: string) => boolean;

maybeUpdatePhishingList: () => Promise<void>;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can't we get this from the phishing controller?

Comment on lines +76 to +77
// @ts-expect-error TypeScript is not convinced methodHooks and actionNames exist
{ targetName, specificationBuilder, methodHooks, actionNames },
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, this doesn't seem ideal 😅. I can take a look tomorrow.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't love that we have to copy (and maintain) a bunch of types. We should definitely reconsider a messenger types package for each controller.

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