Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Nov 16, 2024
2 parents 2b93c3c + 8b02ae4 commit 721d9eb
Show file tree
Hide file tree
Showing 21 changed files with 256 additions and 67 deletions.
3 changes: 3 additions & 0 deletions app/scripts/constants/sentry-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ export const SENTRY_BACKGROUND_STATE = {
[AllProperties]: false,
},
},
TokenBalancesController: {
tokenBalances: false,
},
TokenRatesController: {
marketData: false,
},
Expand Down
39 changes: 39 additions & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
CodefiTokenPricesServiceV2,
RatesController,
fetchMultiExchangeRate,
TokenBalancesController,
} from '@metamask/assets-controllers';
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
import { createEngineStream } from '@metamask/json-rpc-middleware-stream';
Expand Down Expand Up @@ -685,6 +686,7 @@ export default class MetamaskController extends EventEmitter {
'AccountsController:selectedEvmAccountChange',
'PreferencesController:stateChange',
'TokenListController:stateChange',
'NetworkController:stateChange',
],
});
this.tokensController = new TokensController({
Expand Down Expand Up @@ -893,6 +895,28 @@ export default class MetamaskController extends EventEmitter {
};
};

const tokenBalancesMessenger = this.controllerMessenger.getRestricted({
name: 'TokenBalancesController',
allowedActions: [
'NetworkController:getState',
'NetworkController:getNetworkClientById',
'TokensController:getState',
'PreferencesController:getState',
'AccountsController:getSelectedAccount',
],
allowedEvents: [
'PreferencesController:stateChange',
'TokensController:stateChange',
'NetworkController:stateChange',
],
});

this.tokenBalancesController = new TokenBalancesController({
messenger: tokenBalancesMessenger,
state: initState.TokenBalancesController,
interval: 30000,
});

const phishingControllerMessenger = this.controllerMessenger.getRestricted({
name: 'PhishingController',
});
Expand Down Expand Up @@ -2413,6 +2437,7 @@ export default class MetamaskController extends EventEmitter {
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
TokensController: this.tokensController,
TokenBalancesController: this.tokenBalancesController,
SmartTransactionsController: this.smartTransactionsController,
NftController: this.nftController,
PhishingController: this.phishingController,
Expand Down Expand Up @@ -2468,6 +2493,7 @@ export default class MetamaskController extends EventEmitter {
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
TokensController: this.tokensController,
TokenBalancesController: this.tokenBalancesController,
SmartTransactionsController: this.smartTransactionsController,
NftController: this.nftController,
SelectedNetworkController: this.selectedNetworkController,
Expand Down Expand Up @@ -3229,6 +3255,7 @@ export default class MetamaskController extends EventEmitter {
nftController,
nftDetectionController,
currencyRateController,
tokenBalancesController,
tokenDetectionController,
ensController,
tokenListController,
Expand Down Expand Up @@ -4047,6 +4074,14 @@ export default class MetamaskController extends EventEmitter {
tokenListStopPollingByPollingToken:
tokenListController.stopPollingByPollingToken.bind(tokenListController),

tokenBalancesStartPolling: tokenBalancesController.startPolling.bind(
tokenBalancesController,
),
tokenBalancesStopPollingByPollingToken:
tokenBalancesController.stopPollingByPollingToken.bind(
tokenBalancesController,
),

// GasFeeController
gasFeeStartPollingByNetworkClientId:
gasFeeController.startPollingByNetworkClientId.bind(gasFeeController),
Expand Down Expand Up @@ -6681,6 +6716,7 @@ export default class MetamaskController extends EventEmitter {
this.tokenRatesController.stopAllPolling();
this.tokenDetectionController.stopAllPolling();
this.tokenListController.stopAllPolling();
this.tokenBalancesController.stopAllPolling();
this.appStateController.clearPollingTokens();
} catch (error) {
console.error(error);
Expand Down Expand Up @@ -6921,6 +6957,9 @@ export default class MetamaskController extends EventEmitter {
await this._createTransactionNotifcation(transactionMeta);
await this._updateNFTOwnership(transactionMeta);
this._trackTransactionFailure(transactionMeta);
await this.tokenBalancesController.updateBalancesByChainId({
chainId: transactionMeta.chainId,
});
}

async _createTransactionNotifcation(transactionMeta) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
"@metamask/address-book-controller": "^6.0.0",
"@metamask/announcement-controller": "^7.0.0",
"@metamask/approval-controller": "^7.0.0",
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@patch%3A@metamask/assets-controllers@npm%253A43.1.1%23~/.yarn/patches/@metamask-assets-controllers-npm-43.1.1-c223d56176.patch%3A%3Aversion=43.1.1&hash=5a94c2#~/.yarn/patches/@metamask-assets-controllers-patch-9e00573eb4.patch",
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@patch%3A@metamask/assets-controllers@npm%253A44.0.0%23~/.yarn/patches/@metamask-assets-controllers-npm-44.0.0-c223d56176.patch%3A%3Aversion=44.0.0&hash=5a94c2#~/.yarn/patches/@metamask-assets-controllers-patch-9e00573eb4.patch",
"@metamask/base-controller": "^7.0.0",
"@metamask/bitcoin-wallet-snap": "^0.8.2",
"@metamask/browser-passworder": "^4.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@
"swapsFeatureFlags": {}
}
},
"TokenBalancesController": {
"tokenBalances": "object"
},
"TokenListController": {
"tokenList": "object",
"tokensChainsCache": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"0xe705": "object",
"0xe708": "object"
},
"tokenBalances": "object",
"preventPollingOnNetworkRestart": false,
"tokens": "object",
"ignoredTokens": "object",
Expand Down
2 changes: 2 additions & 0 deletions ui/components/app/assets/asset-list/asset-list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jest.mock('../../../../hooks/useIsOriginalNativeTokenSymbol', () => {
jest.mock('../../../../store/actions', () => {
return {
getTokenSymbol: jest.fn(),
tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'),
tokenBalancesStopPollingByPollingToken: jest.fn(),
};
});

Expand Down
2 changes: 2 additions & 0 deletions ui/components/app/wallet-overview/btc-overview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jest.mock('../../../store/actions', () => ({
handleSnapRequest: jest.fn(),
sendMultichainTransaction: jest.fn(),
setDefaultHomeActiveTabName: jest.fn(),
tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'),
tokenBalancesStopPollingByPollingToken: jest.fn(),
}));

const PORTOFOLIO_URL = 'https://portfolio.test';
Expand Down
2 changes: 2 additions & 0 deletions ui/components/app/wallet-overview/eth-overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jest.mock('../../../ducks/locale/locale', () => ({

jest.mock('../../../store/actions', () => ({
startNewDraftTransaction: jest.fn(),
tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'),
tokenBalancesStopPollingByPollingToken: jest.fn(),
}));

const mockGetIntlLocale = getIntlLocale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import {
AccountOverviewBtcProps,
} from './account-overview-btc';

jest.mock('../../../store/actions', () => ({
tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'),
tokenBalancesStopPollingByPollingToken: jest.fn(),
}));

const defaultProps: AccountOverviewBtcProps = {
defaultHomeActiveTabName: null,
onTabClick: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import {
AccountOverviewEthProps,
} from './account-overview-eth';

jest.mock('../../../store/actions', () => ({
tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'),
tokenBalancesStopPollingByPollingToken: jest.fn(),
}));

const render = (props: AccountOverviewEthProps) => {
const store = configureStore({
metamask: mockState.metamask,
Expand Down
10 changes: 10 additions & 0 deletions ui/ducks/metamask/metamask.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,16 @@ export const getGasEstimateTypeByChainId = createSelector(
},
);

/**
* Returns the balances of imported and detected tokens across all accounts and chains.
*
* @param {*} state
* @returns { import('@metamask/assets-controllers').TokenBalancesControllerState['tokenBalances']}
*/
export function getTokenBalances(state) {
return state.metamask.tokenBalances;
}

export const getGasFeeEstimatesByChainId = createSelector(
getGasFeeControllerEstimatesByChainId,
getTransactionGasFeeEstimatesByChainId,
Expand Down
7 changes: 4 additions & 3 deletions ui/hooks/useAccountTotalFiatBalance.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { formatCurrency } from '../helpers/utils/confirm-tx.util';
import { getTokenFiatAmount } from '../helpers/utils/token-util';
import { roundToDecimalPlacesRemovingExtraZeroes } from '../helpers/utils/util';
import { useTokenTracker } from './useTokenTracker';
import { useTokenTracker } from './useTokenBalances';

export const useAccountTotalFiatBalance = (
account,
Expand Down Expand Up @@ -54,10 +54,11 @@ export const useAccountTotalFiatBalance = (
const primaryTokenImage = useSelector(getNativeCurrencyImage);
const nativeCurrency = useSelector(getNativeCurrency);

const { loading, tokensWithBalances } = useTokenTracker({
const loading = false;
const { tokensWithBalances } = useTokenTracker({
chainId: currentChainId,
tokens,
address: account?.address,
includeFailedTokens: true,
hideZeroBalanceTokens: shouldHideZeroBalanceTokens,
});

Expand Down
41 changes: 9 additions & 32 deletions ui/hooks/useAccountTotalFiatBalance.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,6 @@ const mockAccount = createMockInternalAccount({
address: '0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da',
});

jest.mock('./useTokenTracker', () => {
return {
useTokenTracker: () => ({
loading: false,
tokensWithBalances: [
{
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
balance: '48573',
balanceError: null,
decimals: 6,
image: undefined,
isERC721: undefined,
string: '0.04857',
symbol: 'USDC',
},
{
address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
symbol: 'YFI',
balance: '1409247882142934',
decimals: 18,
string: '0.001409247882142934',
balanceError: null,
},
],
error: null,
}),
};
});

const renderUseAccountTotalFiatBalance = (address) => {
const state = {
...mockState,
Expand Down Expand Up @@ -78,7 +49,7 @@ const renderUseAccountTotalFiatBalance = (address) => {
},
...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }),

detectedTokens: {
allTokens: {
'0x1': {
'0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da': [
{
Expand All @@ -96,6 +67,14 @@ const renderUseAccountTotalFiatBalance = (address) => {
],
},
},
tokenBalances: {
[mockAccount.address]: {
[CHAIN_IDS.MAINNET]: {
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': '0xBDBD',
'0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e': '0x501B4176A64D6',
},
},
},
},
};

Expand All @@ -122,8 +101,6 @@ describe('useAccountTotalFiatBalance', () => {
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
symbol: 'USDC',
balance: '48573',
image: undefined,
isERC721: undefined,
decimals: 6,
string: 0.04857,
balanceError: null,
Expand Down
28 changes: 13 additions & 15 deletions ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,21 @@ const mockTokenBalances = [
balance: '48573',
balanceError: null,
decimals: 6,
image: undefined,
isERC721: undefined,
string: '0.04857',
string: 0.04857,
symbol: 'USDC',
tokenFiatAmount: '0.05',
},
{
address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
symbol: 'YFI',
balance: '1409247882142934',
decimals: 18,
string: '0.001409247882142934',
string: 0.00141,
balanceError: null,
tokenFiatAmount: '7.52',
},
];

jest.mock('./useTokenTracker', () => {
return {
useTokenTracker: () => ({
loading: false,
tokensWithBalances: mockTokenBalances,
error: null,
}),
};
});

const mockAccount = createMockInternalAccount({
name: 'Account 1',
address: '0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da',
Expand Down Expand Up @@ -104,7 +94,7 @@ const renderUseMultichainAccountTotalFiatBalance = (
},
...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }),

detectedTokens: {
allTokens: {
'0x1': {
'0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da': [
{
Expand All @@ -122,6 +112,14 @@ const renderUseMultichainAccountTotalFiatBalance = (
],
},
},
tokenBalances: {
[mockAccount.address]: {
[CHAIN_IDS.MAINNET]: {
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': '0xBDBD',
'0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e': '0x501B4176A64D6',
},
},
},
},
};

Expand Down
6 changes: 3 additions & 3 deletions ui/hooks/useMultichainAccountTotalFiatBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export const useMultichainAccountTotalFiatBalance = (
tokensWithBalances: {
address: string;
symbol: string;
decimals: string;
isERC721: boolean;
image: string;
decimals: number;
isERC721?: boolean;
image?: string;
}[];
totalWeiBalance?: string;
totalBalance?: string;
Expand Down
Loading

0 comments on commit 721d9eb

Please sign in to comment.