Skip to content

feat(messenger): add getRegisteredActionTypes accessor#9271

Merged
sirtimid merged 3 commits into
mainfrom
sirtimid/messenger-registered-action-types
Jun 29, 2026
Merged

feat(messenger): add getRegisteredActionTypes accessor#9271
sirtimid merged 3 commits into
mainfrom
sirtimid/messenger-registered-action-types

Conversation

@sirtimid

@sirtimid sirtimid commented Jun 25, 2026

Copy link
Copy Markdown
Member

Explanation

Adds a public, read-only accessor Messenger.getRegisteredActionTypes() that returns the action types a messenger can call() directly — actions registered on it plus actions delegated into it from a child messenger. It returns [...this.#actions.keys()].

There is no public way to enumerate a messenger's callable actions today.

Why string[] and not Action['type'][]

The first instinct is to type the return as the messenger's action-type union for nicer caller types. That's not safe here: it would make Action appear in a covariant (return) position — the first such member on the class. Every existing Action-dependent method (call, registerActionHandler) deliberately keeps Action behind a bounded generic to avoid this. A covariant Action member breaks assigning a messenger to a narrower-typed one (e.g. passing a controller's full messenger to a service typed against only a subset of its actions) — a pattern consumers rely on (@metamask/perps-controller does exactly this and fails to compile with the union return). No union-derived return type avoids this; only a constant return type does. string[] is sufficient for the consumer below, which just lists/prints the types.

Why

@metamask/wallet-cli is gaining an mm daemon list command to enumerate the actions on the wallet's root messenger (sibling to the existing mm daemon call <Controller>:<method>). That needs a public accessor on the messenger, which this PR adds. The command itself is a separate wallet-cli follow-up.

Notes for reviewers

  • Non-breaking and purely additive — new read-only method, no behavior change. Verified with a full monorepo build.
  • Method name is open to bikeshedding.

🤖 Generated with Claude Code


Note

Low Risk
Additive read-only API with no change to call or registration behavior; return type is intentionally loose to preserve existing messenger assignability patterns.

Overview
Adds Messenger.getRegisteredActionTypes(), a read-only API that lists action types the instance can call() directly—local registrations plus actions delegated into that messenger. It returns [...this.#actions.keys()] as string[] (not the messenger’s action-type union) so callers can enumerate actions without introducing a covariant Action return that would break assigning messengers to narrower action typings.

Unit tests cover empty messengers, register/unregister, and delegated actions. packages/messenger/CHANGELOG.md documents the addition.

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

@sirtimid sirtimid force-pushed the sirtimid/messenger-registered-action-types branch from ad9e23f to 41944f4 Compare June 25, 2026 20:34
@sirtimid sirtimid marked this pull request as ready for review June 25, 2026 20:35
@sirtimid sirtimid requested a review from a team as a code owner June 25, 2026 20:35
@sirtimid sirtimid temporarily deployed to default-branch June 25, 2026 20:35 — with GitHub Actions Inactive
Add a public, read-only `getRegisteredActionTypes()` method to the
`Messenger` class that returns every action type the messenger can call
directly — actions registered on it plus actions delegated into it. This
gives consumers a way to discover a messenger's callable action surface
(needed by an upcoming `mm daemon list` command in `@metamask/wallet-cli`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sirtimid sirtimid force-pushed the sirtimid/messenger-registered-action-types branch from 41944f4 to c14f260 Compare June 25, 2026 20:57
@sirtimid sirtimid enabled auto-merge June 25, 2026 20:59
Comment thread packages/messenger/src/Messenger.ts Outdated
* Get the types of all actions that this messenger can call directly.
*
* This includes actions registered on this messenger as well as actions that
* have been delegated into it from another messenger. It does not include

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.

Suggested change
* have been delegated into it from another messenger. It does not include
* have been delegated to it from another messenger. It does not include

nit

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.

Done 2a4dfbf

Comment thread packages/messenger/src/Messenger.ts Outdated
* Get the types of all actions that this messenger can call directly.
*
* This includes actions registered on this messenger as well as actions that
* have been delegated into it from another messenger. It does not include

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 follow the last line: "It does not include actions this messenger has delegated out to other messengers". Can you elaborate on that?

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.

Actually that line is misleading and I removed it 2a4dfbf Thanks!

@sirtimid sirtimid requested a review from FrederikBolding June 29, 2026 15:38
@sirtimid sirtimid added this pull request to the merge queue Jun 29, 2026
Merged via the queue into main with commit 8c7227e Jun 29, 2026
400 checks passed
@sirtimid sirtimid deleted the sirtimid/messenger-registered-action-types branch June 29, 2026 21:14
pull Bot pushed a commit to dmrazzy/core that referenced this pull request Jul 1, 2026
…MetaMask#9339)

## What

`mm daemon call <Controller>:<method>` can dispatch **any** registered
messenger action, but a consumer had no way to see what's callable — and
the surface grows silently as controllers are wired. This adds `mm
daemon list` to enumerate it.

- **`listActions` RPC handler** in the daemon, backed by the live
messenger's `getRegisteredActionTypes()` (landed in MetaMask#9271), so the list
can never drift from what `call` actually accepts — no hand-kept catalog
to rot.
- **`mm daemon list` command** renders an indented, counted list on a
TTY, and a bare, sorted, newline-delimited list when piped (so it pipes
cleanly into `grep`/`fzf`).
- **README** usage section refreshed: documents `list`, frames the
surface as evolving (not a stability contract), links out to each
controller's TypeDoc/README for exhaustive detail, and drops the stale
`@deprecated AccountsController:listAccounts` example (fixed to
`KeyringController:getState`).

## Testing

- New `list.test.ts` and a `listActions` handler test in
`daemon-entry.test.ts`; package stays at 100% coverage.
- `build`, `test`, `lint`, and `changelog:validate` all pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> CLI-only discovery and error-message refactors; no changes to wallet
auth, key handling, or messenger dispatch semantics beyond a read-only
introspection RPC.
> 
> **Overview**
> Adds **`mm daemon list`** so users can see which messenger actions the
running wallet daemon accepts via `daemon call`, without maintaining a
static catalog.
> 
> The daemon exposes a new **`listActions`** JSON-RPC handler that
returns `messenger.getRegisteredActionTypes()`, keeping discovery
aligned with what `call` can dispatch. The CLI sorts actions
lexicographically: on a TTY it prints a counted, indented list with
usage hints; when piped it emits a bare newline-delimited list for
`grep`/`fzf`.
> 
> **`mm daemon call`** now shares centralized socket and JSON-RPC error
handling via `makeDaemonConnectionError`, `formatJsonRpcError`, and
`isStringArray` in `daemon/utils`, including clearer messages for
`ECONNRESET` and permission errors. README and changelog document `list`
and refresh `call` examples.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e9a0545. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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