-
-
Notifications
You must be signed in to change notification settings - Fork 187
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
[token-detection-controller] Apply recent DetectTokensController
updates
#3923
[token-detection-controller] Apply recent DetectTokensController
updates
#3923
Conversation
bbbea84
to
6be2657
Compare
DetectTokensController
DetectTokensController
e03832d
to
d6e35d1
Compare
d6e35d1
to
7abf52f
Compare
e139f86
to
cd16db6
Compare
DetectTokensController
DetectTokensController
, refactor detectTokens
method
6baa047
to
3425c89
Compare
DetectTokensController
, refactor detectTokens
methodDetectTokensController
updates
0a13346
to
de5043b
Compare
fdd94ce
to
c9d88b6
Compare
} | ||
|
||
for (const tokensSlice of sliceOfTokensToDetect) { | ||
for (const tokensSlice of slicesOfTokensToDetect) { |
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.
Seems like the slices could be queried in parallel as a future improvement? What do you you think?
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 don't see a reason why we couldn't do that, yeah.
const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [ | ||
allTokens, | ||
allDetectedTokens, | ||
allIgnoredTokens, | ||
].map((tokens) => | ||
( | ||
tokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ?? [] | ||
).map((value) => (typeof value === 'string' ? value : value.address)), | ||
); |
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.
TIL that allIgnoredTokens
doesn't match the others 😩
} | ||
|
||
for (const tokensSlice of sliceOfTokensToDetect) { | ||
for (const tokensSlice of slicesOfTokensToDetect) { |
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 don't see a reason why we couldn't do that, yeah.
let ignored; | ||
for (const tokenAddress of Object.keys(balances)) { | ||
if (ignoredTokens.length) { | ||
ignored = ignoredTokens.find( | ||
(ignoredTokenAddress) => | ||
ignoredTokenAddress === toChecksumHexAddress(tokenAddress), | ||
); | ||
} | ||
const caseInsensitiveTokenKey = | ||
findCaseInsensitiveMatch( | ||
Object.keys(tokenListUsed), | ||
tokenAddress, | ||
) ?? ''; | ||
|
||
if (ignored === undefined) { |
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 is so much easier to read! 😮💨
}) => { | ||
mockGetProviderConfig({ | ||
chainId: '0x89', | ||
} as unknown as ProviderConfig); |
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.
👍🏻
…count` action - constructor option `selectedAddress` no longer defaults to ''
…lientId` and passing it to `getBalancesInSingleCall` - See MetaMask/metamask-extension#22898 - Uses `NetworkController:getNetworkConfigurationByNetworkClientId` instead of `NetworkController:getNetworkClientById`
…ed to wrong network, and detection using `chainId` keyed states - See MetaMask/metamask-extension#22814 - See #3914
…ClientIdByChainId`, `getProviderConfig`
Co-authored-by: jiexi <jiexiluan@gmail.com>
eccf79c
to
8a73dde
Compare
…for consistency
…kClientId`, so that the method only relies on the network-controller, not the cached `this.#chainId` that could be stale
8a73dde
to
e9bbf1d
Compare
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.
Looks good!
## Explanation Adds refactors and cosmetic, typing fixes to #3923. - Extracts three methods from `TokenDetectionController`'s `detectTokens` method: - `#getCorrectChainIdAndNetworkClientId` - `#getTokenListAndSlicesOfTokensToDetect` - `#addDetectedTokens` - Maintains distinction between class fields `#selectedAddress`, `#networkClientId` and corresponding parameters used in `detectTokens` and its helper methods, so that `detectTokens` method can be used independently of polling/passive detection. - [Refactor `#getCorrectChainIdAndNetworkClientId`](c75fb3b) to remove `findNetworkClientIdByChainId` which might return inconsistent/unexpected results, and replace it with `getState`, `getNetworkClientById` - [Add missing method return types](5c2e887) - [Type networkClientId as `NetworkClientId`](05be5d2) - [Fix excess properties from legacy token list, define `LegacyToken`, `TokenDetectionMap`](ea4c5b8) - Removes `#chainId` class field. ## References - Closes #1614 - Fixes #3661 - Blocked by (Follows from) #3923 - Blocking #3916 - Blocking #3918 ## Changelog ## 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 --------- Co-authored-by: Brian Bergeron <brian.e.bergeron@gmail.com> Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
…nDetectionController` (#22928) ## **Description** This commit replaces [`DetectTokensController`](https://github.com/MetaMask/metamask-extension/blob/68cc610976485d0071400cb2d4c3ea18cc6b15d9/app/scripts/controllers/detect-tokens.js) with the core repo's [`TokenDetectionController`](https://github.com/MetaMask/core/blob/main/packages/assets-controllers/src/TokenDetectionController.ts). This represents the final step of Shared Libraries' initiative to a) consolidate the core repo's `TokenDetectionController`, the extension's `DetectTokensController`, and relevant mobile patches to `@metamask/assets-controllers`, with the goal of b) migrating both extension and mobile to use the consolidated controller in core. This also represents a full conversion to TypeScript for `DetectTokensController` and its unit tests. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/22928?quickstart=1) ## **Related issues** - Contributes to: - MetaMask/core#700 - MetaMask/core#1812 - Closes: - #23127 - #23322 - Blocked by: - MetaMask/core#3916 - MetaMask/core#3923 - MetaMask/core#4007 (`@metamask/assets-controllers` v26) ## **Manual testing steps** - Check whether issue no. 4 in this comment #23010 (comment) can be reproed in this branch. ## Changelog ### `metamask-extension` - `MetamaskController` class: - Define a `preferencesControllerMessenger` instance which only allows the `PreferencesController:getState` action and `PreferencesController:stateChange` event. - Add a subscription to the preferences-controller observable store, with a listener that publishes a `PreferencesController:stateChange` event. - `PreferencesController`: - Add `messenger` as an optional constructor options object property. - Register a `PreferencesController:getState` action handler. - **BREAKING:** Replace all imports of `toChecksumHexAddress` from `@metamask/controller-utils` with imports from the internal `shared/modules/hexstring-utils` module. - **BREAKING:** Bump `@metamask/assets-controllers` to `^26.0.0`. - Remove patch. - **BREAKING:** Bump `@metamask/accounts-controller` to `^11.0.0`. - Remove unused diff in patch. - **BREAKING:** Bump `@metamask/keyring-controller` to `^13.0.0`. - Remove patch. - **BREAKING:** Remove `@metamask/polling-controller` as a dependency. - Required by `test-yarn-dedupe` CI run. - Bump `@metamask/controller-utils` to `^8.0.4`. ### `TokenDetectionController` (compared to `DetectTokensController`) - **BREAKING:** Inherit from `StaticIntervalPollingController` instead of `StaticIntervalPollingControllerOnly` - Constructor and class fields: - **BREAKING:** Remove `preferences`, `network`, `tokenList`, `tokensController`, `assetsContractController`, `getCurrentSelectedAccount`, `getNetworkClientById` as constructor options, and add required option `getBalancesInSingleCall`. - **BREAKING:** Remove `disableLegacyInterval` class field and constructor option. - `#restartTokenDetection` always resets polling interval to default regardless of whether legacy or new polling is being used. - **BREAKING:** Add a `#disabled` private class field, which blocks all network requests if set to true, and add `disabled` as an optional constructor option, which defaults to 'true' if omitted. - **BREAKING:** Remove `isOpen` class field, and replace by adding `enable`, `disable` public methods. - Add optional constructor option `selectedAddress`. If omitted, its value is populated by calling the `AccountsController:getSelectedAccount` action. - Messenger: - **BREAKING:** Newly subscribe to the `PreferencesController:stateChange`, `AccountsController:selectedAccountChange`, `KeyringController:lock`, `KeyringController:unlock` events. - **BREAKING:** Newly allow messenger actions `AccountsController:getSelectedAccount`, `NetworkController:getNetworkClientById`, `NetworkController:getNetworkConfigurationByNetworkClientId`, `NetworkController:getState`, `KeyringController:getState`, `PreferencesController:getState`, `TokenListController:getState`, `TokensController:getState`, and `TokensController:addDetectedTokens`. - **BREAKING:** `detectTokens` replaces the `detectNewTokens` method. - **BREAKING:** Now expects an options object with optional properties `selectedAddress`, `networkClientId`, removing the `chainId` option. - **BREAKING:** Passes lists of full `Token` types to `TokensController:addDetectedTokens` instead of objects containing only `{ address, decimals, symbol }`. - Processes an arbitrary number of tokens in batches of 1000. - Previously, `detectTokens` was limited to two batches, with the first batch being limited to 1000 tokens. - If the `getBalancesInSingleCall` callback fails, it does not throw an error or exit early, and the method continues processing the next batch of tokens. - **BREAKING:** `#restartTokenDetection` is a private method instead of public. - **BREAKING:** Replace the `getChainIdFromNetworkStore` method with the private method `#getCorrectChainIdAndNetworkClientId`. - **BREAKING:** `#trackMetaMetricsEvents` is a private method instead of protected. - Passes string literals instead of extension shared constants into `_trackMetaMetricsEvent`. ### `TokensController` - **BREAKING:** Newly allows `NetworkController:getNetworkClientById` messenger action. - **BREAKING:** Newly subscribes to `NetworkController:networkDidChange`, `PreferencesController:stateChange`, `TokenListController:stateChange` events. - **BREAKING:** Unsubscribes from `NetworkController:stateChange` event. ## **Screenshots/Recordings** ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've clearly explained what problem this PR is solving and how it is solved. - [x] I've linked related issues - [x] I've included manual testing steps - [ ] I've included screenshots/recordings if applicable - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. - [x] I’ve properly set the pull request status: - [x] In case it's not yet "ready for review", I've set it to "draft". - [x] In case it's "ready for review", I've changed it from "draft" to "non-draft". ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
…nDetectionController` (#22928) ## **Description** This commit replaces [`DetectTokensController`](https://github.com/MetaMask/metamask-extension/blob/68cc610976485d0071400cb2d4c3ea18cc6b15d9/app/scripts/controllers/detect-tokens.js) with the core repo's [`TokenDetectionController`](https://github.com/MetaMask/core/blob/main/packages/assets-controllers/src/TokenDetectionController.ts). This represents the final step of Shared Libraries' initiative to a) consolidate the core repo's `TokenDetectionController`, the extension's `DetectTokensController`, and relevant mobile patches to `@metamask/assets-controllers`, with the goal of b) migrating both extension and mobile to use the consolidated controller in core. This also represents a full conversion to TypeScript for `DetectTokensController` and its unit tests. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/22928?quickstart=1) ## **Related issues** - Contributes to: - MetaMask/core#700 - MetaMask/core#1812 - Closes: - #23127 - #23322 - Blocked by: - MetaMask/core#3916 - MetaMask/core#3923 - MetaMask/core#4007 (`@metamask/assets-controllers` v26) ## **Manual testing steps** - Check whether issue no. 4 in this comment #23010 (comment) can be reproed in this branch. ## Changelog ### `metamask-extension` - `MetamaskController` class: - Define a `preferencesControllerMessenger` instance which only allows the `PreferencesController:getState` action and `PreferencesController:stateChange` event. - Add a subscription to the preferences-controller observable store, with a listener that publishes a `PreferencesController:stateChange` event. - `PreferencesController`: - Add `messenger` as an optional constructor options object property. - Register a `PreferencesController:getState` action handler. - **BREAKING:** Replace all imports of `toChecksumHexAddress` from `@metamask/controller-utils` with imports from the internal `shared/modules/hexstring-utils` module. - **BREAKING:** Bump `@metamask/assets-controllers` to `^26.0.0`. - Remove patch. - **BREAKING:** Bump `@metamask/accounts-controller` to `^11.0.0`. - Remove unused diff in patch. - **BREAKING:** Bump `@metamask/keyring-controller` to `^13.0.0`. - Remove patch. - **BREAKING:** Remove `@metamask/polling-controller` as a dependency. - Required by `test-yarn-dedupe` CI run. - Bump `@metamask/controller-utils` to `^8.0.4`. ### `TokenDetectionController` (compared to `DetectTokensController`) - **BREAKING:** Inherit from `StaticIntervalPollingController` instead of `StaticIntervalPollingControllerOnly` - Constructor and class fields: - **BREAKING:** Remove `preferences`, `network`, `tokenList`, `tokensController`, `assetsContractController`, `getCurrentSelectedAccount`, `getNetworkClientById` as constructor options, and add required option `getBalancesInSingleCall`. - **BREAKING:** Remove `disableLegacyInterval` class field and constructor option. - `#restartTokenDetection` always resets polling interval to default regardless of whether legacy or new polling is being used. - **BREAKING:** Add a `#disabled` private class field, which blocks all network requests if set to true, and add `disabled` as an optional constructor option, which defaults to 'true' if omitted. - **BREAKING:** Remove `isOpen` class field, and replace by adding `enable`, `disable` public methods. - Add optional constructor option `selectedAddress`. If omitted, its value is populated by calling the `AccountsController:getSelectedAccount` action. - Messenger: - **BREAKING:** Newly subscribe to the `PreferencesController:stateChange`, `AccountsController:selectedAccountChange`, `KeyringController:lock`, `KeyringController:unlock` events. - **BREAKING:** Newly allow messenger actions `AccountsController:getSelectedAccount`, `NetworkController:getNetworkClientById`, `NetworkController:getNetworkConfigurationByNetworkClientId`, `NetworkController:getState`, `KeyringController:getState`, `PreferencesController:getState`, `TokenListController:getState`, `TokensController:getState`, and `TokensController:addDetectedTokens`. - **BREAKING:** `detectTokens` replaces the `detectNewTokens` method. - **BREAKING:** Now expects an options object with optional properties `selectedAddress`, `networkClientId`, removing the `chainId` option. - **BREAKING:** Passes lists of full `Token` types to `TokensController:addDetectedTokens` instead of objects containing only `{ address, decimals, symbol }`. - Processes an arbitrary number of tokens in batches of 1000. - Previously, `detectTokens` was limited to two batches, with the first batch being limited to 1000 tokens. - If the `getBalancesInSingleCall` callback fails, it does not throw an error or exit early, and the method continues processing the next batch of tokens. - **BREAKING:** `#restartTokenDetection` is a private method instead of public. - **BREAKING:** Replace the `getChainIdFromNetworkStore` method with the private method `#getCorrectChainIdAndNetworkClientId`. - **BREAKING:** `#trackMetaMetricsEvents` is a private method instead of protected. - Passes string literals instead of extension shared constants into `_trackMetaMetricsEvent`. ### `TokensController` - **BREAKING:** Newly allows `NetworkController:getNetworkClientById` messenger action. - **BREAKING:** Newly subscribes to `NetworkController:networkDidChange`, `PreferencesController:stateChange`, `TokenListController:stateChange` events. - **BREAKING:** Unsubscribes from `NetworkController:stateChange` event. ## **Screenshots/Recordings** ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've clearly explained what problem this PR is solving and how it is solved. - [x] I've linked related issues - [x] I've included manual testing steps - [ ] I've included screenshots/recordings if applicable - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. - [x] I’ve properly set the pull request status: - [x] In case it's not yet "ready for review", I've set it to "draft". - [x] In case it's "ready for review", I've changed it from "draft" to "non-draft". ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
Explanation
As a preparatory step for fully replacing the extension
DetectTokensController
with the consolidated core repoTokenDetectionController
,TokenDetectionController
needs to be updated with changes made to the extensionDetectTokensController
since #1813 was closed.Diff of
DetectTokensController
state5d285f7be5f7be981995dfa725aad97d81cc990a..85cd1c89039e900b452edb704ec37e9ccbd3e76a
#diff-323d0cf464Differences from extension
DetectTokensController
Refactors logic for retrieving
chainId
,networkClientId
intothis.#getCorrectChainIdAndNetworkClientId
getNetworkConfigurationByNetworkClientId
action instead ofgetNetworkClientById
to retrievechainId
.networkClientId
is not supplied to the method, or it's supplied butgetNetworkConfigurationByNetworkClientId
returnsundefined
, findschainId
fromproviderConfig
.detectTokens
replacesdetectNewTokens
detectTokens
accepts options object{ selectedAddress, networkClientId }
instead of{ selectedAddress, chainId, networkClientId }
.getBalancesInSingleCall
fails. Also does not exit early -- continues looping.Token
types toTokensController:addDetectedTokens
instead of objects containing only{ address, decimals, symbol }
.#trackMetaMetricsEvents
is a private method instead of protected._trackMetaMetricsEvent
.References
TokenDetectionController
up-to-date and release new version ofassets-controllers
#3916detectTokens
method #3938Changelog
@metamask/assets-controllers
Checklist