-
-
Notifications
You must be signed in to change notification settings - Fork 207
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
feat: Add MultichainNetworkController
to handle both EVM and non-EVM network and account switching
#5215
feat: Add MultichainNetworkController
to handle both EVM and non-EVM network and account switching
#5215
Conversation
… to update nonEvmNetwork state variable to false; added unit tests for setActiveNetwork and both new setters
This looks amazing! Lets align today with the review made on the PR #5209 |
…script documentation, and solve most of the review comments
…Mask/core into feat/handle-multichain-network-and-account-switching
…Mask/core into feat/handle-multichain-network-and-account-switching
…ichain-network-and-account-switching
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a lot better now. I had a couple of comments about the use of barrel exports and also a missing dependency in accounts-controller
but other than that the rest are minor and can be deferred to a future PR.
…ichain-network-and-account-switching
Co-authored-by: Charly Chevalier <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, just one more thing.
Co-authored-by: Elliot Winkler <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linting errors :(
packages/multichain-network-controller/src/MultichainNetworkController.ts
Outdated
Show resolved
Hide resolved
…ntroller.ts Co-authored-by: Elliot Winkler <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. We'll follow up this PR with the decoupling of the selected network from the network configurations
} | ||
|
||
// Handle switching to non-EVM network | ||
const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use account.scopes
to check which chains are supported by the account.
With the new scopes
we don't need this kind of runtime logic anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate on how this logic might look with your suggestion? FYI, one of the reasons that we kept accounts controller and multichain network controller away from each other is prevent circular dependencies.
// Notify listeners that setActiveNetwork was called | ||
this.messagingSystem.publish( | ||
'MultichainNetworkController:networkDidChange', | ||
id, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this should have been fired after the actually update the network configuration.
If some logic is checking the actual state from this controller (and its counterpart the NetworkController
) and react to this event, the state won't be "consistent", no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
// Notify listeners that setActiveNetwork was called | ||
this.messagingSystem.publish( | ||
'MultichainNetworkController:networkDidChange', | ||
id, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we notify twice? We just do it in the if
right before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. It was missing a return statement. Ended up simplifying this logic
this.update((currentState) => { | ||
currentState.internalAccounts.accounts[accountId].metadata.lastSelected = | ||
Date.now(); | ||
currentState.internalAccounts.selectedAccount = accountId; | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we're not calling setSelectedAccount
here to avoid triggering the "account change" event?
If yes, we should add a comment to explain this, cause this could easily be refactored and since there's no comment, we could make a mistake here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think that changing the account without publishing this event might have some side effects (like for other controllers that listen to this change event).
I'm not sure how to avoid infinite loop with those inter-dependent events, but that's something we might wanna re-visit at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated with comment. Yeah it's a tricky problem. We're just being extra careful not to subscribe and publish to the same controller in each handler atm. Regarding side effects, if another controller relies on account changes, it should subscribe to the state change event and manage its own logic
* | ||
* @param id - The EVM client ID or non-EVM chain ID that changed. | ||
*/ | ||
readonly #handleMultichainNetworkChange = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The handler name is not following the same convention as the others, it should be #handleOnMultichainNetworkDidChange
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
this.update((state) => { | ||
state.selectedMultichainNetworkChainId = nonEvmChainId; | ||
state.isEvmSelected = false; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, we should add a comment to explain why we are not firing any event in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
## Explanation CODEOWNER rules have been added for all packages that are currently missing them: * `example-controllers`: These are examples maintained by the wallet framework team. * `mutlichain-network-controller`: This package has been a collaboration between many teams, but for now the owners have been set to the same as the `network-controller` plus the accounts team (who proposed this controller's creation). We can change this further if appropriate. ## References The `multichain-network-controller` package was added here: #5215 ## Changelog N/A ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've highlighted breaking changes using the "BREAKING" category above as appropriate - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
Explanation
This PR updates both the MultichainNetworkController and AccountsController to handle network switching as well as account switching. The logic handles the following logic:
References
Fixes https://github.com/MetaMask/accounts-planning/issues/804
Changelog
@metamask/accounts-controller
MultichainNetworkController:networkDidChange
to allowed events. This is used to subscribe to thesetActiveNetwork
event from theMultichainNetworkController
and is responsible for updating selected account based on network changes (both EVM and non-EVM).@metamask/multichain-network-controller
NetworkControllerGetStateAction
|NetworkControllerSetActiveNetworkAction
. TheMultichainNetworkController
acts as a proxy for theNetworkController
and will update it based on EVM network changes.AccountsControllerSelectedAccountChangeEvent
to allowed events. This is used to subscribe to theselectedAccountChange
event from theAccountsController
and is responsible for updating active network based on account changes (both EVM and non-EVM).Checklist