Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 2 deletions ui/hooks/snaps/useDisplayName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
} from '@metamask/utils';
import { useSelector } from 'react-redux';
import {
getMemoizedAccountName,
getAddressBookEntryByNetwork,
AddressBookMetaMaskState,
AccountsMetaMaskState,
getAccountNameFromState,
} from '../../selectors/snaps';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import { decimalToHex } from '../../../shared/modules/conversion.utils';
Expand Down Expand Up @@ -54,7 +54,7 @@ export const useDisplayName = (

const accountGroupName = accountGroups[0]?.metadata.name;
const accountName = useSelector((state: AccountsMetaMaskState) =>
getMemoizedAccountName(state, parsedAddress),
getAccountNameFromState(state, parsedAddress),
);

const addressBookEntry = useSelector((state: AddressBookMetaMaskState) =>
Expand Down
4 changes: 2 additions & 2 deletions ui/pages/snaps/snap-view/snap-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
getSnapLatestVersion,
getSnapMetadata,
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
getMemoizedMetaMaskInternalAccounts,
getInternalAccounts,
///: END:ONLY_INCLUDE_IF
} from '../../../selectors';
import {
Expand Down Expand Up @@ -73,7 +73,7 @@ function SnapSettings({ snapId, initRemove, resetInitRemove }) {
// eslint-disable-next-line no-unused-vars -- Main build does not use setKeyringAccounts
const [keyringAccounts, setKeyringAccounts] = useState([]);
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
const internalAccounts = useSelector(getMemoizedMetaMaskInternalAccounts);
const internalAccounts = useSelector(getInternalAccounts);
///: END:ONLY_INCLUDE_IF

const connectedSubjects = useSelector((state) =>
Expand Down
15 changes: 6 additions & 9 deletions ui/selectors/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
} from '@metamask/keyring-api';
import { InternalAccount } from '@metamask/keyring-internal-api';
import { AccountsControllerState } from '@metamask/accounts-controller';
import { createSelector } from 'reselect';
import { KnownCaipNamespace, parseCaipChainId } from '@metamask/utils';
import { createDeepEqualSelector } from '../../shared/modules/selectors/util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
Expand Down Expand Up @@ -43,16 +42,14 @@ export function isNonEvmAccount(account: InternalAccount) {
);
}

export const getInternalAccounts = createSelector(
(state: AccountsState) =>
Object.values(state.metamask.internalAccounts.accounts),
(accounts) => accounts,
export const getInternalAccounts = createDeepEqualSelector(
getInternalAccountsObject,
(accounts) => Object.values(accounts),
);

export const getInternalAccountsObject = createSelector(
(state: AccountsState) => state.metamask.internalAccounts.accounts,
(internalAccounts) => internalAccounts,
);
export function getInternalAccountsObject(state: AccountsState) {
return state.metamask.internalAccounts.accounts;
}

export const getMemoizedInternalAccountByAddress = createDeepEqualSelector(
[getInternalAccounts, (_state, address) => address],
Expand Down
46 changes: 28 additions & 18 deletions ui/selectors/multichain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,25 +693,35 @@ export const getMemoizedMultichainNetworkConfigurationsByChainId =
(networkConfigurations) => networkConfigurations,
);

export function getLastSelectedNonEvmAccount(state: MultichainState) {
const nonEvmAccounts = getInternalAccounts(state);
const sortedNonEvmAccounts = nonEvmAccounts
.filter((account) => !isEvmAccountType(account.type))
.sort(
(a, b) => (b.metadata.lastSelected ?? 0) - (a.metadata.lastSelected ?? 0),
);
return sortedNonEvmAccounts.length > 0 ? sortedNonEvmAccounts[0] : undefined;
}
export const getLastSelectedNonEvmAccount = createDeepEqualSelector(
getInternalAccounts,
(nonEvmAccounts) => {
const sortedNonEvmAccounts = nonEvmAccounts
.filter((account) => !isEvmAccountType(account.type))
.sort(
(a, b) =>
(b.metadata.lastSelected ?? 0) - (a.metadata.lastSelected ?? 0),
);
return sortedNonEvmAccounts.length > 0
? sortedNonEvmAccounts[0]
: undefined;
},
);

export function getLastSelectedSolanaAccount(state: MultichainState) {
const nonEvmAccounts = getInternalAccounts(state);
const sortedNonEvmAccounts = nonEvmAccounts
.filter((account) => isSolanaAccount(account))
.sort(
(a, b) => (b.metadata.lastSelected ?? 0) - (a.metadata.lastSelected ?? 0),
);
return sortedNonEvmAccounts.length > 0 ? sortedNonEvmAccounts[0] : undefined;
}
export const getLastSelectedSolanaAccount = createDeepEqualSelector(
getInternalAccounts,
(nonEvmAccounts) => {
const sortedNonEvmAccounts = nonEvmAccounts
.filter((account) => isSolanaAccount(account))
.sort(
(a, b) =>
(b.metadata.lastSelected ?? 0) - (a.metadata.lastSelected ?? 0),
);
return sortedNonEvmAccounts.length > 0
? sortedNonEvmAccounts[0]
: undefined;
},
);

export function getLastSelectedTronAccount(state: MultichainState) {
const nonEvmAccounts = getInternalAccounts(state);
Expand Down
65 changes: 27 additions & 38 deletions ui/selectors/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ export const getMetaMaskAccounts = createDeepEqualSelector(
currentChainId,
chainId,
) =>
Object.values(internalAccounts).reduce((accounts, internalAccount) => {
internalAccounts.reduce((accounts, internalAccount) => {
// TODO: mix in the identity state here as well, consolidating this
// selector with `accountsWithSendEtherInfoSelector`
let account = internalAccount;
Expand Down Expand Up @@ -525,11 +525,11 @@ export function getSelectedAddress(state) {
return getSelectedInternalAccount(state)?.address;
}

export const getInternalAccountByAddress = createSelector(
(state) => state.metamask.internalAccounts.accounts,
export const getInternalAccountByAddress = createDeepEqualSelector(
getInternalAccounts,
(_, address) => address,
(accounts, address) => {
return Object.values(accounts).find((account) =>
return accounts.find((account) =>
isEqualCaseInsensitive(account.address, address),
);
},
Expand Down Expand Up @@ -1204,21 +1204,22 @@ export function getAccountName(accounts, accountAddress) {
return account && account.metadata.name !== '' ? account.metadata.name : '';
}

export function accountsWithSendEtherInfoSelector(state) {
const accounts = getMetaMaskAccounts(state);
const internalAccounts = getInternalAccounts(state);

const accountsWithSendEtherInfo = Object.values(internalAccounts).map(
(internalAccount) => {
return {
...internalAccount,
...accounts[internalAccount.address],
};
},
);
export const accountsWithSendEtherInfoSelector = createDeepEqualSelector(
getMetaMaskAccounts,
getInternalAccounts,
(accounts, internalAccounts) => {
const accountsWithSendEtherInfo = internalAccounts.map(
(internalAccount) => {
return {
...internalAccount,
...accounts[internalAccount.address],
};
},
);

return accountsWithSendEtherInfo;
}
return accountsWithSendEtherInfo;
},
);

export function getAccountsWithLabels(state) {
return getMetaMaskAccountsOrdered(state).map((account) => {
Expand Down Expand Up @@ -2037,17 +2038,6 @@ export function getNativeCurrencyForChain(chainId) {
return CHAIN_ID_TOKEN_IMAGE_MAP[chainId] ?? undefined;
}

/**
* Returns a memoized selector that gets the internal accounts from the Redux store.
*
* @param state - The Redux store state.
* @returns {Array} An array of internal accounts.
*/
export const getMemoizedMetaMaskInternalAccounts = createDeepEqualSelector(
getInternalAccounts,
(internalAccounts) => internalAccounts,
);

export const selectERC20TokensByChain = createDeepEqualSelector(
(state) => state.metamask.tokensChainsCache,
(erc20TokensByChain) => erc20TokensByChain,
Expand Down Expand Up @@ -3596,17 +3586,16 @@ export function getSnapRegistry(state) {
return snapRegistryList;
}

export function getKeyringSnapAccounts(state) {
const internalAccounts = getInternalAccounts(state);

const keyringAccounts = Object.values(internalAccounts).filter(
(internalAccount) => {
export const getKeyringSnapAccounts = createSelector(
getInternalAccounts,
(internalAccounts) => {
const keyringAccounts = internalAccounts.filter((internalAccount) => {
const { keyring } = internalAccount.metadata;
return keyring.type === KeyringType.snap;
},
);
return keyringAccounts;
}
});
return keyringAccounts;
},
);
///: END:ONLY_INCLUDE_IF

export const getSelectedKeyringByIdOrDefault = createSelector(
Expand Down
15 changes: 1 addition & 14 deletions ui/selectors/snaps/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { createSelector } from 'reselect';
import { AccountsControllerState } from '@metamask/accounts-controller';
import { getAccountName } from '../selectors';
import { getInternalAccounts } from '../accounts';
Expand All @@ -18,22 +17,10 @@ export type AccountsMetaMaskState = {
* @param address - The address to get the display name for.
* @returns The account name for the address.
*/
export const getAccountNameFromState = createSelector(
export const getAccountNameFromState = createDeepEqualSelector(
[
getInternalAccounts,
(_state: AccountsMetaMaskState, address: string) => address,
],
getAccountName,
);

/**
* Get the memoized account name for an address.
*
* @param state - The Metamask state for the accounts controller.
* @param address - The address to get the display name for.
* @returns The account name for the address.
*/
export const getMemoizedAccountName = createDeepEqualSelector(
[getAccountNameFromState],
(accountName: string) => accountName,
);
Loading