Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[composable-controller] Enable handling of non-controller input #4943

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

MajorLift
Copy link
Contributor

@MajorLift MajorLift commented Nov 19, 2024

References

Changelog

@metamask/composable-controller

Changed

  • Widen ComposableController controller option controllers and generic type parameter ChildControllers to accept all objects with a 'name' property. Passing in non-controller input no longer produces a runtime error.
    • Note that the composed state output and stateChange event subscription operation will exclude non-controller input.
    • Generic type parameter ComposableControllerState only accepts controllers with a 'state' property.
  • Widen input type for type guards isBaseController, isBaseControllerV1 from ControllerInstance to unknown.

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 highlighted breaking changes using the "BREAKING" category above as appropriate
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

@MajorLift MajorLift added team-wallet-framework team-tiger Tiger team (for tech debt reduction + performance improvements) labels Nov 19, 2024
@MajorLift MajorLift self-assigned this Nov 19, 2024
@MajorLift
Copy link
Contributor Author

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "19.0.0-preview-bb2f1fdd",
  "@metamask-previews/address-book-controller": "6.0.1-preview-bb2f1fdd",
  "@metamask-previews/announcement-controller": "7.0.1-preview-bb2f1fdd",
  "@metamask-previews/approval-controller": "7.1.1-preview-bb2f1fdd",
  "@metamask-previews/assets-controllers": "44.0.0-preview-bb2f1fdd",
  "@metamask-previews/base-controller": "7.0.2-preview-bb2f1fdd",
  "@metamask-previews/build-utils": "3.0.1-preview-bb2f1fdd",
  "@metamask-previews/chain-controller": "0.1.3-preview-bb2f1fdd",
  "@metamask-previews/composable-controller": "9.0.1-preview-bb2f1fdd",
  "@metamask-previews/controller-utils": "11.4.3-preview-bb2f1fdd",
  "@metamask-previews/ens-controller": "15.0.0-preview-bb2f1fdd",
  "@metamask-previews/eth-json-rpc-provider": "4.1.6-preview-bb2f1fdd",
  "@metamask-previews/gas-fee-controller": "22.0.1-preview-bb2f1fdd",
  "@metamask-previews/json-rpc-engine": "10.0.1-preview-bb2f1fdd",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.5-preview-bb2f1fdd",
  "@metamask-previews/keyring-controller": "18.0.0-preview-bb2f1fdd",
  "@metamask-previews/logging-controller": "6.0.2-preview-bb2f1fdd",
  "@metamask-previews/message-manager": "11.0.1-preview-bb2f1fdd",
  "@metamask-previews/multichain": "0.0.0-preview-bb2f1fdd",
  "@metamask-previews/name-controller": "8.0.1-preview-bb2f1fdd",
  "@metamask-previews/network-controller": "22.0.2-preview-bb2f1fdd",
  "@metamask-previews/notification-controller": "7.0.0-preview-bb2f1fdd",
  "@metamask-previews/notification-services-controller": "0.13.0-preview-bb2f1fdd",
  "@metamask-previews/permission-controller": "11.0.3-preview-bb2f1fdd",
  "@metamask-previews/permission-log-controller": "3.0.1-preview-bb2f1fdd",
  "@metamask-previews/phishing-controller": "12.3.0-preview-bb2f1fdd",
  "@metamask-previews/polling-controller": "12.0.1-preview-bb2f1fdd",
  "@metamask-previews/preferences-controller": "14.0.0-preview-bb2f1fdd",
  "@metamask-previews/profile-sync-controller": "1.0.0-preview-bb2f1fdd",
  "@metamask-previews/queued-request-controller": "7.0.1-preview-bb2f1fdd",
  "@metamask-previews/rate-limit-controller": "6.0.1-preview-bb2f1fdd",
  "@metamask-previews/selected-network-controller": "19.0.0-preview-bb2f1fdd",
  "@metamask-previews/signature-controller": "22.0.0-preview-bb2f1fdd",
  "@metamask-previews/transaction-controller": "39.0.0-preview-bb2f1fdd",
  "@metamask-previews/user-operation-controller": "18.0.0-preview-bb2f1fdd"
}

@MajorLift
Copy link
Contributor Author

MajorLift commented Nov 19, 2024

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "19.0.0-preview-3d44b965",
  "@metamask-previews/address-book-controller": "6.0.1-preview-3d44b965",
  "@metamask-previews/announcement-controller": "7.0.1-preview-3d44b965",
  "@metamask-previews/approval-controller": "7.1.1-preview-3d44b965",
  "@metamask-previews/assets-controllers": "44.0.0-preview-3d44b965",
  "@metamask-previews/base-controller": "7.0.2-preview-3d44b965",
  "@metamask-previews/build-utils": "3.0.1-preview-3d44b965",
  "@metamask-previews/chain-controller": "0.1.3-preview-3d44b965",
  "@metamask-previews/composable-controller": "9.0.1-preview-3d44b965",
  "@metamask-previews/controller-utils": "11.4.3-preview-3d44b965",
  "@metamask-previews/ens-controller": "15.0.0-preview-3d44b965",
  "@metamask-previews/eth-json-rpc-provider": "4.1.6-preview-3d44b965",
  "@metamask-previews/gas-fee-controller": "22.0.1-preview-3d44b965",
  "@metamask-previews/json-rpc-engine": "10.0.1-preview-3d44b965",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.5-preview-3d44b965",
  "@metamask-previews/keyring-controller": "18.0.0-preview-3d44b965",
  "@metamask-previews/logging-controller": "6.0.2-preview-3d44b965",
  "@metamask-previews/message-manager": "11.0.1-preview-3d44b965",
  "@metamask-previews/multichain": "0.0.0-preview-3d44b965",
  "@metamask-previews/name-controller": "8.0.1-preview-3d44b965",
  "@metamask-previews/network-controller": "22.0.2-preview-3d44b965",
  "@metamask-previews/notification-controller": "7.0.0-preview-3d44b965",
  "@metamask-previews/notification-services-controller": "0.13.0-preview-3d44b965",
  "@metamask-previews/permission-controller": "11.0.3-preview-3d44b965",
  "@metamask-previews/permission-log-controller": "3.0.1-preview-3d44b965",
  "@metamask-previews/phishing-controller": "12.3.0-preview-3d44b965",
  "@metamask-previews/polling-controller": "12.0.1-preview-3d44b965",
  "@metamask-previews/preferences-controller": "14.0.0-preview-3d44b965",
  "@metamask-previews/profile-sync-controller": "1.0.0-preview-3d44b965",
  "@metamask-previews/queued-request-controller": "7.0.1-preview-3d44b965",
  "@metamask-previews/rate-limit-controller": "6.0.1-preview-3d44b965",
  "@metamask-previews/selected-network-controller": "19.0.0-preview-3d44b965",
  "@metamask-previews/signature-controller": "22.0.0-preview-3d44b965",
  "@metamask-previews/transaction-controller": "39.0.0-preview-3d44b965",
  "@metamask-previews/user-operation-controller": "18.0.0-preview-3d44b965"
}

@MajorLift
Copy link
Contributor Author

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "19.0.0-preview-335c4644",
  "@metamask-previews/address-book-controller": "6.0.1-preview-335c4644",
  "@metamask-previews/announcement-controller": "7.0.1-preview-335c4644",
  "@metamask-previews/approval-controller": "7.1.1-preview-335c4644",
  "@metamask-previews/assets-controllers": "44.0.0-preview-335c4644",
  "@metamask-previews/base-controller": "7.0.2-preview-335c4644",
  "@metamask-previews/build-utils": "3.0.1-preview-335c4644",
  "@metamask-previews/chain-controller": "0.1.3-preview-335c4644",
  "@metamask-previews/composable-controller": "9.0.1-preview-335c4644",
  "@metamask-previews/controller-utils": "11.4.3-preview-335c4644",
  "@metamask-previews/ens-controller": "15.0.0-preview-335c4644",
  "@metamask-previews/eth-json-rpc-provider": "4.1.6-preview-335c4644",
  "@metamask-previews/gas-fee-controller": "22.0.1-preview-335c4644",
  "@metamask-previews/json-rpc-engine": "10.0.1-preview-335c4644",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.5-preview-335c4644",
  "@metamask-previews/keyring-controller": "18.0.0-preview-335c4644",
  "@metamask-previews/logging-controller": "6.0.2-preview-335c4644",
  "@metamask-previews/message-manager": "11.0.1-preview-335c4644",
  "@metamask-previews/multichain": "0.0.0-preview-335c4644",
  "@metamask-previews/name-controller": "8.0.1-preview-335c4644",
  "@metamask-previews/network-controller": "22.0.2-preview-335c4644",
  "@metamask-previews/notification-controller": "7.0.0-preview-335c4644",
  "@metamask-previews/notification-services-controller": "0.13.0-preview-335c4644",
  "@metamask-previews/permission-controller": "11.0.3-preview-335c4644",
  "@metamask-previews/permission-log-controller": "3.0.1-preview-335c4644",
  "@metamask-previews/phishing-controller": "12.3.0-preview-335c4644",
  "@metamask-previews/polling-controller": "12.0.1-preview-335c4644",
  "@metamask-previews/preferences-controller": "14.0.0-preview-335c4644",
  "@metamask-previews/profile-sync-controller": "1.0.0-preview-335c4644",
  "@metamask-previews/queued-request-controller": "7.0.1-preview-335c4644",
  "@metamask-previews/rate-limit-controller": "6.0.1-preview-335c4644",
  "@metamask-previews/selected-network-controller": "19.0.0-preview-335c4644",
  "@metamask-previews/signature-controller": "22.0.0-preview-335c4644",
  "@metamask-previews/transaction-controller": "39.0.0-preview-335c4644",
  "@metamask-previews/user-operation-controller": "18.0.0-preview-335c4644"
}

@@ -16,8 +15,18 @@ import type { Patch } from 'immer';

export const controllerName = 'ComposableController';

export const INVALID_CONTROLLER_ERROR =
'Invalid controller: controller must have a `messagingSystem` or be a class inheriting from `BaseControllerV1`.';
// TODO: Replace with type guard once superclass for messageable non-controllers has been defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

If the goal is to figure out which controllers do not have state, can we check for the absence of the state property?

Copy link
Contributor Author

@MajorLift MajorLift Nov 19, 2024

Choose a reason for hiding this comment

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

Unfortunately only AssetsContractController lacks a state property.

NftDetectionController and TokenDetectionController both have a state property which is assigned an empty object of type Record<never, never>, because both inherit from BaseController.

Checking for an empty state object is not useful because there could be controllers with non-empty state that are initialized with empty state objects.

These inconsistencies make the changes in this PR less type-safe than they could be. This ties in to one of the motivations for the MessengerClient/Messageable ADR. which is to align inheritance for stateless non-controllers.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I see. My thought is that we could clean this up by assuming that the non-controllers do not inherit from BaseController. I forgot that we will do that through the MessengerClient/Messageable ADR though.

Copy link
Contributor Author

@MajorLift MajorLift Nov 19, 2024

Choose a reason for hiding this comment

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

There's currently no common supertype for the stateless non-controllers that is narrower than an object with a 'name' property.

Ideally, we would be able to exclude all classes with properties 'name', 'messagingSystem' and without 'state', 'metadata', but since that's currently not an option until the ADR is implemented, I went for just explicitly specifying the non-controllers, so we wouldn't have to deal with edge cases in the input.

I refactored the logic a bit. Hopefully this makes the intention a bit clearer: 85389bb

@MajorLift MajorLift marked this pull request as ready for review November 19, 2024 16:58
@MajorLift MajorLift requested a review from a team as a code owner November 19, 2024 16:58
TODO: move to `@metamask/base-controller` once we have a type and type guard for stateless non-controllers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-tiger Tiger team (for tech debt reduction + performance improvements) team-wallet-framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[composable-controller] Enable handling of input that includes non-controllers with empty state
2 participants