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

feat: cross chain aggregated balance #28456

Merged
merged 91 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
85fe12d
bump asset controllers to 39
bergeron Oct 22, 2024
0f3cd64
update ConfirmTransaction
bergeron Oct 22, 2024
bdf921b
fix useGasFeeEstimates unit test
bergeron Oct 22, 2024
9bc4ecf
fix usePolling tests
bergeron Oct 23, 2024
9b1529b
bump controller utils
bergeron Oct 23, 2024
c8bcc0b
remove patch
bergeron Oct 23, 2024
d1a3782
Merge branch 'develop' into brian/asset-controller-39
bergeron Oct 23, 2024
05fd6ef
Update LavaMoat policies
metamaskbot Oct 23, 2024
9dfdfa8
lint
bergeron Oct 23, 2024
04ea3d6
Merge branch 'brian/asset-controller-39' of github.com:MetaMask/metam…
bergeron Oct 23, 2024
cf66072
Merge branch 'develop' into brian/asset-controller-39
bergeron Oct 24, 2024
785de28
initial multi chain polling for currency and token rates
bergeron Oct 29, 2024
f461767
fix testnets
bergeron Oct 29, 2024
f1da818
only refetch prices on chains whose tokens changed
bergeron Oct 29, 2024
878f407
poll multiple native currencies
bergeron Oct 30, 2024
e8a9d6a
fix test
bergeron Oct 30, 2024
245f8d3
yarn dedupe
bergeron Oct 30, 2024
1afebee
Update LavaMoat policies
metamaskbot Oct 30, 2024
e99e2ef
Merge branch 'develop' into brian/currency-rate-multichain-polling2
bergeron Oct 30, 2024
ca590ec
fix e2e test mocks
bergeron Oct 30, 2024
d2191ac
Merge branch 'develop' of github.com:MetaMask/metamask-extension into…
bergeron Oct 30, 2024
70c0db4
fix e2e test
bergeron Oct 30, 2024
6b7df4d
.
bergeron Oct 30, 2024
4e816c2
lint
bergeron Oct 30, 2024
aaef377
fix e2e test
bergeron Oct 30, 2024
48bff46
Merge branch 'brian/currency-rate-multichain-polling2' of github.com:…
bergeron Oct 31, 2024
0450b04
package.json
bergeron Oct 31, 2024
fdc04ad
Merge branch 'develop' of github.com:MetaMask/metamask-extension into…
bergeron Oct 31, 2024
3ec3574
bump controller preview version
bergeron Oct 31, 2024
dcc8a64
Merge branch 'develop' into brian/multiexchangerate
bergeron Oct 31, 2024
0e7a872
fix: fix lint
sahar-fehri Oct 31, 2024
ea95aca
fix: update js file to tsx
sahar-fehri Oct 31, 2024
3bf7b78
Merge branch 'develop' into brian/multiexchangerate
sahar-fehri Nov 1, 2024
bb1f278
make polling input a chain id
bergeron Nov 1, 2024
14dc84b
Merge branch 'develop' into brian/multiexchangerate
bergeron Nov 1, 2024
ef3ef10
bump to asset controller v42
bergeron Nov 1, 2024
ab6e7cc
.
bergeron Nov 1, 2024
44861d9
Merge branch 'brian/multiexchangerate' of github.com:MetaMask/metamas…
bergeron Nov 1, 2024
0b543e0
Merge branch 'develop' of github.com:MetaMask/metamask-extension into…
bergeron Nov 4, 2024
411fc1c
initial token balances controller
bergeron Nov 4, 2024
c2b6afe
Update metamask-controller.js
bergeron Nov 4, 2024
69404a5
Merge branch 'develop' into brian/token-balances-controller
bergeron Nov 4, 2024
bb1d6bf
cleanup
bergeron Nov 4, 2024
f6e56b3
Merge branch 'brian/token-balances-controller' of github.com:MetaMask…
bergeron Nov 4, 2024
8e752a1
yarn
bergeron Nov 4, 2024
febc7f1
fix typo
bergeron Nov 8, 2024
31303e6
feat: cross-chain aggregated balances and percentages
sahar-fehri Nov 12, 2024
3d19aaa
fix: fix network change error
sahar-fehri Nov 15, 2024
e6e60fd
fix: fix conversion rate
sahar-fehri Nov 15, 2024
e1ea312
fix: refactor
sahar-fehri Nov 15, 2024
14eb579
fix: hook account list item with agg balance cross chains
sahar-fehri Nov 15, 2024
a970af1
fix: merge conflicts
sahar-fehri Nov 18, 2024
25e5a2b
fix: merge conflicts
sahar-fehri Nov 18, 2024
355f908
fix: merge conflicts
sahar-fehri Nov 18, 2024
b218da9
fix: rm comments
sahar-fehri Nov 18, 2024
068ca67
fix: fix cross chain agg balance with network filter
sahar-fehri Nov 18, 2024
a0d0791
fix: fix unit test
sahar-fehri Nov 18, 2024
96acc46
fix: fix unit test
sahar-fehri Nov 18, 2024
c0ce3ca
fix: fix unit test
sahar-fehri Nov 18, 2024
7ae5b8f
fix: fix unit test
sahar-fehri Nov 18, 2024
234cf09
fix: unit test
sahar-fehri Nov 18, 2024
ab32ced
fix: fix unit test
sahar-fehri Nov 18, 2024
e01f04b
fix: fix test
sahar-fehri Nov 18, 2024
df0c3d0
fix: convert to .ts file
sahar-fehri Nov 18, 2024
1e8062d
fix: lint
sahar-fehri Nov 18, 2024
83c7eba
fix: fix
sahar-fehri Nov 18, 2024
302a757
fix: fix e2e fixtures
sahar-fehri Nov 18, 2024
4d7a1ac
fix: fix e2e
sahar-fehri Nov 18, 2024
1520ef4
fix: rm hardcoded value in network filter
sahar-fehri Nov 18, 2024
b212907
fix: fix Sentry e2e
sahar-fehri Nov 18, 2024
3b7f4bf
fix: fix e2e
sahar-fehri Nov 18, 2024
cfaa119
fix: fix e2e and update types
sahar-fehri Nov 19, 2024
47c6e9f
fix: fix unit test
sahar-fehri Nov 19, 2024
5d512e6
fix: fix network filter format and disable network filter when on tes…
sahar-fehri Nov 19, 2024
bfa6b86
fix: lint
sahar-fehri Nov 19, 2024
ac78d0d
Merge branch 'develop' into feat/cross-chain-aggregated-balance
sahar-fehri Nov 19, 2024
f92add6
fix: use getChainIdsToPoll selector
sahar-fehri Nov 19, 2024
decb2f1
fix: fix import
sahar-fehri Nov 19, 2024
1f97c68
fix: fix
sahar-fehri Nov 19, 2024
fa55e4c
fix: refactor usage of getChainIdsToPoll
sahar-fehri Nov 19, 2024
33bcfad
fix: add feature flag for agg percentage overview
sahar-fehri Nov 19, 2024
4cbeb57
fix: feature flag on account list item
sahar-fehri Nov 19, 2024
04505e4
fix: add unit test
sahar-fehri Nov 19, 2024
31a6b36
fix: fix unit test
sahar-fehri Nov 19, 2024
48312b7
fix: add unit test
sahar-fehri Nov 19, 2024
69c9d5b
fix: update popover text
sahar-fehri Nov 19, 2024
69ed10a
fix: fix import
sahar-fehri Nov 19, 2024
30ffad5
Merge branch 'develop' into feat/cross-chain-aggregated-balance
sahar-fehri Nov 19, 2024
0c058aa
fix: rm privacy snapshot updates
sahar-fehri Nov 19, 2024
d380413
fix: add mock for e2e and update privacy snapshot
sahar-fehri Nov 19, 2024
fd49581
Merge branch 'develop' into feat/cross-chain-aggregated-balance
sahar-fehri Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion privacy-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@
"security-alerts.api.cx.metamask.io",
"security-alerts.dev-api.cx.metamask.io",
"sentry.io",
"sepolia.infura.io",
Copy link
Contributor

Choose a reason for hiding this comment

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

we'd prefer to mock all places hitting this. I think we expected #28277 to cover all places and, aren't sure which caller remains.

Copy link
Contributor Author

@sahar-fehri sahar-fehri Nov 20, 2024

Choose a reason for hiding this comment

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

Agree; Inspecting the network tab on the test test/e2e/tests/settings/account-token-list.spec.js; the calls to infura that i see are eth_blockNumber, even though i added a mock for those, it is still requiring the snapshot update; not quite sure what i missed there

"snaps.metamask.io",
"sourcify.dev",
"start.metamask.io",
"static.cx.metamask.io",
"support.metamask.io",
"support.metamask-institutional.io",
"support.metamask.io",
"swap.api.cx.metamask.io",
"test.metamask-phishing.io",
"token.api.cx.metamask.io",
Expand Down
4 changes: 3 additions & 1 deletion test/data/mock-send-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"currentLocale": "en"
},
"metamask": {
"accountsByChainId": {},
"ipfsGateway": "",
"dismissSeedBackUpReminder": false,
"usePhishDetect": true,
Expand Down Expand Up @@ -131,7 +132,8 @@
"preferences": {
"hideZeroBalanceTokens": false,
"showFiatInTestnets": false,
"showTestNetworks": true
"showTestNetworks": true,
"tokenNetworkFilter": {}
},
"seedPhraseBackedUp": null,
"ensResolutionsByAddress": {},
Expand Down
1 change: 1 addition & 0 deletions test/data/mock-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@
"showNativeTokenAsMainBalance": true,
"showTestNetworks": true,
"smartTransactionsOptInStatus": true,
"tokenNetworkFilter": {},
"tokenSortConfig": {
"key": "tokenFiatAmount",
"order": "dsc",
Expand Down
1 change: 1 addition & 0 deletions test/e2e/default-fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) {
sortCallback: 'stringNumeric',
},
shouldShowAggregatedBalancePopover: true,
tokenNetworkFilter: {},
},
selectedAddress: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1',
theme: 'light',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@
"redesignedConfirmationsEnabled": true,
"redesignedTransactionsEnabled": "boolean",
"tokenSortConfig": "object",
"tokenNetworkFilter": "object",
"shouldShowAggregatedBalancePopover": "boolean"
},
"ipfsGateway": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"redesignedConfirmationsEnabled": true,
"redesignedTransactionsEnabled": "boolean",
"tokenSortConfig": "object",
"showMultiRpcModal": "boolean",
"tokenNetworkFilter": "object",
"shouldShowAggregatedBalancePopover": "boolean"
},
"firstTimeFlowType": "import",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@
"showConfirmationAdvancedDetails": false,
"tokenSortConfig": "object",
"showMultiRpcModal": "boolean",
"shouldShowAggregatedBalancePopover": "boolean"
"shouldShowAggregatedBalancePopover": "boolean",
"tokenNetworkFilter": "object"
},
"selectedAddress": "string",
"theme": "light",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
"isRedesignedConfirmationsDeveloperEnabled": "boolean",
"showConfirmationAdvancedDetails": false,
"tokenSortConfig": "object",
"tokenNetworkFilter": "object",
"showMultiRpcModal": "boolean",
"shouldShowAggregatedBalancePopover": "boolean"
},
Expand Down
44 changes: 44 additions & 0 deletions test/e2e/tests/settings/account-token-list.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,38 @@ const {
logInWithBalanceValidation,
unlockWallet,
} = require('../../helpers');
const {
switchToNetworkFlow,
} = require('../../page-objects/flows/network.flow');

const { mockServerJsonRpc } = require('../ppom/mocks/mock-server-json-rpc');
const FixtureBuilder = require('../../fixture-builder');

const infuraSepoliaUrl =
'https://sepolia.infura.io/v3/00000000000000000000000000000000';

async function mockInfura(mockServer) {
await mockServerJsonRpc(mockServer, [
['eth_blockNumber'],
['eth_getBlockByNumber'],
]);
await mockServer
.forPost(infuraSepoliaUrl)
.withJsonBodyIncluding({ method: 'eth_getBalance' })
.thenCallback(() => ({
statusCode: 200,
json: {
jsonrpc: '2.0',
id: '6857940763865360',
result: '0x15af1d78b58c40000',
},
}));
}

async function mockInfuraResponses(mockServer) {
await mockInfura(mockServer);
}

describe('Settings', function () {
it('Should match the value of token list item and account list item for eth conversion', async function () {
await withFixtures(
Expand Down Expand Up @@ -49,6 +78,7 @@ describe('Settings', function () {
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test.fullTitle(),
testSpecificMock: mockInfuraResponses,
},
async ({ driver }) => {
await unlockWallet(driver);
Expand All @@ -63,6 +93,20 @@ describe('Settings', function () {
);
await driver.delay(1000);
assert.equal(await tokenListAmount.getText(), '$42,500.00\nUSD');

// switch to Sepolia
// the account list item used to always show account.balance as long as its EVM network.
// Now we are showing aggregated fiat balance on non testnetworks; but if it is a testnetwork we will show account.balance.
// The current test was running initially on localhost
// which is not a testnetwork resulting in the code trying to calculate the aggregated total fiat balance which shows 0.00$
// If this test switches to mainnet then switches back to localhost; the test will pass because switching to mainnet
// will make the code calculate the aggregate fiat balance on mainnet+Linea mainnet and because this account in this test
// has 42,500.00 native Eth on mainnet then the aggregated total fiat would be 42,500.00. When the user switches back to localhost
// it will show the total that the test is expecting.

// I think we can slightly modify this test to switch to Sepolia network before checking the account List item value
await switchToNetworkFlow(driver, 'Sepolia');

await driver.clickElement('[data-testid="account-menu-icon"]');
const accountTokenValue = await driver.waitForSelector(
'.multichain-account-list-item .multichain-account-list-item__asset',
Expand Down
3 changes: 2 additions & 1 deletion test/integration/data/integration-init-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,8 @@
"smartTransactionsOptInStatus": true,
"petnamesEnabled": false,
"showConfirmationAdvancedDetails": false,
"showMultiRpcModal": false
"showMultiRpcModal": false,
"tokenNetworkFilter": {}
},
"preventPollingOnNetworkRestart": true,
"previousAppVersion": "11.14.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, useState } from 'react';
import React, { useMemo, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { getCurrentNetwork, getPreferences } from '../../../../../selectors';
import {
Expand Down Expand Up @@ -28,6 +28,7 @@ import {
ENVIRONMENT_TYPE_POPUP,
} from '../../../../../../shared/constants/app';
import NetworkFilter from '../network-filter';
import { TEST_CHAINS } from '../../../../../../shared/constants/network';

type AssetListControlBarProps = {
showTokensLinks?: boolean;
Expand All @@ -43,6 +44,9 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
useState(false);

const allNetworksFilterShown = Object.keys(tokenNetworkFilter ?? {}).length;
const isTestNetwork = useMemo(() => {
return (TEST_CHAINS as string[]).includes(currentNetwork.chainId);
}, [currentNetwork.chainId, TEST_CHAINS]);

const windowType = getEnvironmentType();
const isFullScreen =
Expand Down Expand Up @@ -84,6 +88,7 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
className="asset-list-control-bar__button"
onClick={toggleNetworkFilterPopover}
size={ButtonBaseSize.Sm}
disabled={isTestNetwork}
endIconName={IconName.ArrowDown}
backgroundColor={
isNetworkFilterPopoverOpen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { setTokenNetworkFilter } from '../../../../../store/actions';
import {
getCurrentChainId,
getCurrentNetwork,
getIsTestnet,
getPreferences,
getSelectedInternalAccount,
getShouldHideZeroBalanceTokens,
getNetworkConfigurationsByChainId,
getChainIdsToPoll,
} from '../../../../../selectors';
import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { SelectableListItem } from '../sort-control/sort-control';
import { useAccountTotalFiatBalance } from '../../../../../hooks/useAccountTotalFiatBalance';
import { Text } from '../../../../component-library/text/text';
import {
Display,
Expand All @@ -24,6 +23,8 @@ import { Box } from '../../../../component-library/box/box';
import { AvatarNetwork } from '../../../../component-library';
import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display';
import { CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP } from '../../../../../../shared/constants/network';
import { useGetFormattedTokensPerChain } from '../../../../../hooks/useGetFormattedTokensPerChain';
import { useAccountTotalCrossChainFiatBalance } from '../../../../../hooks/useAccountTotalCrossChainFiatBalance';

type SortControlProps = {
handleClose: () => void;
Expand All @@ -36,15 +37,35 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => {
const selectedAccount = useSelector(getSelectedInternalAccount);
const currentNetwork = useSelector(getCurrentNetwork);
const allNetworks = useSelector(getNetworkConfigurationsByChainId);
const isTestnet = useSelector(getIsTestnet);
const { tokenNetworkFilter, showNativeTokenAsMainBalance } =
useSelector(getPreferences);
const { tokenNetworkFilter } = useSelector(getPreferences);
const shouldHideZeroBalanceTokens = useSelector(
getShouldHideZeroBalanceTokens,
);

const allChainIDs = useSelector(getChainIdsToPoll);
const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain(
selectedAccount,
shouldHideZeroBalanceTokens,
true, // true to get formattedTokensWithBalancesPerChain for the current chain
allChainIDs,
);
const { totalFiatBalance: selectedAccountBalance } =
useAccountTotalFiatBalance(selectedAccount, shouldHideZeroBalanceTokens);
useAccountTotalCrossChainFiatBalance(
selectedAccount,
formattedTokensWithBalancesPerChain,
);

const { formattedTokensWithBalancesPerChain: formattedTokensForAllNetworks } =
useGetFormattedTokensPerChain(
selectedAccount,
shouldHideZeroBalanceTokens,
false, // false to get the value for all networks
allChainIDs,
);
const { totalFiatBalance: selectedAccountBalanceForAllNetworks } =
useAccountTotalCrossChainFiatBalance(
selectedAccount,
formattedTokensForAllNetworks,
);

// TODO: fetch balances across networks
// const multiNetworkAccountBalance = useMultichainAccountBalance()
Expand Down Expand Up @@ -78,7 +99,15 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => {
color={TextColor.textDefault}
>
{/* TODO: Should query cross chain account balance */}
$1,000.00

<UserPreferencedCurrencyDisplay
value={selectedAccountBalanceForAllNetworks}
type="PRIMARY"
ethNumberOfDecimals={4}
hideTitle
showFiat
isAggregatedFiatOverviewBalance
/>
</Text>
</Box>
<Box display={Display.Flex}>
Expand Down Expand Up @@ -120,16 +149,19 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => {
>
{t('currentNetwork')}
</Text>
<UserPreferencedCurrencyDisplay
value={selectedAccountBalance}
type="PRIMARY"
ethNumberOfDecimals={4}
hideTitle
shouldCheckShowNativeToken
isAggregatedFiatOverviewBalance={
!showNativeTokenAsMainBalance && !isTestnet
}
/>
<Text
variant={TextVariant.bodySmMedium}
color={TextColor.textAlternative}
>
<UserPreferencedCurrencyDisplay
value={selectedAccountBalance}
type="PRIMARY"
ethNumberOfDecimals={4}
hideTitle
showFiat
isAggregatedFiatOverviewBalance
/>
</Text>
</Box>
<AvatarNetwork
name="Current"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AggregatedPercentageOverviewCrossChains render renders correctly 1`] = `
<div>
<div
class="mm-box mm-box--display-flex"
>
<p
class="mm-box mm-text mm-text--body-md-medium mm-text--ellipsis mm-box--color-success-default"
data-testid="aggregated-value-change"
style="white-space: pre;"
>
+$0.22
</p>
<p
class="mm-box mm-text mm-text--body-md-medium mm-text--ellipsis mm-box--color-success-default"
data-testid="aggregated-percentage-change"
>
(+0.08%)
</p>
</div>
</div>
`;
Loading