Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ jest.mock('../../../../selectors/currencyRateController', () => ({
}));

jest.mock('ethereumjs-util', () => ({
toChecksumAddress: jest.fn((address) => address),
zeroAddress: jest.fn(() => '0x0000000000000000000000000000000000000000'),
}));

jest.mock('../../../../util/address', () => ({
toChecksumAddress: jest.fn((address) => address),
}));

describe('AggregatedPercentageCrossChains', () => {
const mockStore = configureStore([]);
let store: Store;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import {
FORMATTED_VALUE_PRICE_TEST_ID,
FORMATTED_PERCENTAGE_TEST_ID,
} from './AggregatedPercentage.constants';
import { toChecksumAddress, zeroAddress } from 'ethereumjs-util';
import { zeroAddress } from 'ethereumjs-util';
import { selectTokenMarketData } from '../../../../selectors/tokenRatesController';
import {
MarketDataMapping,
TokensWithBalances,
} from '../../../../components/hooks/useGetFormattedTokensPerChain';
import { getFormattedAmountChange, getPercentageTextColor } from './utils';
import { AggregatedPercentageCrossChainsProps } from './AggregatedPercentageCrossChains.types';
import { toChecksumAddress } from '../../../../util/address';

export const getCalculatedTokenAmount1dAgo = (
tokenFiatBalance: number,
Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/AccountFromToInfoCard/AddressFrom.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { toChecksumAddress } from 'ethereumjs-util';
import React, { useEffect, useState } from 'react';
import { View } from 'react-native';
import { useSelector } from 'react-redux';
Expand All @@ -16,6 +15,7 @@ import {
import {
getLabelTextByAddress,
renderAccountName,
toChecksumAddress,
} from '../../../util/address';
import useAddressBalance from '../../hooks/useAddressBalance/useAddressBalance';
import stylesheet from './AddressFrom.styles';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { CaipChainId, getChecksumAddress, Hex } from '@metamask/utils';
import { CaipChainId, Hex } from '@metamask/utils';
import { TokenI } from '../../../Tokens/types';
import { selectTokensBalances } from '../../../../../selectors/tokenBalancesController';
import {
Expand Down Expand Up @@ -30,6 +30,7 @@ import { renderNumber, renderFiat } from '../../../../../util/number';
import { formatUnits } from 'ethers/lib/utils';
import { BigNumber } from 'ethers';
import { selectAccountsByChainId } from '../../../../../selectors/accountTrackerController';
import { toChecksumAddress } from '../../../../../util/address';

interface CalculateFiatBalancesParams {
assets: TokenI[];
Expand Down Expand Up @@ -90,7 +91,7 @@ export const calculateEvmBalances = ({
// Native EVM token
if (token.isETH || token.isNative) {
const nativeTokenBalanceAtomicHex =
evmAccountsByChainId?.[chainId]?.[getChecksumAddress(selectedAddress)]
evmAccountsByChainId?.[chainId]?.[toChecksumAddress(selectedAddress)]
?.balance || '0x0';
const nativeTokenBalance = formatUnits(
BigNumber.from(nativeTokenBalanceAtomicHex),
Expand All @@ -116,7 +117,7 @@ export const calculateEvmBalances = ({
);
const erc20BalanceAtomicHex =
multiChainTokenBalances?.[token.address as Hex] ||
multiChainTokenBalances?.[getChecksumAddress(token.address as Hex)] ||
multiChainTokenBalances?.[toChecksumAddress(token.address as Hex)] ||
'0x0';

const erc20Balance = formatUnits(
Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/PaymentRequest/AssetList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { fontStyles } from '../../../../styles/common';
import Identicon from '../../Identicon';
import NetworkMainAssetLogo from '../../NetworkMainAssetLogo';
import { useSelector } from 'react-redux';
import { toChecksumAddress } from 'ethereumjs-util';
import { useTheme } from '../../../../util/theme';
import { selectTokenList } from '../../../../selectors/tokenListController';
import { ImportTokenViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/ImportTokenView.selectors';
import { toChecksumAddress } from '../../../../util/address';

// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/TransactionElement/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import {
renderFullAddress,
areAddressesEqual,
toFormattedAddress,
toChecksumAddress,
} from '../../../util/address';
import {
decodeTransferData,
isCollectibleAddress,
getActionKey,
TRANSACTION_TYPES,
} from '../../../util/transactions';
import { toChecksumAddress } from 'ethereumjs-util';
import { swapsUtils } from '@metamask/swaps-controller';
import { isSwapsNativeAsset } from '../Swaps/utils';
import Engine from '../../../core/Engine';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import PropTypes from 'prop-types';
import { getEditableOptions } from '../../../../UI/Navbar';
import StyledButton from '../../../../UI/StyledButton';
import Engine from '../../../../../core/Engine';
import { toChecksumAddress } from 'ethereumjs-util';
import { connect } from 'react-redux';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { strings } from '../../../../../../locales/i18n';
import {
renderShortAddress,
areAddressesEqual,
validateAddressOrENS,
toChecksumAddress,
} from '../../../../../util/address';
import ErrorMessage from '../../../confirmations/legacy/SendFlow/ErrorMessage';
import AntIcon from 'react-native-vector-icons/AntDesign';
Expand Down
5 changes: 2 additions & 3 deletions app/components/Views/confirmations/hooks/useAccountInfo.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { toChecksumAddress } from 'ethereumjs-util';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { Hex } from '@metamask/utils';

import Engine from '../../../../core/Engine';
import useAddressBalance from '../../../../components/hooks/useAddressBalance/useAddressBalance';
import { selectInternalAccounts } from '../../../../selectors/accountsController';
import { renderAccountName } from '../../../../util/address';
import { renderAccountName, toChecksumAddress } from '../../../../util/address';
import { selectCurrentCurrency } from '../../../../selectors/currencyRateController';
import { formatWithThreshold } from '../../../../util/assets';
import I18n from '../../../../../locales/i18n';

const useAccountInfo = (address: string, chainId: Hex) => {
const internalAccounts = useSelector(selectInternalAccounts);
const activeAddress = toChecksumAddress(address);
const activeAddress = toChecksumAddress(address as Hex);
const { addressBalance: accountBalance } = useAddressBalance(
undefined,
address,
Expand Down
7 changes: 5 additions & 2 deletions app/components/Views/confirmations/legacy/Send/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
fromWei,
fromTokenMinimalUnit,
} from '../../../../../util/number';
import { toChecksumAddress } from 'ethereumjs-util';
import { strings } from '../../../../../../locales/i18n';
import { getTransactionOptionsTitle } from '../../../../UI/Navbar';
import { connect } from 'react-redux';
Expand All @@ -36,7 +35,11 @@ import {
generateTransferData,
} from '../../../../../util/transactions';
import Logger from '../../../../../util/Logger';
import { getAddress, areAddressesEqual } from '../../../../../util/address';
import {
getAddress,
areAddressesEqual,
toChecksumAddress,
} from '../../../../../util/address';
import { MAINNET } from '../../../../../constants/network';
import BigNumber from 'bignumber.js';
import { WalletDevice } from '@metamask/transaction-controller';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { Fragment, PureComponent } from 'react';
import { View, ScrollView, Alert, Platform, BackHandler } from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { toChecksumAddress } from 'ethereumjs-util';
import { SafeAreaView } from 'react-native-safe-area-context';
import Icon from 'react-native-vector-icons/FontAwesome';
import AddressList from '../AddressList';
Expand All @@ -21,6 +20,7 @@ import {
isValidHexAddress,
validateAddressOrENS,
areAddressesEqual,
toChecksumAddress,
} from '../../../../../../util/address';
import { getEther, getTicker } from '../../../../../../util/transactions';
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { toChecksumAddress } from 'ethereumjs-util';
import React, { useEffect, useState } from 'react';
import { View } from 'react-native';
import { useSelector } from 'react-redux';
Expand All @@ -12,6 +11,7 @@ import { selectAccountsByChainId } from '../../../../../../selectors/accountTrac
import {
getLabelTextByAddress,
renderAccountName,
toChecksumAddress,
} from '../../../../../../util/address';
import useAddressBalance from '../../../../../hooks/useAddressBalance/useAddressBalance';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import EthereumAddress from '../../../../../../UI/EthereumAddress';
import Engine from '../../../../../../../core/Engine';
import { MetaMetricsEvents } from '../../../../../../../core/Analytics';

import { toChecksumAddress } from 'ethereumjs-util';
import { connect, useSelector } from 'react-redux';
import StyledButton from '../../../../../../UI/StyledButton';
import Text from '../../../../../../../component-library/components/Texts/Text';
Expand All @@ -24,6 +23,7 @@ import { AddNicknameProps } from './types';
import {
validateAddressOrENS,
shouldShowBlockExplorer,
toChecksumAddress,
} from '../../../../../../../util/address';
import ErrorMessage from '../../../SendFlow/ErrorMessage';
import {
Expand Down
7 changes: 3 additions & 4 deletions app/components/hooks/useAccounts/useAccounts.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { KeyringTypes } from '@metamask/keyring-controller';
import { EthScope } from '@metamask/keyring-api';
import { toChecksumAddress } from 'ethereumjs-util';
import useAccounts from './useAccounts';
import { backgroundState } from '../../../util/test/initial-root-state';
import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils';
import { Account } from './useAccounts.types';
import { Hex } from '@metamask/utils';
// eslint-disable-next-line import/no-namespace
import * as networks from '../../../util/networks';
import { toChecksumAddress } from '../../../util/address';

jest.mock('../../../core/Engine', () => ({
getTotalEvmFiatAccountBalance: jest.fn().mockReturnValue({
Expand All @@ -32,7 +31,7 @@ const MOCK_ACCOUNTS = Object.values(
const MOCK_ACCOUNT_1: Account = {
id: MOCK_ACCOUNTS[0].id,
name: 'Account 1',
address: toChecksumAddress(MOCK_ACCOUNTS[0].address) as Hex,
address: toChecksumAddress(MOCK_ACCOUNTS[0].address),
type: KeyringTypes.hd,
yOffset: 0,
isSelected: false,
Expand All @@ -47,7 +46,7 @@ const MOCK_ACCOUNT_1: Account = {
const MOCK_ACCOUNT_2: Account = {
id: MOCK_ACCOUNTS[1].id,
name: 'Account 2',
address: toChecksumAddress(MOCK_ACCOUNTS[1].address) as Hex,
address: toChecksumAddress(MOCK_ACCOUNTS[1].address),
type: KeyringTypes.hd,
yOffset: 78,
isSelected: true,
Expand Down
3 changes: 1 addition & 2 deletions app/components/hooks/useExistingAddress.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { toChecksumAddress } from 'ethereumjs-util';
import { useSelector } from 'react-redux';

import { selectInternalAccounts } from '../../selectors/accountsController';
import { areAddressesEqual } from '../../util/address';
import { areAddressesEqual, toChecksumAddress } from '../../util/address';
import { AddressBookEntry } from '@metamask/address-book-controller';
import { selectAddressBook } from '../../selectors/addressBookController';
import { selectIsEvmNetworkSelected } from '../../selectors/multichainNetworkController';
Expand Down
14 changes: 5 additions & 9 deletions app/selectors/earnController/earn/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ import { selectNetworkConfigurations } from '../../networkController';
import { selectTokensBalances } from '../../tokenBalancesController';
import { selectTokenMarketData } from '../../tokenRatesController';
import { pooledStakingSelectors } from '../pooledStaking';
import { toChecksumAddress } from 'ethereumjs-util';
import {
selectPooledStakingEnabledFlag,
selectStablecoinLendingEnabledFlag,
} from '../../../components/UI/Earn/selectors/featureFlags';
import { EarnTokenDetails } from '../../../components/UI/Earn/types/lending.types';
import { isNonEvmAddress } from '../../../core/Multichain/utils';
import { createDeepEqualSelector } from '../../util';
import { toFormattedAddress } from '../../../util/address';

const selectEarnControllerState = (state: RootState) =>
state.engine.backgroundState.EarnController;
Expand Down Expand Up @@ -157,7 +156,6 @@ const selectEarnTokens = createDeepEqualSelector(
selectLendingMarketsByChainIdAndTokenAddress(earnState);
const lendingMarketsByChainIdAndOutputTokenAddress =
selectLendingMarketsByChainIdAndOutputTokenAddress(earnState);
const isEvmAddress = !isNonEvmAddress(selectedAddress || '');

const earnTokensData = allTokens.reduce((acc, token) => {
const experiences: EarnTokenDetails['experiences'] = [];
Expand Down Expand Up @@ -192,15 +190,13 @@ const selectEarnTokens = createDeepEqualSelector(
}

// TODO: balance logic, extract to utils then use when we are clear to add token
const formattedAddress = toFormattedAddress(selectedAddress as Hex);
const rawAccountBalance = selectedAddress
? accountsByChainId[token?.chainId as Hex]?.[
isEvmAddress ? toChecksumAddress(selectedAddress) : selectedAddress
]?.balance
? accountsByChainId[token?.chainId as Hex]?.[formattedAddress]?.balance
: '0';
const rawStakedAccountBalance = selectedAddress
? accountsByChainId[token?.chainId as Hex]?.[
isEvmAddress ? toChecksumAddress(selectedAddress) : selectedAddress
]?.stakedBalance
? accountsByChainId[token?.chainId as Hex]?.[formattedAddress]
?.stakedBalance
: '0';
const balanceWei = hexToBN(rawAccountBalance);
const stakedBalanceWei = hexToBN(rawStakedAccountBalance);
Expand Down
11 changes: 11 additions & 0 deletions app/util/address/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
renderAccountName,
getTokenDetails,
areAddressesEqual,
toChecksumAddress,
} from '.';
import {
mockHDKeyringAddress,
Expand Down Expand Up @@ -534,6 +535,16 @@ describe('resemblesAddress', () => {
expect(resemblesAddress(mockHDKeyringAddress)).toBeTruthy();
});
});
describe('toChecksumAddress', () => {
it('should return the same address if it is invalid hex string', () => {
expect(toChecksumAddress('0x1')).toBe('0x1');
expect(toChecksumAddress('0x123')).toBe('0x123');
expect(toChecksumAddress('0x1234')).toBe('0x1234');
});
it('should throw an error if address is not a hex string', () => {
expect(() => toChecksumAddress('abc')).toThrow('Invalid hex address.');
});
});
describe('isSnapAccount,', () => {
it('should return true if account is of type Snap Keyring', () => {
expect(isSnapAccount(mockSnapAddress1)).toBeTruthy();
Expand Down
28 changes: 25 additions & 3 deletions app/util/address/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {
toChecksumAddress,
isValidAddress,
addHexPrefix,
isValidChecksumAddress,
isHexPrefixed,
} from 'ethereumjs-util';
import {
getChecksumAddress,
type Hex,
isHexString,
isStrictHexString,
} from '@metamask/utils';
import punycode from 'punycode/punycode';
import ExtendedKeyringTypes from '../../constants/keyringTypes';
import Engine from '../../core/Engine';
Expand Down Expand Up @@ -43,7 +48,6 @@ import type {
NetworkState,
} from '@metamask/network-controller';
import { KeyringTypes } from '@metamask/keyring-controller';
import { type Hex, isHexString } from '@metamask/utils';
import PREINSTALLED_SNAPS from '../../lib/snaps/preinstalled-snaps';
import { EntropySourceId } from '@metamask/keyring-api';

Expand Down Expand Up @@ -478,9 +482,27 @@ export function resemblesAddress(address: string) {
return address && address.length === 2 + 20 * 2;
}

export function toChecksumAddress(address: string) {
try {
return getChecksumAddress(address as Hex);
} catch (error) {
// This is necessary for backward compatibility with the old behavior of
// `ethereumjs-util` which would return the original string if the address
// was invalid. This should happen only in tests which uses invalid addresses
// like 0x1, 0x2 etc.
if (error instanceof Error && error.message === 'Invalid hex address.') {
if (isStrictHexString(address)) {
return address as Hex;
}
throw new Error('Invalid hex address.');
}
throw error;
}
}

export function safeToChecksumAddress(address?: string) {
if (!address) return undefined;
return toChecksumAddress(address) as Hex;
return toChecksumAddress(address);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/util/checkAddress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AddressBookControllerState } from '@metamask/address-book-controller';
import { toChecksumAddress } from 'ethereumjs-util';
import { toChecksumAddress } from './address';

/**
* Check whether the recipient of the given transaction is included in
Expand Down
4 changes: 2 additions & 2 deletions app/util/transactions/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addHexPrefix, toChecksumAddress } from 'ethereumjs-util';
import { addHexPrefix } from 'ethereumjs-util';
import BN from 'bnjs4';
import { rawEncode, rawDecode } from 'ethereumjs-abi';
import BigNumber from 'bignumber.js';
Expand All @@ -17,7 +17,7 @@ import {
import { swapsUtils } from '@metamask/swaps-controller';
import Engine from '../../core/Engine';
import I18n, { strings } from '../../../locales/i18n';
import { safeToChecksumAddress } from '../address';
import { safeToChecksumAddress, toChecksumAddress } from '../address';
import {
balanceToFiatNumber,
BNToHex,
Expand Down
Loading