Skip to content

feat(messenger): add delegateAll with exhaustive type checking - #8338

Merged
cryptodev-2s merged 15 commits into
mainfrom
add-messenger-delegate-all
Jul 28, 2026
Merged

feat(messenger): add delegateAll with exhaustive type checking#8338
cryptodev-2s merged 15 commits into
mainfrom
add-messenger-delegate-all

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Explanation

Messenger.delegate() accepts a partial list of actions/events without compile-time enforcement that all required items are present. This means missing a delegation (e.g., a newly added AllowedAction) silently compiles and only fails at runtime.

delegateAll() wraps delegate() with a RequireExhaustive branded intersection type that produces a clear TypeScript error showing exactly which actions or events are missing from the list. Own-namespace actions of the delegatee are automatically excluded from the check.

Example error when an action is missing:

Property '__missing' is missing in type '[...]'
  but required in type '{ __missing: "KeyringController:signTypedMessage" }'.

References

Changelog

@metamask/messenger

  • Added: delegateAll() method — strict alternative to delegate() that requires all external actions and events to be listed
  • Added: MessengerNamespace<M> utility type — extracts the namespace string literal from a Messenger type
  • Added: RequireExhaustive<Required, Provided> utility type — validates tuple exhaustiveness at compile time

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Low Risk
API addition only (delegateAll delegates to existing delegate); main risk is consumers adopting stricter typing, not runtime behavior changes.

Overview
Adds Messenger.delegateAll, a typed wrapper around delegate that requires every external action and event on the delegatee messenger to be listed (own-namespace items are excluded). Missing entries fail at compile time via a RequireExhaustive branded type that surfaces __MISSING_DELEGATIONS__, and the source messenger must also type-check as able to provide those items.

Also exports MessengerNamespace for extracting a messenger’s namespace literal from its type.

Testing/tooling: Jest unit tests for runtime behavior, new TSTyche (*.tst.ts) compile-time tests, test split into test:unit + test:types, coverage/build/lint configs updated to exclude type-test files, and yarn.config allows the messenger package’s custom test script.

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

@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.0.0-preview-c6e356a6a
@metamask-previews/accounts-controller@37.1.1-preview-c6e356a6a
@metamask-previews/address-book-controller@7.1.1-preview-c6e356a6a
@metamask-previews/ai-controllers@0.6.3-preview-c6e356a6a
@metamask-previews/analytics-controller@1.0.1-preview-c6e356a6a
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-c6e356a6a
@metamask-previews/announcement-controller@8.1.0-preview-c6e356a6a
@metamask-previews/app-metadata-controller@2.0.1-preview-c6e356a6a
@metamask-previews/approval-controller@9.0.1-preview-c6e356a6a
@metamask-previews/assets-controller@3.2.1-preview-c6e356a6a
@metamask-previews/assets-controllers@103.0.0-preview-c6e356a6a
@metamask-previews/base-controller@9.0.1-preview-c6e356a6a
@metamask-previews/base-data-service@0.1.1-preview-c6e356a6a
@metamask-previews/bridge-controller@69.2.3-preview-c6e356a6a
@metamask-previews/bridge-status-controller@70.0.3-preview-c6e356a6a
@metamask-previews/build-utils@3.0.4-preview-c6e356a6a
@metamask-previews/chain-agnostic-permission@1.5.0-preview-c6e356a6a
@metamask-previews/claims-controller@0.5.0-preview-c6e356a6a
@metamask-previews/client-controller@1.0.1-preview-c6e356a6a
@metamask-previews/compliance-controller@1.0.2-preview-c6e356a6a
@metamask-previews/composable-controller@12.0.1-preview-c6e356a6a
@metamask-previews/config-registry-controller@0.2.0-preview-c6e356a6a
@metamask-previews/connectivity-controller@0.2.0-preview-c6e356a6a
@metamask-previews/controller-utils@11.19.0-preview-c6e356a6a
@metamask-previews/core-backend@6.2.1-preview-c6e356a6a
@metamask-previews/delegation-controller@2.1.0-preview-c6e356a6a
@metamask-previews/earn-controller@11.2.1-preview-c6e356a6a
@metamask-previews/eip-5792-middleware@3.0.2-preview-c6e356a6a
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-c6e356a6a
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-c6e356a6a
@metamask-previews/ens-controller@19.1.1-preview-c6e356a6a
@metamask-previews/eth-block-tracker@15.0.1-preview-c6e356a6a
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-c6e356a6a
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-c6e356a6a
@metamask-previews/foundryup@1.0.1-preview-c6e356a6a
@metamask-previews/gas-fee-controller@26.1.1-preview-c6e356a6a
@metamask-previews/gator-permissions-controller@3.0.0-preview-c6e356a6a
@metamask-previews/geolocation-controller@0.1.2-preview-c6e356a6a
@metamask-previews/json-rpc-engine@10.2.4-preview-c6e356a6a
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-c6e356a6a
@metamask-previews/keyring-controller@25.1.1-preview-c6e356a6a
@metamask-previews/logging-controller@8.0.1-preview-c6e356a6a
@metamask-previews/message-manager@14.1.1-preview-c6e356a6a
@metamask-previews/messenger@1.0.0-preview-c6e356a6a
@metamask-previews/multichain-account-service@8.0.1-preview-c6e356a6a
@metamask-previews/multichain-api-middleware@2.0.0-preview-c6e356a6a
@metamask-previews/multichain-network-controller@3.0.6-preview-c6e356a6a
@metamask-previews/multichain-transactions-controller@7.0.4-preview-c6e356a6a
@metamask-previews/name-controller@9.1.1-preview-c6e356a6a
@metamask-previews/network-controller@30.0.1-preview-c6e356a6a
@metamask-previews/network-enablement-controller@5.0.1-preview-c6e356a6a
@metamask-previews/notification-services-controller@23.0.1-preview-c6e356a6a
@metamask-previews/permission-controller@12.3.0-preview-c6e356a6a
@metamask-previews/permission-log-controller@5.1.0-preview-c6e356a6a
@metamask-previews/perps-controller@2.0.0-preview-c6e356a6a
@metamask-previews/phishing-controller@17.1.0-preview-c6e356a6a
@metamask-previews/polling-controller@16.0.4-preview-c6e356a6a
@metamask-previews/preferences-controller@23.1.0-preview-c6e356a6a
@metamask-previews/profile-metrics-controller@3.1.2-preview-c6e356a6a
@metamask-previews/profile-sync-controller@28.0.2-preview-c6e356a6a
@metamask-previews/ramps-controller@12.1.0-preview-c6e356a6a
@metamask-previews/rate-limit-controller@7.0.1-preview-c6e356a6a
@metamask-previews/react-data-query@0.2.0-preview-c6e356a6a
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-c6e356a6a
@metamask-previews/sample-controllers@4.0.4-preview-c6e356a6a
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-c6e356a6a
@metamask-previews/selected-network-controller@26.1.0-preview-c6e356a6a
@metamask-previews/shield-controller@5.1.0-preview-c6e356a6a
@metamask-previews/signature-controller@39.1.2-preview-c6e356a6a
@metamask-previews/social-controllers@0.0.0-preview-c6e356a6a
@metamask-previews/storage-service@1.0.1-preview-c6e356a6a
@metamask-previews/subscription-controller@6.1.1-preview-c6e356a6a
@metamask-previews/transaction-controller@63.3.1-preview-c6e356a6a
@metamask-previews/transaction-pay-controller@19.0.0-preview-c6e356a6a
@metamask-previews/user-operation-controller@41.1.1-preview-c6e356a6a

@cryptodev-2s
cryptodev-2s force-pushed the add-messenger-delegate-all branch from 5bd4a95 to f0e25c9 Compare March 30, 2026 17:44
`delegate` accepts partial action/event lists without compile-time
enforcement that all required items are present. `delegateAll` uses
a branded intersection type to produce a clear TS error showing
exactly which actions or events are missing.
@cryptodev-2s
cryptodev-2s force-pushed the add-messenger-delegate-all branch from f0e25c9 to 0bc2ac9 Compare April 7, 2026 16:59
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.0.0-preview-0bc2ac9
@metamask-previews/accounts-controller@37.2.0-preview-0bc2ac9
@metamask-previews/address-book-controller@7.1.1-preview-0bc2ac9
@metamask-previews/ai-controllers@0.6.3-preview-0bc2ac9
@metamask-previews/analytics-controller@1.0.1-preview-0bc2ac9
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-0bc2ac9
@metamask-previews/announcement-controller@8.1.0-preview-0bc2ac9
@metamask-previews/app-metadata-controller@2.0.1-preview-0bc2ac9
@metamask-previews/approval-controller@9.0.1-preview-0bc2ac9
@metamask-previews/assets-controller@4.0.0-preview-0bc2ac9
@metamask-previews/assets-controllers@103.1.1-preview-0bc2ac9
@metamask-previews/base-controller@9.0.1-preview-0bc2ac9
@metamask-previews/base-data-service@0.1.1-preview-0bc2ac9
@metamask-previews/bridge-controller@70.0.1-preview-0bc2ac9
@metamask-previews/bridge-status-controller@70.0.5-preview-0bc2ac9
@metamask-previews/build-utils@3.0.4-preview-0bc2ac9
@metamask-previews/chain-agnostic-permission@1.5.0-preview-0bc2ac9
@metamask-previews/claims-controller@0.5.0-preview-0bc2ac9
@metamask-previews/client-controller@1.0.1-preview-0bc2ac9
@metamask-previews/compliance-controller@2.0.0-preview-0bc2ac9
@metamask-previews/composable-controller@12.0.1-preview-0bc2ac9
@metamask-previews/config-registry-controller@0.2.0-preview-0bc2ac9
@metamask-previews/connectivity-controller@0.2.0-preview-0bc2ac9
@metamask-previews/controller-utils@11.20.0-preview-0bc2ac9
@metamask-previews/core-backend@6.2.1-preview-0bc2ac9
@metamask-previews/delegation-controller@2.1.0-preview-0bc2ac9
@metamask-previews/earn-controller@11.2.1-preview-0bc2ac9
@metamask-previews/eip-5792-middleware@3.0.3-preview-0bc2ac9
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-0bc2ac9
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-0bc2ac9
@metamask-previews/ens-controller@19.1.1-preview-0bc2ac9
@metamask-previews/eth-block-tracker@15.0.1-preview-0bc2ac9
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-0bc2ac9
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-0bc2ac9
@metamask-previews/foundryup@1.0.1-preview-0bc2ac9
@metamask-previews/gas-fee-controller@26.1.1-preview-0bc2ac9
@metamask-previews/gator-permissions-controller@3.0.1-preview-0bc2ac9
@metamask-previews/geolocation-controller@0.1.2-preview-0bc2ac9
@metamask-previews/json-rpc-engine@10.2.4-preview-0bc2ac9
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-0bc2ac9
@metamask-previews/keyring-controller@25.2.0-preview-0bc2ac9
@metamask-previews/logging-controller@8.0.1-preview-0bc2ac9
@metamask-previews/message-manager@14.1.1-preview-0bc2ac9
@metamask-previews/messenger@1.1.1-preview-0bc2ac9
@metamask-previews/messenger-cli@0.1.0-preview-0bc2ac9
@metamask-previews/money-account-controller@0.1.0-preview-0bc2ac9
@metamask-previews/multichain-account-service@8.0.1-preview-0bc2ac9
@metamask-previews/multichain-api-middleware@2.0.0-preview-0bc2ac9
@metamask-previews/multichain-network-controller@3.0.6-preview-0bc2ac9
@metamask-previews/multichain-transactions-controller@7.0.4-preview-0bc2ac9
@metamask-previews/name-controller@9.1.1-preview-0bc2ac9
@metamask-previews/network-controller@30.0.1-preview-0bc2ac9
@metamask-previews/network-enablement-controller@5.0.2-preview-0bc2ac9
@metamask-previews/notification-services-controller@23.0.1-preview-0bc2ac9
@metamask-previews/permission-controller@12.3.0-preview-0bc2ac9
@metamask-previews/permission-log-controller@5.1.0-preview-0bc2ac9
@metamask-previews/perps-controller@2.0.0-preview-0bc2ac9
@metamask-previews/phishing-controller@17.1.1-preview-0bc2ac9
@metamask-previews/polling-controller@16.0.4-preview-0bc2ac9
@metamask-previews/preferences-controller@23.1.0-preview-0bc2ac9
@metamask-previews/profile-metrics-controller@3.1.3-preview-0bc2ac9
@metamask-previews/profile-sync-controller@28.0.2-preview-0bc2ac9
@metamask-previews/ramps-controller@13.0.0-preview-0bc2ac9
@metamask-previews/rate-limit-controller@7.0.1-preview-0bc2ac9
@metamask-previews/react-data-query@0.2.0-preview-0bc2ac9
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-0bc2ac9
@metamask-previews/sample-controllers@4.0.4-preview-0bc2ac9
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-0bc2ac9
@metamask-previews/selected-network-controller@26.1.0-preview-0bc2ac9
@metamask-previews/shield-controller@5.1.1-preview-0bc2ac9
@metamask-previews/signature-controller@39.1.2-preview-0bc2ac9
@metamask-previews/social-controllers@0.1.0-preview-0bc2ac9
@metamask-previews/storage-service@1.0.1-preview-0bc2ac9
@metamask-previews/subscription-controller@6.1.2-preview-0bc2ac9
@metamask-previews/transaction-controller@64.0.0-preview-0bc2ac9
@metamask-previews/transaction-pay-controller@19.0.3-preview-0bc2ac9
@metamask-previews/user-operation-controller@41.2.0-preview-0bc2ac9

@cryptodev-2s
cryptodev-2s marked this pull request as ready for review July 24, 2026 13:39
@cryptodev-2s
cryptodev-2s requested a review from a team as a code owner July 24, 2026 13:39

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Overall strategy seems sound, but I had some suggestions.

Comment thread packages/messenger/src/Messenger.test.ts Outdated
Comment thread packages/messenger/src/Messenger.ts Outdated
Comment thread packages/messenger/src/Messenger.ts Outdated
Comment thread packages/messenger/src/Messenger.ts Outdated
Comment thread packages/messenger/src/Messenger.ts Outdated
Comment thread packages/messenger/src/Messenger.ts Outdated
Align delegateAll type params with delegate/revoke, drop casts, and
rename the missing-delegations brand for clearer type errors.
Move exhaustiveness checks out of Jest into compile-time tests so
missing delegations are verified by the type checker.
Comment thread packages/messenger/tsconfig.build.json Outdated
@socket-security

socket-security Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedtstyche@​5.0.29410010095100

View full report

@socket-security

socket-security Bot commented Jul 25, 2026

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

Ignoring alerts on:

  • tstyche@5.0.2

View full report

Keep Jest test files out of the build when excluding TSTyche files,
format misc lint failures, and allow messenger's combined test script.
@cryptodev-2s
cryptodev-2s requested a review from mcmire July 27, 2026 10:22

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 0f82791. Configure here.

Comment thread packages/messenger/src/Messenger.ts
Require every external delegatee action/event in the exhaustiveness
check, even when the source type omits them, and cover missing events
plus unsupported source deps in tstyche.
Mirror the Jest layout with one Messenger type test file and nested
describes instead of a per-method file.

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One more thing.

Comment thread packages/messenger/src/Messenger.ts
mcmire
mcmire previously approved these changes Jul 27, 2026

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@cryptodev-2s
cryptodev-2s added this pull request to the merge queue Jul 27, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 27, 2026
@cryptodev-2s cryptodev-2s self-assigned this Jul 27, 2026
Intentional type errors in Messenger.tst.ts fail project typecheck;
keep them under yarn test:types only.
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@SocketSecurity ignore npm/tstyche@5.0.2
Used as a dev dependency only

@cryptodev-2s
cryptodev-2s requested a review from mcmire July 28, 2026 11:01

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.

@cryptodev-2s
cryptodev-2s added this pull request to the merge queue Jul 28, 2026
Merged via the queue into main with commit fd8f375 Jul 28, 2026
428 checks passed
@cryptodev-2s
cryptodev-2s deleted the add-messenger-delegate-all branch July 28, 2026 14:08
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