mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
use safer toChecksum utility (#11117)
This commit is contained in:
parent
9386e3cb03
commit
d9a2165f69
@ -1,8 +1,8 @@
|
|||||||
import punycode from 'punycode/punycode';
|
import punycode from 'punycode/punycode';
|
||||||
import { toChecksumAddress } from 'ethereumjs-util';
|
|
||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { CHAIN_ID_TO_NETWORK_ID_MAP } from '../../../../shared/constants/network';
|
import { CHAIN_ID_TO_NETWORK_ID_MAP } from '../../../../shared/constants/network';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
import Ens from './ens';
|
import Ens from './ens';
|
||||||
|
|
||||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
@ -43,7 +43,7 @@ export default class EnsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reverseResolveAddress(address) {
|
reverseResolveAddress(address) {
|
||||||
return this._reverseResolveAddress(toChecksumAddress(address));
|
return this._reverseResolveAddress(toChecksumHexAddress(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _reverseResolveAddress(address) {
|
async _reverseResolveAddress(address) {
|
||||||
@ -79,7 +79,7 @@ export default class EnsController {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toChecksumAddress(registeredAddress) !== address) {
|
if (toChecksumHexAddress(registeredAddress) !== address) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { normalize as normalizeAddress } from 'eth-sig-util';
|
import { normalize as normalizeAddress } from 'eth-sig-util';
|
||||||
import { toChecksumAddress } from 'ethereumjs-util';
|
|
||||||
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
|
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
|
||||||
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
const fetchWithTimeout = getFetchWithTimeout(30000);
|
const fetchWithTimeout = getFetchWithTimeout(30000);
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ export default class TokenRatesController {
|
|||||||
this._tokens.forEach((token) => {
|
this._tokens.forEach((token) => {
|
||||||
const price =
|
const price =
|
||||||
prices[token.address.toLowerCase()] ||
|
prices[token.address.toLowerCase()] ||
|
||||||
prices[toChecksumAddress(token.address)];
|
prices[toChecksumHexAddress(token.address)];
|
||||||
contractExchangeRates[normalizeAddress(token.address)] = price
|
contractExchangeRates[normalizeAddress(token.address)] = price
|
||||||
? price[nativeCurrency]
|
? price[nativeCurrency]
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -10,7 +10,7 @@ import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager'
|
|||||||
import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware';
|
import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware';
|
||||||
import KeyringController from 'eth-keyring-controller';
|
import KeyringController from 'eth-keyring-controller';
|
||||||
import { Mutex } from 'await-semaphore';
|
import { Mutex } from 'await-semaphore';
|
||||||
import { toChecksumAddress, stripHexPrefix } from 'ethereumjs-util';
|
import { stripHexPrefix } from 'ethereumjs-util';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import TrezorKeyring from 'eth-trezor-keyring';
|
import TrezorKeyring from 'eth-trezor-keyring';
|
||||||
import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring';
|
import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring';
|
||||||
@ -27,6 +27,7 @@ import {
|
|||||||
import { TRANSACTION_STATUSES } from '../../shared/constants/transaction';
|
import { TRANSACTION_STATUSES } from '../../shared/constants/transaction';
|
||||||
import { MAINNET_CHAIN_ID } from '../../shared/constants/network';
|
import { MAINNET_CHAIN_ID } from '../../shared/constants/network';
|
||||||
import { UI_NOTIFICATIONS } from '../../shared/notifications';
|
import { UI_NOTIFICATIONS } from '../../shared/notifications';
|
||||||
|
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
import ComposableObservableStore from './lib/ComposableObservableStore';
|
import ComposableObservableStore from './lib/ComposableObservableStore';
|
||||||
import AccountTracker from './lib/account-tracker';
|
import AccountTracker from './lib/account-tracker';
|
||||||
@ -1123,14 +1124,14 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
// Filter ERC20 tokens
|
// Filter ERC20 tokens
|
||||||
const filteredAccountTokens = {};
|
const filteredAccountTokens = {};
|
||||||
Object.keys(accountTokens).forEach((address) => {
|
Object.keys(accountTokens).forEach((address) => {
|
||||||
const checksummedAddress = toChecksumAddress(address);
|
const checksummedAddress = toChecksumHexAddress(address);
|
||||||
filteredAccountTokens[checksummedAddress] = {};
|
filteredAccountTokens[checksummedAddress] = {};
|
||||||
Object.keys(accountTokens[address]).forEach((chainId) => {
|
Object.keys(accountTokens[address]).forEach((chainId) => {
|
||||||
filteredAccountTokens[checksummedAddress][chainId] =
|
filteredAccountTokens[checksummedAddress][chainId] =
|
||||||
chainId === MAINNET_CHAIN_ID
|
chainId === MAINNET_CHAIN_ID
|
||||||
? accountTokens[address][chainId].filter(
|
? accountTokens[address][chainId].filter(
|
||||||
({ address: tokenAddress }) => {
|
({ address: tokenAddress }) => {
|
||||||
const checksumAddress = toChecksumAddress(tokenAddress);
|
const checksumAddress = toChecksumHexAddress(tokenAddress);
|
||||||
return contractMap[checksumAddress]
|
return contractMap[checksumAddress]
|
||||||
? contractMap[checksumAddress].erc20
|
? contractMap[checksumAddress].erc20
|
||||||
: true;
|
: true;
|
||||||
@ -1167,10 +1168,10 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
const accounts = {
|
const accounts = {
|
||||||
hd: hdAccounts
|
hd: hdAccounts
|
||||||
.filter((item, pos) => hdAccounts.indexOf(item) === pos)
|
.filter((item, pos) => hdAccounts.indexOf(item) === pos)
|
||||||
.map((address) => toChecksumAddress(address)),
|
.map((address) => toChecksumHexAddress(address)),
|
||||||
simpleKeyPair: simpleKeyPairAccounts
|
simpleKeyPair: simpleKeyPairAccounts
|
||||||
.filter((item, pos) => simpleKeyPairAccounts.indexOf(item) === pos)
|
.filter((item, pos) => simpleKeyPairAccounts.indexOf(item) === pos)
|
||||||
.map((address) => toChecksumAddress(address)),
|
.map((address) => toChecksumHexAddress(address)),
|
||||||
ledger: [],
|
ledger: [],
|
||||||
trezor: [],
|
trezor: [],
|
||||||
};
|
};
|
||||||
@ -1180,7 +1181,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
let { transactions } = this.txController.store.getState();
|
let { transactions } = this.txController.store.getState();
|
||||||
// delete tx for other accounts that we're not importing
|
// delete tx for other accounts that we're not importing
|
||||||
transactions = Object.values(transactions).filter((tx) => {
|
transactions = Object.values(transactions).filter((tx) => {
|
||||||
const checksummedTxFrom = toChecksumAddress(tx.txParams.from);
|
const checksummedTxFrom = toChecksumHexAddress(tx.txParams.from);
|
||||||
return accounts.hd.includes(checksummedTxFrom);
|
return accounts.hd.includes(checksummedTxFrom);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { toChecksumAddress } from 'ethereumjs-util';
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
const version = 39;
|
const version = 39;
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ function isOldDai(token = {}) {
|
|||||||
token &&
|
token &&
|
||||||
typeof token === 'object' &&
|
typeof token === 'object' &&
|
||||||
token.symbol === DAI_V1_TOKEN_SYMBOL &&
|
token.symbol === DAI_V1_TOKEN_SYMBOL &&
|
||||||
toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS
|
toChecksumHexAddress(token.address) === DAI_V1_CONTRACT_ADDRESS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
isValidAddress,
|
isValidAddress,
|
||||||
isValidChecksumAddress,
|
isValidChecksumAddress,
|
||||||
addHexPrefix,
|
addHexPrefix,
|
||||||
|
toChecksumAddress,
|
||||||
} from 'ethereumjs-util';
|
} from 'ethereumjs-util';
|
||||||
|
|
||||||
export const BURN_ADDRESS = '0x0000000000000000000000000000000000000000';
|
export const BURN_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
@ -51,3 +52,22 @@ export function isValidHexAddress(
|
|||||||
|
|
||||||
return isValidAddress(addressToCheck);
|
return isValidAddress(addressToCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toChecksumHexAddress(address) {
|
||||||
|
if (!address) {
|
||||||
|
// our internal checksumAddress function that this method replaces would
|
||||||
|
// return an empty string for nullish input. If any direct usages of
|
||||||
|
// ethereumjs-util.toChecksumAddress were called with nullish input it
|
||||||
|
// would have resulted in an error on version 5.1.
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const hexPrefixed = addHexPrefix(address);
|
||||||
|
if (!isHexString(hexPrefixed)) {
|
||||||
|
// Version 5.1 of ethereumjs-utils would have returned '0xY' for input 'y'
|
||||||
|
// but we shouldn't waste effort trying to change case on a clearly invalid
|
||||||
|
// string. Instead just return the hex prefixed original string which most
|
||||||
|
// closely mimics the original behavior.
|
||||||
|
return hexPrefixed;
|
||||||
|
}
|
||||||
|
return toChecksumAddress(addHexPrefix(address));
|
||||||
|
}
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import * as utils from '../../../helpers/utils/util';
|
|
||||||
import Identicon from '../../ui/identicon';
|
import Identicon from '../../ui/identicon';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
import AccountListItem from './account-list-item';
|
import AccountListItem from './account-list-item';
|
||||||
|
|
||||||
|
jest.mock('../../../../shared/modules/hexstring-utils', () => ({
|
||||||
|
toChecksumHexAddress: jest.fn(() => 'mockCheckSumAddress'),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('AccountListItem Component', () => {
|
describe('AccountListItem Component', () => {
|
||||||
let wrapper, propsMethodSpies, checksumAddressStub;
|
let wrapper, propsMethodSpies;
|
||||||
|
|
||||||
describe('render', () => {
|
describe('render', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
checksumAddressStub = sinon
|
|
||||||
.stub(utils, 'checksumAddress')
|
|
||||||
.returns('mockCheckSumAddress');
|
|
||||||
propsMethodSpies = {
|
propsMethodSpies = {
|
||||||
handleClick: sinon.spy(),
|
handleClick: sinon.spy(),
|
||||||
};
|
};
|
||||||
@ -36,7 +37,6 @@ describe('AccountListItem Component', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
propsMethodSpies.handleClick.resetHistory();
|
propsMethodSpies.handleClick.resetHistory();
|
||||||
checksumAddressStub.resetHistory();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
@ -126,9 +126,7 @@ describe('AccountListItem Component', () => {
|
|||||||
expect(
|
expect(
|
||||||
wrapper.find('.account-list-item__account-address').text(),
|
wrapper.find('.account-list-item__account-address').text(),
|
||||||
).toStrictEqual('mockCheckSumAddress');
|
).toStrictEqual('mockCheckSumAddress');
|
||||||
expect(checksumAddressStub.getCall(0).args).toStrictEqual([
|
expect(toChecksumHexAddress).toHaveBeenCalledWith('mockAddress');
|
||||||
'mockAddress',
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not render the account address as a checksumAddress if displayAddress is false', () => {
|
it('should not render the account address as a checksumAddress if displayAddress is false', () => {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { checksumAddress } from '../../../helpers/utils/util';
|
|
||||||
import Identicon from '../../ui/identicon';
|
import Identicon from '../../ui/identicon';
|
||||||
import AccountMismatchWarning from '../../ui/account-mismatch-warning/account-mismatch-warning.component';
|
import AccountMismatchWarning from '../../ui/account-mismatch-warning/account-mismatch-warning.component';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default function AccountListItem({
|
export default function AccountListItem({
|
||||||
account,
|
account,
|
||||||
@ -34,7 +34,7 @@ export default function AccountListItem({
|
|||||||
|
|
||||||
{displayAddress && name && (
|
{displayAddress && name && (
|
||||||
<div className="account-list-item__account-address">
|
<div className="account-list-item__account-address">
|
||||||
{checksumAddress(address)}
|
{toChecksumHexAddress(address)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,10 +4,10 @@ import React, { Component } from 'react';
|
|||||||
|
|
||||||
import { stripHexPrefix } from 'ethereumjs-util';
|
import { stripHexPrefix } from 'ethereumjs-util';
|
||||||
import copyToClipboard from 'copy-to-clipboard';
|
import copyToClipboard from 'copy-to-clipboard';
|
||||||
import { checksumAddress } from '../../../../helpers/utils/util';
|
|
||||||
import ReadOnlyInput from '../../../ui/readonly-input';
|
import ReadOnlyInput from '../../../ui/readonly-input';
|
||||||
import Button from '../../../ui/button';
|
import Button from '../../../ui/button';
|
||||||
import AccountModalContainer from '../account-modal-container';
|
import AccountModalContainer from '../account-modal-container';
|
||||||
|
import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default class ExportPrivateKeyModal extends Component {
|
export default class ExportPrivateKeyModal extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -149,7 +149,7 @@ export default class ExportPrivateKeyModal extends Component {
|
|||||||
<span className="export-private-key-modal__account-name">{name}</span>
|
<span className="export-private-key-modal__account-name">{name}</span>
|
||||||
<ReadOnlyInput
|
<ReadOnlyInput
|
||||||
wrapperClass="ellip-address-wrapper"
|
wrapperClass="ellip-address-wrapper"
|
||||||
value={checksumAddress(address)}
|
value={toChecksumHexAddress(address)}
|
||||||
/>
|
/>
|
||||||
<div className="export-private-key-modal__divider" />
|
<div className="export-private-key-modal__divider" />
|
||||||
<span className="export-private-key-modal__body-title">
|
<span className="export-private-key-modal__body-title">
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import copyToClipboard from 'copy-to-clipboard';
|
import copyToClipboard from 'copy-to-clipboard';
|
||||||
import { shortenAddress, checksumAddress } from '../../../helpers/utils/util';
|
import { shortenAddress } from '../../../helpers/utils/util';
|
||||||
|
|
||||||
import Tooltip from '../../ui/tooltip';
|
import Tooltip from '../../ui/tooltip';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
class SelectedAccount extends Component {
|
class SelectedAccount extends Component {
|
||||||
state = {
|
state = {
|
||||||
@ -32,7 +33,7 @@ class SelectedAccount extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const { t } = this.context;
|
const { t } = this.context;
|
||||||
const { selectedIdentity } = this.props;
|
const { selectedIdentity } = this.props;
|
||||||
const checksummedAddress = checksumAddress(selectedIdentity.address);
|
const checksummedAddress = toChecksumHexAddress(selectedIdentity.address);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="selected-account">
|
<div className="selected-account">
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { checksumAddress } from '../../../helpers/utils/util';
|
|
||||||
import { tryReverseResolveAddress } from '../../../store/actions';
|
import { tryReverseResolveAddress } from '../../../store/actions';
|
||||||
import {
|
import {
|
||||||
getAddressBook,
|
getAddressBook,
|
||||||
getRpcPrefsForCurrentProvider,
|
getRpcPrefsForCurrentProvider,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
import TransactionListItemDetails from './transaction-list-item-details.component';
|
import TransactionListItemDetails from './transaction-list-item-details.component';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
@ -13,7 +13,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
const { recipientAddress, senderAddress } = ownProps;
|
const { recipientAddress, senderAddress } = ownProps;
|
||||||
let recipientEns;
|
let recipientEns;
|
||||||
if (recipientAddress) {
|
if (recipientAddress) {
|
||||||
const address = checksumAddress(recipientAddress);
|
const address = toChecksumHexAddress(recipientAddress);
|
||||||
recipientEns = ensResolutionsByAddress[address] || '';
|
recipientEns = ensResolutionsByAddress[address] || '';
|
||||||
}
|
}
|
||||||
const addressBook = getAddressBook(state);
|
const addressBook = getAddressBook(state);
|
||||||
|
@ -2,9 +2,8 @@ import React, { PureComponent } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import contractMap from '@metamask/contract-metadata';
|
import contractMap from '@metamask/contract-metadata';
|
||||||
import { isHexString, addHexPrefix } from 'ethereumjs-util';
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
import { checksumAddress } from '../../../helpers/utils/util';
|
|
||||||
import Jazzicon from '../jazzicon';
|
import Jazzicon from '../jazzicon';
|
||||||
import BlockieIdenticon from './blockieIdenticon';
|
import BlockieIdenticon from './blockieIdenticon';
|
||||||
|
|
||||||
@ -86,11 +85,9 @@ export default class Identicon extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (address) {
|
if (address) {
|
||||||
const checksummedAddress =
|
const checksummedAddress = toChecksumHexAddress(address);
|
||||||
isHexString(addHexPrefix(address)) &&
|
|
||||||
checksumAddress(addHexPrefix(address));
|
|
||||||
|
|
||||||
if (contractMap[checksummedAddress]?.logo) {
|
if (checksummedAddress && contractMap[checksummedAddress]?.logo) {
|
||||||
return this.renderJazzicon();
|
return this.renderJazzicon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import qrCode from 'qrcode-generator';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { isHexPrefixed } from 'ethereumjs-util';
|
import { isHexPrefixed } from 'ethereumjs-util';
|
||||||
import ReadOnlyInput from '../readonly-input/readonly-input';
|
import ReadOnlyInput from '../readonly-input/readonly-input';
|
||||||
import { checksumAddress } from '../../../helpers/utils/util';
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default connect(mapStateToProps)(QrCodeView);
|
export default connect(mapStateToProps)(QrCodeView);
|
||||||
|
|
||||||
@ -20,9 +20,9 @@ function mapStateToProps(state) {
|
|||||||
function QrCodeView(props) {
|
function QrCodeView(props) {
|
||||||
const { Qr, warning } = props;
|
const { Qr, warning } = props;
|
||||||
const { message, data } = Qr;
|
const { message, data } = Qr;
|
||||||
const address = `${isHexPrefixed(data) ? 'ethereum:' : ''}${checksumAddress(
|
const address = `${
|
||||||
data,
|
isHexPrefixed(data) ? 'ethereum:' : ''
|
||||||
)}`;
|
}${toChecksumHexAddress(data)}`;
|
||||||
const qrImage = qrCode(4, 'M');
|
const qrImage = qrCode(4, 'M');
|
||||||
qrImage.addData(address);
|
qrImage.addData(address);
|
||||||
qrImage.make();
|
qrImage.make();
|
||||||
@ -50,7 +50,7 @@ function QrCodeView(props) {
|
|||||||
<ReadOnlyInput
|
<ReadOnlyInput
|
||||||
wrapperClass="ellip-address-wrapper"
|
wrapperClass="ellip-address-wrapper"
|
||||||
autoFocus
|
autoFocus
|
||||||
value={checksumAddress(data)}
|
value={toChecksumHexAddress(data)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -4,9 +4,10 @@ import classnames from 'classnames';
|
|||||||
import copyToClipboard from 'copy-to-clipboard';
|
import copyToClipboard from 'copy-to-clipboard';
|
||||||
import Tooltip from '../tooltip';
|
import Tooltip from '../tooltip';
|
||||||
import Identicon from '../identicon';
|
import Identicon from '../identicon';
|
||||||
import { checksumAddress, shortenAddress } from '../../../helpers/utils/util';
|
import { shortenAddress } from '../../../helpers/utils/util';
|
||||||
import AccountMismatchWarning from '../account-mismatch-warning/account-mismatch-warning.component';
|
import AccountMismatchWarning from '../account-mismatch-warning/account-mismatch-warning.component';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
import {
|
import {
|
||||||
DEFAULT_VARIANT,
|
DEFAULT_VARIANT,
|
||||||
CARDS_VARIANT,
|
CARDS_VARIANT,
|
||||||
@ -56,7 +57,10 @@ function SenderAddress({
|
|||||||
>
|
>
|
||||||
{!addressOnly && (
|
{!addressOnly && (
|
||||||
<div className="sender-to-recipient__sender-icon">
|
<div className="sender-to-recipient__sender-icon">
|
||||||
<Identicon address={checksumAddress(senderAddress)} diameter={24} />
|
<Identicon
|
||||||
|
address={toChecksumHexAddress(senderAddress)}
|
||||||
|
diameter={24}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -203,8 +207,8 @@ export default function SenderToRecipient({
|
|||||||
warnUserOnAccountMismatch,
|
warnUserOnAccountMismatch,
|
||||||
}) {
|
}) {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const checksummedSenderAddress = checksumAddress(senderAddress);
|
const checksummedSenderAddress = toChecksumHexAddress(senderAddress);
|
||||||
const checksummedRecipientAddress = checksumAddress(recipientAddress);
|
const checksummedRecipientAddress = toChecksumHexAddress(recipientAddress);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('sender-to-recipient', variantHash[variant])}>
|
<div className={classnames('sender-to-recipient', variantHash[variant])}>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import contractMap from '@metamask/contract-metadata';
|
import contractMap from '@metamask/contract-metadata';
|
||||||
import { isHexString, addHexPrefix } from 'ethereumjs-util';
|
import {
|
||||||
import { isValidHexAddress } from '../../../shared/modules/hexstring-utils';
|
isValidHexAddress,
|
||||||
import { checksumAddress } from './util';
|
toChecksumHexAddress,
|
||||||
|
} from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
let iconFactory;
|
let iconFactory;
|
||||||
|
|
||||||
@ -18,11 +19,7 @@ function IconFactory(jazzicon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconFactory.prototype.iconForAddress = function (address, diameter) {
|
IconFactory.prototype.iconForAddress = function (address, diameter) {
|
||||||
let addr = address;
|
const addr = toChecksumHexAddress(address);
|
||||||
|
|
||||||
if (isHexString(addHexPrefix(address))) {
|
|
||||||
addr = checksumAddress(addHexPrefix(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconExistsFor(addr)) {
|
if (iconExistsFor(addr)) {
|
||||||
return imageElFor(addr);
|
return imageElFor(addr);
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
RINKEBY_CHAIN_ID,
|
RINKEBY_CHAIN_ID,
|
||||||
ROPSTEN_CHAIN_ID,
|
ROPSTEN_CHAIN_ID,
|
||||||
} from '../../../shared/constants/network';
|
} from '../../../shared/constants/network';
|
||||||
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
// formatData :: ( date: <Unix Timestamp> ) -> String
|
// formatData :: ( date: <Unix Timestamp> ) -> String
|
||||||
export function formatDate(date, format = "M/d/y 'at' T") {
|
export function formatDate(date, format = "M/d/y 'at' T") {
|
||||||
@ -67,7 +68,7 @@ export function addressSummary(
|
|||||||
if (!address) {
|
if (!address) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
let checked = checksumAddress(address);
|
let checked = toChecksumHexAddress(address);
|
||||||
if (!includeHex) {
|
if (!includeHex) {
|
||||||
checked = ethUtil.stripHexPrefix(checked);
|
checked = ethUtil.stripHexPrefix(checked);
|
||||||
}
|
}
|
||||||
@ -195,18 +196,6 @@ export function exportAsFile(filename, data, type = 'text/csv') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely checksumms a potentially-null address
|
|
||||||
*
|
|
||||||
* @param {string} [address] - address to checksum
|
|
||||||
* @returns {string} checksummed address
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export function checksumAddress(address) {
|
|
||||||
const checksummed = address ? ethUtil.toChecksumAddress(address) : '';
|
|
||||||
return checksummed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortens an Ethereum address for display, preserving the beginning and end.
|
* Shortens an Ethereum address for display, preserving the beginning and end.
|
||||||
* Returns the given address if it is no longer than 10 characters.
|
* Returns the given address if it is no longer than 10 characters.
|
||||||
|
@ -3,7 +3,6 @@ import { useSelector } from 'react-redux';
|
|||||||
import contractMap from '@metamask/contract-metadata';
|
import contractMap from '@metamask/contract-metadata';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { isEqual, shuffle } from 'lodash';
|
import { isEqual, shuffle } from 'lodash';
|
||||||
import { checksumAddress } from '../helpers/utils/util';
|
|
||||||
import { getTokenFiatAmount } from '../helpers/utils/token-util';
|
import { getTokenFiatAmount } from '../helpers/utils/token-util';
|
||||||
import {
|
import {
|
||||||
getTokenExchangeRates,
|
getTokenExchangeRates,
|
||||||
@ -14,6 +13,7 @@ import {
|
|||||||
} from '../selectors';
|
} from '../selectors';
|
||||||
import { getSwapsTokens } from '../ducks/swaps/swaps';
|
import { getSwapsTokens } from '../ducks/swaps/swaps';
|
||||||
import { isSwapsDefaultTokenSymbol } from '../../shared/modules/swaps.utils';
|
import { isSwapsDefaultTokenSymbol } from '../../shared/modules/swaps.utils';
|
||||||
|
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
|
||||||
import { useEqualityCheck } from './useEqualityCheck';
|
import { useEqualityCheck } from './useEqualityCheck';
|
||||||
|
|
||||||
const tokenList = shuffle(
|
const tokenList = shuffle(
|
||||||
@ -58,12 +58,12 @@ export function getRenderableTokenData(
|
|||||||
) || '';
|
) || '';
|
||||||
const usedIconUrl =
|
const usedIconUrl =
|
||||||
iconUrl ||
|
iconUrl ||
|
||||||
(contractMap[checksumAddress(address)] &&
|
(contractMap[toChecksumHexAddress(address)] &&
|
||||||
`images/contract/${contractMap[checksumAddress(address)].logo}`);
|
`images/contract/${contractMap[toChecksumHexAddress(address)].logo}`);
|
||||||
return {
|
return {
|
||||||
...token,
|
...token,
|
||||||
primaryLabel: symbol,
|
primaryLabel: symbol,
|
||||||
secondaryLabel: name || contractMap[checksumAddress(address)]?.name,
|
secondaryLabel: name || contractMap[toChecksumHexAddress(address)]?.name,
|
||||||
rightPrimaryLabel:
|
rightPrimaryLabel:
|
||||||
string && `${new BigNumber(string).round(6).toString()} ${symbol}`,
|
string && `${new BigNumber(string).round(6).toString()} ${symbol}`,
|
||||||
rightSecondaryLabel: formattedFiat,
|
rightSecondaryLabel: formattedFiat,
|
||||||
@ -71,7 +71,7 @@ export function getRenderableTokenData(
|
|||||||
identiconAddress: usedIconUrl ? null : address,
|
identiconAddress: usedIconUrl ? null : address,
|
||||||
balance,
|
balance,
|
||||||
decimals,
|
decimals,
|
||||||
name: name || contractMap[checksumAddress(address)]?.name,
|
name: name || contractMap[toChecksumHexAddress(address)]?.name,
|
||||||
rawFiat,
|
rawFiat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,7 @@ import { getHexGasTotal } from '../../helpers/utils/confirm-tx.util';
|
|||||||
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils';
|
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils';
|
||||||
import { conversionGreaterThan } from '../../helpers/utils/conversion-util';
|
import { conversionGreaterThan } from '../../helpers/utils/conversion-util';
|
||||||
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants';
|
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants';
|
||||||
import {
|
import { shortenAddress, valuesFor } from '../../helpers/utils/util';
|
||||||
checksumAddress,
|
|
||||||
shortenAddress,
|
|
||||||
valuesFor,
|
|
||||||
} from '../../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
getAdvancedInlineGasShown,
|
getAdvancedInlineGasShown,
|
||||||
getCustomNonceValue,
|
getCustomNonceValue,
|
||||||
@ -43,6 +39,7 @@ import {
|
|||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
||||||
import { transactionMatchesNetwork } from '../../../shared/modules/transaction.utils';
|
import { transactionMatchesNetwork } from '../../../shared/modules/transaction.utils';
|
||||||
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
import ConfirmTransactionBase from './confirm-transaction-base.component';
|
import ConfirmTransactionBase from './confirm-transaction-base.component';
|
||||||
|
|
||||||
const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
|
const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
|
||||||
@ -107,9 +104,9 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
const toName =
|
const toName =
|
||||||
identities[toAddress]?.name ||
|
identities[toAddress]?.name ||
|
||||||
casedContractMap[toAddress]?.name ||
|
casedContractMap[toAddress]?.name ||
|
||||||
shortenAddress(checksumAddress(toAddress));
|
shortenAddress(toChecksumHexAddress(toAddress));
|
||||||
|
|
||||||
const checksummedAddress = checksumAddress(toAddress);
|
const checksummedAddress = toChecksumHexAddress(toAddress);
|
||||||
const addressBookObject = addressBook[checksummedAddress];
|
const addressBookObject = addressBook[checksummedAddress];
|
||||||
const toEns = ensResolutionsByAddress[checksummedAddress] || '';
|
const toEns = ensResolutionsByAddress[checksummedAddress] || '';
|
||||||
const toNickname = addressBookObject ? addressBookObject.name : '';
|
const toNickname = addressBookObject ? addressBookObject.name : '';
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { toChecksumAddress } from 'ethereumjs-util';
|
|
||||||
import contractMap from '@metamask/contract-metadata';
|
import contractMap from '@metamask/contract-metadata';
|
||||||
import { isConfusing } from 'unicode-confusables';
|
import { isConfusing } from 'unicode-confusables';
|
||||||
import {
|
import {
|
||||||
@ -19,6 +18,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
isBurnAddress,
|
isBurnAddress,
|
||||||
isValidHexAddress,
|
isValidHexAddress,
|
||||||
|
toChecksumHexAddress,
|
||||||
} from '../../../../../shared/modules/hexstring-utils';
|
} from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export function getToErrorObject(to, sendTokenAddress, chainId) {
|
export function getToErrorObject(to, sendTokenAddress, chainId) {
|
||||||
@ -44,7 +44,8 @@ export function getToWarningObject(to, tokens = [], sendToken = null) {
|
|||||||
let toWarning = null;
|
let toWarning = null;
|
||||||
if (
|
if (
|
||||||
sendToken &&
|
sendToken &&
|
||||||
(toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens))
|
(toChecksumHexAddress(to) in contractMap ||
|
||||||
|
checkExistingAddresses(to, tokens))
|
||||||
) {
|
) {
|
||||||
toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR;
|
toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR;
|
||||||
} else if (isValidDomainName(to) && isConfusing(to)) {
|
} else if (isValidDomainName(to) && isConfusing(to)) {
|
||||||
|
@ -22,6 +22,7 @@ jest.mock('../../../../../shared/modules/hexstring-utils', () => ({
|
|||||||
Boolean(to.match(/^[0xabcdef123456798]+$/u)),
|
Boolean(to.match(/^[0xabcdef123456798]+$/u)),
|
||||||
),
|
),
|
||||||
isBurnAddress: jest.fn(() => false),
|
isBurnAddress: jest.fn(() => false),
|
||||||
|
toChecksumHexAddress: jest.fn((input) => input),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('add-recipient utils', () => {
|
describe('add-recipient utils', () => {
|
||||||
|
@ -2,11 +2,11 @@ import { compose } from 'redux';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { getAddressBookEntry } from '../../../../selectors';
|
import { getAddressBookEntry } from '../../../../selectors';
|
||||||
import { checksumAddress } from '../../../../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
CONTACT_EDIT_ROUTE,
|
CONTACT_EDIT_ROUTE,
|
||||||
CONTACT_LIST_ROUTE,
|
CONTACT_LIST_ROUTE,
|
||||||
} from '../../../../helpers/constants/routes';
|
} from '../../../../helpers/constants/routes';
|
||||||
|
import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils';
|
||||||
import ViewContact from './view-contact.component';
|
import ViewContact from './view-contact.component';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
@ -25,7 +25,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
address: contact ? address : null,
|
address: contact ? address : null,
|
||||||
checkSummedAddress: checksumAddress(address),
|
checkSummedAddress: toChecksumHexAddress(address),
|
||||||
memo,
|
memo,
|
||||||
editRoute: CONTACT_EDIT_ROUTE,
|
editRoute: CONTACT_EDIT_ROUTE,
|
||||||
listRoute: CONTACT_LIST_ROUTE,
|
listRoute: CONTACT_LIST_ROUTE,
|
||||||
|
@ -14,11 +14,7 @@ import {
|
|||||||
ALLOWED_SWAPS_CHAIN_IDS,
|
ALLOWED_SWAPS_CHAIN_IDS,
|
||||||
} from '../../shared/constants/swaps';
|
} from '../../shared/constants/swaps';
|
||||||
|
|
||||||
import {
|
import { shortenAddress, getAccountByAddress } from '../helpers/utils/util';
|
||||||
shortenAddress,
|
|
||||||
checksumAddress,
|
|
||||||
getAccountByAddress,
|
|
||||||
} from '../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
getValueFromWeiHex,
|
getValueFromWeiHex,
|
||||||
hexToDecimal,
|
hexToDecimal,
|
||||||
@ -26,6 +22,7 @@ import {
|
|||||||
|
|
||||||
import { TEMPLATED_CONFIRMATION_MESSAGE_TYPES } from '../pages/confirmation/templates';
|
import { TEMPLATED_CONFIRMATION_MESSAGE_TYPES } from '../pages/confirmation/templates';
|
||||||
|
|
||||||
|
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
|
||||||
import { getNativeCurrency } from './send';
|
import { getNativeCurrency } from './send';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,7 +259,7 @@ export function getAddressBook(state) {
|
|||||||
export function getAddressBookEntry(state, address) {
|
export function getAddressBookEntry(state, address) {
|
||||||
const addressBook = getAddressBook(state);
|
const addressBook = getAddressBook(state);
|
||||||
const entry = addressBook.find(
|
const entry = addressBook.find(
|
||||||
(contact) => contact.address === checksumAddress(address),
|
(contact) => contact.address === toChecksumHexAddress(address),
|
||||||
);
|
);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import pify from 'pify';
|
|||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { capitalize } from 'lodash';
|
import { capitalize } from 'lodash';
|
||||||
import getBuyEthUrl from '../../app/scripts/lib/buy-eth-url';
|
import getBuyEthUrl from '../../app/scripts/lib/buy-eth-url';
|
||||||
import { checksumAddress } from '../helpers/utils/util';
|
|
||||||
import { calcTokenBalance, estimateGasForSend } from '../pages/send/send.utils';
|
import { calcTokenBalance, estimateGasForSend } from '../pages/send/send.utils';
|
||||||
import {
|
import {
|
||||||
fetchLocale,
|
fetchLocale,
|
||||||
@ -24,6 +23,7 @@ import {
|
|||||||
import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-account';
|
import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-account';
|
||||||
import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask';
|
import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask';
|
||||||
import { LISTED_CONTRACT_ADDRESSES } from '../../shared/constants/tokens';
|
import { LISTED_CONTRACT_ADDRESSES } from '../../shared/constants/tokens';
|
||||||
|
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
|
||||||
import * as actionConstants from './actionConstants';
|
import * as actionConstants from './actionConstants';
|
||||||
|
|
||||||
let background = null;
|
let background = null;
|
||||||
@ -1717,7 +1717,7 @@ export function addToAddressBook(recipient, nickname = '', memo = '') {
|
|||||||
let set;
|
let set;
|
||||||
try {
|
try {
|
||||||
set = await promisifiedBackground.setAddressBook(
|
set = await promisifiedBackground.setAddressBook(
|
||||||
checksumAddress(recipient),
|
toChecksumHexAddress(recipient),
|
||||||
nickname,
|
nickname,
|
||||||
chainId,
|
chainId,
|
||||||
memo,
|
memo,
|
||||||
@ -1743,7 +1743,7 @@ export function removeFromAddressBook(chainId, addressToRemove) {
|
|||||||
return async () => {
|
return async () => {
|
||||||
await promisifiedBackground.removeFromAddressBook(
|
await promisifiedBackground.removeFromAddressBook(
|
||||||
chainId,
|
chainId,
|
||||||
checksumAddress(addressToRemove),
|
toChecksumHexAddress(addressToRemove),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user