Skip to content

Commit

Permalink
feat: token detection polling
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Nov 4, 2024
1 parent 65a1038 commit 75b0332
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 11 deletions.
9 changes: 9 additions & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4013,6 +4013,15 @@ export default class MetamaskController extends EventEmitter {
tokenRatesController,
),

// Token detection polling
tokenDetectionStartPolling: tokenRatesController.startPolling.bind(
tokenDetectionController,
),
tokenDetectionStopPollingByPollingToken:
tokenDetectionController.stopPollingByPollingToken.bind(
tokenDetectionController,
),

// GasFeeController
gasFeeStartPollingByNetworkClientId:
gasFeeController.startPollingByNetworkClientId.bind(gasFeeController),
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@
"attributions:generate": "./development/generate-attributions.sh"
},
"resolutions": {
"@metamask/assets-controllers": "patch:@metamask-previews/[email protected]#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch",
"chokidar": "^3.6.0",
"@metamask/assets-controllers@^41.1.0": "file:../core/packages/assets-controllers",
"gridplus-sdk/elliptic": "^6.5.7",
"gridplus-sdk/secp256k1": "^5.0.1",
"eth-lattice-keyring/@ethereumjs/tx": "^4.2.0",
Expand Down Expand Up @@ -287,7 +287,7 @@
"@metamask/address-book-controller": "^6.0.0",
"@metamask/announcement-controller": "^7.0.0",
"@metamask/approval-controller": "^7.0.0",
"@metamask/assets-controllers": "^41.1.0",
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch",
"@metamask/base-controller": "^7.0.0",
"@metamask/bitcoin-wallet-snap": "^0.8.2",
"@metamask/browser-passworder": "^4.3.0",
Expand Down
13 changes: 13 additions & 0 deletions ui/contexts/tokenDetection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import useTokenDetectionPolling from '../hooks/useTokenDetectionPolling';

export const TokenDetectionProvider = ({ children }) => {
useTokenDetectionPolling();

return <>{children}</>;
};

TokenDetectionProvider.propTypes = {
children: PropTypes.node.isRequired,
};
32 changes: 32 additions & 0 deletions ui/hooks/useTokenDetectionPolling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useSelector } from 'react-redux';
import {
getAllDetectedTokensForSelectedAddress,
getNetworkConfigurationsByChainId,
getUseTokenDetection,
} from '../selectors';
import {
tokenDetectionStartPolling,
tokenDetectionStopPollingByPollingToken,
} from '../store/actions';
import useMultiPolling from './useMultiPolling';

const useTokenDetectionPolling = () => {
const useTokenDetection = useSelector(getUseTokenDetection);
const networkConfigurations = useSelector(getNetworkConfigurationsByChainId);
const chainIds = Object.keys(networkConfigurations);

// Selectors returning state updated by the polling
const detectedTokens = useSelector(getAllDetectedTokensForSelectedAddress);

useMultiPolling({
startPolling: tokenDetectionStartPolling,
stopPollingByPollingToken: tokenDetectionStopPollingByPollingToken,
input: useTokenDetection ? chainIds : [],
});

return {
detectedTokens,
};
};

export default useTokenDetectionPolling;
5 changes: 4 additions & 1 deletion ui/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { MetamaskNotificationsProvider } from '../contexts/metamask-notifications';
import { CurrencyRateProvider } from '../contexts/currencyRate';
import { TokenRatesProvider } from '../contexts/tokenRates';
import { TokenDetectionProvider } from '../contexts/tokenDetection';
import ErrorPage from './error';
import Routes from './routes';

Expand Down Expand Up @@ -53,7 +54,9 @@ class Index extends PureComponent {
<CurrencyRateProvider>
<MetamaskNotificationsProvider>
<TokenRatesProvider>
<Routes />
<TokenDetectionProvider>
<Routes />
</TokenDetectionProvider>
</TokenRatesProvider>
</MetamaskNotificationsProvider>
</CurrencyRateProvider>
Expand Down
30 changes: 30 additions & 0 deletions ui/selectors/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import {
getLedgerTransportType,
isAddressLedger,
getIsUnlocked,
getCompletedOnboarding,
} from '../ducks/metamask/metamask';
import {
getLedgerWebHidConnectedStatus,
Expand Down Expand Up @@ -2230,6 +2231,35 @@ export function getDetectedTokensInCurrentNetwork(state) {
return state.metamask.allDetectedTokens?.[currentChainId]?.[selectedAddress];
}

/**
* To retrieve the list of tokens detected across all chains.
*
* @param {*} state
* @returns list of token objects on all networks
*/
export function getAllDetectedTokensForSelectedAddress(state) {
const completedOnboarding = getCompletedOnboarding(state);

// handle onboarding where selected address is not set yet
if (!completedOnboarding) {
return {};
}

const { address: selectedAddress } = getSelectedInternalAccount(state);

const tokensByChainId = Object.entries(
state.metamask.allDetectedTokens || {},
).reduce((acc, [chainId, chainTokens]) => {
const tokensForAddress = chainTokens[selectedAddress];
if (tokensForAddress) {
acc[chainId] = tokensForAddress;
}
return acc;
}, {});

return tokensByChainId;
}

/**
* To fetch the name of the tokens that are imported from tokens found page
*
Expand Down
32 changes: 32 additions & 0 deletions ui/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4586,6 +4586,38 @@ export async function tokenRatesStopPollingByPollingToken(
await removePollingTokenFromAppState(pollingToken);
}

/**
* Informs the TokenDetectionController that the UI requires token detection polling
*
* @param chainId
* @returns polling token that can be used to stop polling
*/
export async function tokenDetectionStartPolling(
chainId: string,
): Promise<string> {
const pollingToken = await submitRequestToBackground(
'tokenDetectionStartPolling',
[{ chainId }],
);
// todo needed?
await addPollingTokenToAppState(pollingToken);
return pollingToken;
}

/**
*
* @param pollingToken -
*/
export async function tokenDetectionStopPollingByPollingToken(
pollingToken: string,
) {
await submitRequestToBackground('tokenDetectionStopPollingByPollingToken', [
pollingToken,
]);
// todo needed?
await removePollingTokenFromAppState(pollingToken);
}

/**
* Informs the GasFeeController that the UI requires gas fee polling
*
Expand Down
54 changes: 46 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4663,6 +4663,44 @@ __metadata:
languageName: node
linkType: hard

"@metamask-previews/assets-controllers@npm:40.0.0-preview-fa7d96bb":
version: 40.0.0-preview-fa7d96bb
resolution: "@metamask-previews/assets-controllers@npm:40.0.0-preview-fa7d96bb"
dependencies:
"@ethereumjs/util": "npm:^8.1.0"
"@ethersproject/address": "npm:^5.7.0"
"@ethersproject/bignumber": "npm:^5.7.0"
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
"@metamask/abi-utils": "npm:^2.0.3"
"@metamask/base-controller": "npm:^7.0.2"
"@metamask/contract-metadata": "npm:^2.4.0"
"@metamask/controller-utils": "npm:^11.4.1"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/polling-controller": "npm:^12.0.0"
"@metamask/rpc-errors": "npm:^7.0.1"
"@metamask/utils": "npm:^10.0.0"
"@types/bn.js": "npm:^5.1.5"
"@types/uuid": "npm:^8.3.0"
async-mutex: "npm:^0.5.0"
bn.js: "npm:^5.2.1"
cockatiel: "npm:^3.1.2"
immer: "npm:^9.0.6"
lodash: "npm:^4.17.21"
multiformats: "npm:^13.1.0"
single-call-balance-checker-abi: "npm:^1.0.0"
uuid: "npm:^8.3.2"
peerDependencies:
"@metamask/accounts-controller": ^18.0.0
"@metamask/approval-controller": ^7.0.0
"@metamask/keyring-controller": ^17.0.0
"@metamask/network-controller": ^22.0.0
"@metamask/preferences-controller": ^13.0.0
checksum: 10/b4ad08d082770e7947b2c0fce3926ab8776394b15079d8b5c3696bb7bb2db9698192580d895dcb45a6d5497f105576acc4e504987a17c19f541e5ba74b93bb7a
languageName: node
linkType: hard

"@metamask/abi-utils@npm:^2.0.2, @metamask/abi-utils@npm:^2.0.3, @metamask/abi-utils@npm:^2.0.4":
version: 2.0.4
resolution: "@metamask/abi-utils@npm:2.0.4"
Expand Down Expand Up @@ -4772,9 +4810,9 @@ __metadata:
languageName: node
linkType: hard

"@metamask/assets-controllers@file:../core/packages/assets-controllers::locator=metamask-crx%40workspace%3A.":
version: 41.1.0
resolution: "@metamask/assets-controllers@file:../core/packages/assets-controllers#../core/packages/assets-controllers::hash=3227f0&locator=metamask-crx%40workspace%3A."
"@metamask/assets-controllers@patch:@metamask-previews/[email protected]#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch":
version: 40.0.0-preview-fa7d96bb
resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=40.0.0-preview-fa7d96bb&hash=e14ff8"
dependencies:
"@ethereumjs/util": "npm:^8.1.0"
"@ethersproject/address": "npm:^5.7.0"
Expand All @@ -4784,10 +4822,10 @@ __metadata:
"@metamask/abi-utils": "npm:^2.0.3"
"@metamask/base-controller": "npm:^7.0.2"
"@metamask/contract-metadata": "npm:^2.4.0"
"@metamask/controller-utils": "npm:^11.4.2"
"@metamask/controller-utils": "npm:^11.4.1"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/polling-controller": "npm:^12.0.1"
"@metamask/polling-controller": "npm:^12.0.0"
"@metamask/rpc-errors": "npm:^7.0.1"
"@metamask/utils": "npm:^10.0.0"
"@types/bn.js": "npm:^5.1.5"
Expand All @@ -4806,7 +4844,7 @@ __metadata:
"@metamask/keyring-controller": ^17.0.0
"@metamask/network-controller": ^22.0.0
"@metamask/preferences-controller": ^13.0.0
checksum: 10/c512d79394663b4216af79ed6108179cf3dc2d67925e8d429ea6d33693f92a725dd659ca5fa42933cd875f1c86ae4749af6bfbb205aef17e048cee2e8a24b065
checksum: 10/f24fe4a422fe68d3df6473611680459cff1651e1eb6d006b90f2e91a6df5a5588aa101eb5f9b2d30e298c499e8e7c71ef69bb95720df13818f5a032702e73d9f
languageName: node
linkType: hard

Expand Down Expand Up @@ -5886,7 +5924,7 @@ __metadata:
languageName: node
linkType: hard

"@metamask/polling-controller@npm:^12.0.1":
"@metamask/polling-controller@npm:^12.0.0":
version: 12.0.1
resolution: "@metamask/polling-controller@npm:12.0.1"
dependencies:
Expand Down Expand Up @@ -25914,7 +25952,7 @@ __metadata:
"@metamask/announcement-controller": "npm:^7.0.0"
"@metamask/api-specs": "npm:^0.9.3"
"@metamask/approval-controller": "npm:^7.0.0"
"@metamask/assets-controllers": "npm:^41.1.0"
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch"
"@metamask/auto-changelog": "npm:^2.1.0"
"@metamask/base-controller": "npm:^7.0.0"
"@metamask/bitcoin-wallet-snap": "npm:^0.8.2"
Expand Down

0 comments on commit 75b0332

Please sign in to comment.