1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 09:23:21 +01:00

Fix account selectors when balances are missing (#20385)

* Fix account selectors when balances are missing

Some of the account selectors we use would return an empty set of
accounts if the `AccountTracker` state was missing. This resulted in UI
crashes when trying to access the current selected account.

The selectors have been updated to use the `identities` as the source-
of-truth for the full set of accounts. This ensures that even if the
balances are missing, each account will at least be represented by an
empty object.

* Fix unit test

* Fix another unit test

* Fix another unit test

* Fix another unit test

* Fix more unit tests

---------

Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>
This commit is contained in:
Mark Stacey 2023-08-26 00:28:24 -02:30 committed by GitHub
parent c3f907fe4f
commit 3044aa0ebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 27 deletions

View File

@ -61,6 +61,9 @@ const render = ({ txProps, contextProps } = {}) => {
balance: '0x1F4',
},
},
identities: {
'0xAddress': {},
},
selectedAddress: '0xAddress',
featureFlags: { advancedInlineGas: true },
gasFeeEstimates: MOCK_FEE_ESTIMATE,

View File

@ -67,6 +67,9 @@ const renderComponent = ({
balance: '0x176e5b6f173ebe66',
},
},
identities: {
'0xAddress': {},
},
selectedAddress: '0xAddress',
featureFlags: { advancedInlineGas: true },
gasEstimateType: 'fee-market',

View File

@ -41,6 +41,9 @@ const renderComponent = (componentProps) => {
balance: '0x176e5b6f173ebe66',
},
},
identities: {
'0xAddress': {},
},
selectedAddress: '0xAddress',
featureFlags: { advancedInlineGas: true },
},

View File

@ -28,6 +28,9 @@ const render = () => {
balance: '0x176e5b6f173ebe66',
},
},
identities: {
'0xAddress': {},
},
selectedAddress: '0xAddress',
},
});

View File

@ -11,7 +11,7 @@ import withModalProps from '../../../helpers/higher-order-components/with-modal-
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
import { mmiActionsFactory } from '../../../store/institutional/institution-background';
import { setSelectedAddress } from '../../../store/actions';
import { getMetaMaskAccountsRaw } from '../../../selectors';
import { getMetaMaskIdentities } from '../../../selectors';
import {
getMMIAddressFromModalOrAddress,
getCustodyAccountDetails,
@ -42,7 +42,7 @@ const CustodyConfirmLink = ({ hideModal }) => {
const dispatch = useDispatch();
const mmiActions = mmiActionsFactory();
const trackEvent = useContext(MetaMetricsContext);
const mmiAccounts = useSelector(getMetaMaskAccountsRaw);
const mmiAccounts = useSelector(getMetaMaskIdentities);
const address = useSelector(getMMIAddressFromModalOrAddress);
const custodyAccountDetails = useSelector(getCustodyAccountDetails);
const { custodians } = useSelector(getMMIConfiguration);

View File

@ -1598,6 +1598,9 @@ describe('Send Slice', () => {
address: mockAddress1,
},
},
identities: {
[mockAddress1]: {},
},
},
send: {
...getInitialSendStateWithExistingTxState({
@ -2387,7 +2390,9 @@ describe('Send Slice', () => {
addressBook: {
[CHAIN_IDS.GOERLI]: {},
},
identities: {},
identities: {
[mockAddress1]: {},
},
accounts: {
[mockAddress1]: {
address: mockAddress1,
@ -2522,7 +2527,9 @@ describe('Send Slice', () => {
addressBook: {
[CHAIN_IDS.GOERLI]: {},
},
identities: {},
identities: {
[mockAddress1]: {},
},
accounts: {
[mockAddress1]: {
address: mockAddress1,
@ -2705,7 +2712,9 @@ describe('Send Slice', () => {
addressBook: {
[CHAIN_IDS.GOERLI]: {},
},
identities: {},
identities: {
[mockAddress1]: {},
},
accounts: {
[mockAddress1]: {
address: mockAddress1,

View File

@ -290,28 +290,38 @@ export function deprecatedGetCurrentNetworkId(state) {
return state.metamask.networkId ?? 'loading';
}
/**
* Get MetaMask accounts, including account name and balance.
*/
export const getMetaMaskAccounts = createSelector(
getMetaMaskAccountsRaw,
getMetaMaskIdentities,
getMetaMaskAccountBalances,
getMetaMaskCachedBalances,
(currentAccounts, cachedBalances) =>
Object.entries(currentAccounts).reduce(
(selectedAccounts, [accountID, account]) => {
if (account.balance === null || account.balance === undefined) {
return {
...selectedAccounts,
[accountID]: {
...account,
balance: cachedBalances && cachedBalances[accountID],
},
};
}
return {
...selectedAccounts,
[accountID]: account,
(identities, balances, cachedBalances) =>
Object.keys(identities).reduce((accounts, address) => {
// TODO: mix in the identity state here as well, consolidating this
// selector with `accountsWithSendEtherInfoSelector`
let account = {};
if (balances[address]) {
account = {
...account,
...balances[address],
};
},
{},
),
}
if (account.balance === null || account.balance === undefined) {
account = {
...account,
balance: cachedBalances && cachedBalances[address],
};
}
return {
...accounts,
[address]: account,
};
}, {}),
);
export function getSelectedAddress(state) {
@ -334,11 +344,23 @@ export function getMetaMaskKeyrings(state) {
return state.metamask.keyrings;
}
/**
* Get identity state.
*
* @param {object} state - Redux state
* @returns {object} A map of account addresses to identities (which includes the account name)
*/
export function getMetaMaskIdentities(state) {
return state.metamask.identities;
}
export function getMetaMaskAccountsRaw(state) {
/**
* Get account balances state.
*
* @param {object} state - Redux state
* @returns {object} A map of account addresses to account objects (which includes the account balance)
*/
export function getMetaMaskAccountBalances(state) {
return state.metamask.accounts;
}
@ -376,8 +398,8 @@ export const getMetaMaskAccountsConnected = createSelector(
);
export function isBalanceCached(state) {
const selectedAccount = state.metamask.accounts[getSelectedAddress(state)];
const selectedAccountBalance = selectedAccount && selectedAccount.balance;
const selectedAccountBalance =
getMetaMaskAccountBalances(state)[getSelectedAddress(state)]?.balance;
const cachedBalance = getSelectedAccountCachedBalance(state);
return Boolean(!selectedAccountBalance && cachedBalance);

View File

@ -244,6 +244,9 @@ describe('Actions', () => {
'0xAnotherAddress': '0x0',
},
},
identities: {
'0xAnotherAddress': {},
},
}),
);
@ -1942,6 +1945,9 @@ describe('Actions', () => {
balance: '0x0',
},
},
identities: {
'0xFirstAddress': {},
},
cachedBalances: {
'0x1': {
'0xFirstAddress': '0x0',