mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
create safer isValidAddress method (#11089)
This commit is contained in:
parent
761288b18f
commit
8254213b9c
@ -2,12 +2,12 @@ import { strict as assert } from 'assert';
|
|||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import { normalize as normalizeAddress } from 'eth-sig-util';
|
import { normalize as normalizeAddress } from 'eth-sig-util';
|
||||||
import { isValidAddress } from 'ethereumjs-util';
|
|
||||||
import ethers from 'ethers';
|
import ethers from 'ethers';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens';
|
import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens';
|
||||||
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
|
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
|
||||||
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
|
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
|
||||||
|
import { isValidHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
import { NETWORK_EVENTS } from './network';
|
import { NETWORK_EVENTS } from './network';
|
||||||
|
|
||||||
export default class PreferencesController {
|
export default class PreferencesController {
|
||||||
@ -836,7 +836,7 @@ export default class PreferencesController {
|
|||||||
`Invalid decimals "${decimals}": must be 0 <= 36.`,
|
`Invalid decimals "${decimals}": must be 0 <= 36.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!isValidAddress(address)) {
|
if (!isValidHexAddress(address, { allowNonPrefixed: false })) {
|
||||||
throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`);
|
throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { isValidAddress } from 'ethereumjs-util';
|
|
||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import { addHexPrefix } from '../../../lib/util';
|
import { addHexPrefix } from '../../../lib/util';
|
||||||
import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction';
|
import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction';
|
||||||
|
import { isValidHexAddress } from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
const normalizers = {
|
const normalizers = {
|
||||||
from: (from) => addHexPrefix(from),
|
from: (from) => addHexPrefix(from),
|
||||||
@ -110,7 +110,7 @@ export function validateFrom(txParams) {
|
|||||||
`Invalid "from" address "${txParams.from}": not a string.`,
|
`Invalid "from" address "${txParams.from}": not a string.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!isValidAddress(txParams.from)) {
|
if (!isValidHexAddress(txParams.from, { allowNonPrefixed: false })) {
|
||||||
throw ethErrors.rpc.invalidParams('Invalid "from" address.');
|
throw ethErrors.rpc.invalidParams('Invalid "from" address.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +128,10 @@ export function validateRecipient(txParams) {
|
|||||||
} else {
|
} else {
|
||||||
throw ethErrors.rpc.invalidParams('Invalid "to" address.');
|
throw ethErrors.rpc.invalidParams('Invalid "to" address.');
|
||||||
}
|
}
|
||||||
} else if (txParams.to !== undefined && !isValidAddress(txParams.to)) {
|
} else if (
|
||||||
|
txParams.to !== undefined &&
|
||||||
|
!isValidHexAddress(txParams.to, { allowNonPrefixed: false })
|
||||||
|
) {
|
||||||
throw ethErrors.rpc.invalidParams('Invalid "to" address.');
|
throw ethErrors.rpc.invalidParams('Invalid "to" address.');
|
||||||
}
|
}
|
||||||
return txParams;
|
return txParams;
|
||||||
|
@ -3,12 +3,12 @@ import assert from 'assert';
|
|||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util';
|
import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util';
|
||||||
import { isValidAddress } from 'ethereumjs-util';
|
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import jsonschema from 'jsonschema';
|
import jsonschema from 'jsonschema';
|
||||||
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
||||||
import createId from '../../../shared/modules/random-id';
|
import createId from '../../../shared/modules/random-id';
|
||||||
|
import { isValidHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a
|
* Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a
|
||||||
@ -160,7 +160,8 @@ export default class TypedMessageManager extends EventEmitter {
|
|||||||
assert.ok('data' in params, 'Params must include a "data" field.');
|
assert.ok('data' in params, 'Params must include a "data" field.');
|
||||||
assert.ok('from' in params, 'Params must include a "from" field.');
|
assert.ok('from' in params, 'Params must include a "from" field.');
|
||||||
assert.ok(
|
assert.ok(
|
||||||
typeof params.from === 'string' && isValidAddress(params.from),
|
typeof params.from === 'string' &&
|
||||||
|
isValidHexAddress(params.from, { allowNonPrefixed: false }),
|
||||||
'"from" field must be a valid, lowercase, hexadecimal Ethereum address string.',
|
'"from" field must be a valid, lowercase, hexadecimal Ethereum address string.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
53
shared/modules/hexstring-utils.js
Normal file
53
shared/modules/hexstring-utils.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import {
|
||||||
|
isHexString,
|
||||||
|
isValidAddress,
|
||||||
|
isValidChecksumAddress,
|
||||||
|
addHexPrefix,
|
||||||
|
} from 'ethereumjs-util';
|
||||||
|
|
||||||
|
export const BURN_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
|
|
||||||
|
export function isBurnAddress(address) {
|
||||||
|
return address === BURN_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the input is a hex address. This utility method is a thin
|
||||||
|
* wrapper around ethereumjs-util.isValidAddress, with the exception that it
|
||||||
|
* does not throw an error when provided values that are not hex strings. In
|
||||||
|
* addition, and by default, this method will return true for hex strings that
|
||||||
|
* meet the length requirement of a hex address, but are not prefixed with `0x`
|
||||||
|
* Finally, if the mixedCaseUseChecksum flag is true and a mixed case string is
|
||||||
|
* provided this method will validate it has the proper checksum formatting.
|
||||||
|
* @param {string} possibleAddress - Input parameter to check against
|
||||||
|
* @param {Object} [options] - options bag
|
||||||
|
* @param {boolean} [options.allowNonPrefixed] - If true will first ensure '0x'
|
||||||
|
* is prepended to the string
|
||||||
|
* @param {boolean} [options.mixedCaseUseChecksum] - If true will treat mixed
|
||||||
|
* case addresses as checksum addresses and validate that proper checksum
|
||||||
|
* format is used
|
||||||
|
* @returns {boolean} whether or not the input is a valid hex address
|
||||||
|
*/
|
||||||
|
export function isValidHexAddress(
|
||||||
|
possibleAddress,
|
||||||
|
{ allowNonPrefixed = true, mixedCaseUseChecksum = false } = {},
|
||||||
|
) {
|
||||||
|
const addressToCheck = allowNonPrefixed
|
||||||
|
? addHexPrefix(possibleAddress)
|
||||||
|
: possibleAddress;
|
||||||
|
if (!isHexString(addressToCheck)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mixedCaseUseChecksum) {
|
||||||
|
const prefixRemoved = addressToCheck.slice(2);
|
||||||
|
const lower = prefixRemoved.toLowerCase();
|
||||||
|
const upper = prefixRemoved.toUpperCase();
|
||||||
|
const allOneCase = prefixRemoved === lower || prefixRemoved === upper;
|
||||||
|
if (!allOneCase) {
|
||||||
|
return isValidChecksumAddress(addressToCheck);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValidAddress(addressToCheck);
|
||||||
|
}
|
57
shared/modules/hexstring-utils.test.js
Normal file
57
shared/modules/hexstring-utils.test.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { toChecksumAddress } from 'ethereumjs-util';
|
||||||
|
import { isValidHexAddress } from './hexstring-utils';
|
||||||
|
|
||||||
|
describe('hexstring utils', function () {
|
||||||
|
describe('isValidHexAddress', function () {
|
||||||
|
it('should allow 40-char non-prefixed hex', function () {
|
||||||
|
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825';
|
||||||
|
const result = isValidHexAddress(address);
|
||||||
|
assert.equal(result, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow 42-char prefixed hex', function () {
|
||||||
|
const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825';
|
||||||
|
const result = isValidHexAddress(address);
|
||||||
|
assert.equal(result, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT allow 40-char non-prefixed hex when allowNonPrefixed is false', function () {
|
||||||
|
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825';
|
||||||
|
const result = isValidHexAddress(address, { allowNonPrefixed: false });
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT allow any length of non hex-prefixed string', function () {
|
||||||
|
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b85';
|
||||||
|
const result = isValidHexAddress(address);
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT allow less than 42 character hex-prefixed string', function () {
|
||||||
|
const address = '0xfdea65ce26263f6d9a1b5de9555d2931a33b85';
|
||||||
|
const result = isValidHexAddress(address);
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recognize correct capitalized checksum', function () {
|
||||||
|
const address = '0xFDEa65C8e26263F6d9A1B5de9555D2931A33b825';
|
||||||
|
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true });
|
||||||
|
assert.equal(result, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recognize incorrect capitalized checksum', function () {
|
||||||
|
const address = '0xFDea65C8e26263F6d9A1B5de9555D2931A33b825';
|
||||||
|
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true });
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recognize this sample hashed address', function () {
|
||||||
|
const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0';
|
||||||
|
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true });
|
||||||
|
const hashed = toChecksumAddress(address.toLowerCase());
|
||||||
|
assert.equal(hashed, address);
|
||||||
|
assert.equal(result, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -2,8 +2,9 @@ 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 { checksumAddress, isHex } from '../../../helpers/utils/util';
|
import { checksumAddress } from '../../../helpers/utils/util';
|
||||||
import Jazzicon from '../jazzicon';
|
import Jazzicon from '../jazzicon';
|
||||||
import BlockieIdenticon from './blockieIdenticon';
|
import BlockieIdenticon from './blockieIdenticon';
|
||||||
|
|
||||||
@ -85,12 +86,12 @@ export default class Identicon extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (address) {
|
if (address) {
|
||||||
if (isHex(address)) {
|
const checksummedAddress =
|
||||||
const checksummedAddress = checksumAddress(address);
|
isHexString(addHexPrefix(address)) &&
|
||||||
|
checksumAddress(addHexPrefix(address));
|
||||||
|
|
||||||
if (contractMap[checksummedAddress]?.logo) {
|
if (contractMap[checksummedAddress]?.logo) {
|
||||||
return this.renderJazzicon();
|
return this.renderJazzicon();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -38,7 +38,11 @@ describe('Identicon', () => {
|
|||||||
|
|
||||||
it('renders div with address prop', () => {
|
it('renders div with address prop', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Identicon store={store} className="test-address" address="0x0" />,
|
<Identicon
|
||||||
|
store={store}
|
||||||
|
className="test-address"
|
||||||
|
address="0x0000000000000000000000000000000000000000"
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper.find('div.test-address').prop('className')).toStrictEqual(
|
expect(wrapper.find('div.test-address').prop('className')).toStrictEqual(
|
||||||
|
@ -78,20 +78,6 @@ export function addressSummary(
|
|||||||
: '...';
|
: '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidAddress(address) {
|
|
||||||
if (!address || address === '0x0000000000000000000000000000000000000000') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const prefixed = addHexPrefix(address);
|
|
||||||
if (!isHex(prefixed)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
(isAllOneCase(prefixed.slice(2)) && ethUtil.isValidAddress(prefixed)) ||
|
|
||||||
ethUtil.isValidChecksumAddress(prefixed)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidDomainName(address) {
|
export function isValidDomainName(address) {
|
||||||
const match = punycode
|
const match = punycode
|
||||||
.toASCII(address)
|
.toASCII(address)
|
||||||
@ -112,15 +98,6 @@ export function isOriginContractAddress(to, sendTokenAddress) {
|
|||||||
return to.toLowerCase() === sendTokenAddress.toLowerCase();
|
return to.toLowerCase() === sendTokenAddress.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isAllOneCase(address) {
|
|
||||||
if (!address) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const lower = address.toLowerCase();
|
|
||||||
const upper = address.toUpperCase();
|
|
||||||
return address === lower || address === upper;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes wei Hex, returns wei BN, even if input is null
|
// Takes wei Hex, returns wei BN, even if input is null
|
||||||
export function numericBalance(balance) {
|
export function numericBalance(balance) {
|
||||||
if (!balance) {
|
if (!balance) {
|
||||||
@ -182,10 +159,6 @@ export function formatBalance(
|
|||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isHex(str) {
|
|
||||||
return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/u));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getContractAtAddress(tokenAddress) {
|
export function getContractAtAddress(tokenAddress) {
|
||||||
return global.eth.contract(abi).at(tokenAddress);
|
return global.eth.contract(abi).at(tokenAddress);
|
||||||
}
|
}
|
||||||
@ -253,13 +226,6 @@ export function shortenAddress(address = '') {
|
|||||||
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidAddressHead(address) {
|
|
||||||
const addressLengthIsLessThanFull = address.length < 42;
|
|
||||||
const addressIsHex = isHex(address);
|
|
||||||
|
|
||||||
return addressLengthIsLessThanFull && addressIsHex;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAccountByAddress(accounts = [], targetAddress) {
|
export function getAccountByAddress(accounts = [], targetAddress) {
|
||||||
return accounts.find(({ address }) => address === targetAddress);
|
return accounts.find(({ address }) => address === targetAddress);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { BN, toChecksumAddress } from 'ethereumjs-util';
|
import { BN } from 'ethereumjs-util';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
|
|
||||||
describe('util', () => {
|
describe('util', () => {
|
||||||
@ -47,52 +47,6 @@ describe('util', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#isValidAddress', () => {
|
|
||||||
it('should allow 40-char non-prefixed hex', () => {
|
|
||||||
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow 42-char non-prefixed hex', () => {
|
|
||||||
const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not allow less non hex-prefixed', () => {
|
|
||||||
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b85';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not allow less hex-prefixed', () => {
|
|
||||||
const address = '0xfdea65ce26263f6d9a1b5de9555d2931a33b85';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should recognize correct capitalized checksum', () => {
|
|
||||||
const address = '0xFDEa65C8e26263F6d9A1B5de9555D2931A33b825';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should recognize incorrect capitalized checksum', () => {
|
|
||||||
const address = '0xFDea65C8e26263F6d9A1B5de9555D2931A33b825';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
expect(result).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should recognize this sample hashed address', () => {
|
|
||||||
const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0';
|
|
||||||
const result = util.isValidAddress(address);
|
|
||||||
const hashed = toChecksumAddress(address.toLowerCase());
|
|
||||||
expect(hashed).toStrictEqual(address);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isValidDomainName', () => {
|
describe('isValidDomainName', () => {
|
||||||
it('should return true when given a valid domain name', () => {
|
it('should return true when given a valid domain name', () => {
|
||||||
expect(util.isValidDomainName('foo.bar')).toStrictEqual(true);
|
expect(util.isValidDomainName('foo.bar')).toStrictEqual(true);
|
||||||
@ -239,36 +193,6 @@ describe('util', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('normalizing values', function () {
|
describe('normalizing values', function () {
|
||||||
describe('#isHex', function () {
|
|
||||||
it('should return true when given a hex string', function () {
|
|
||||||
const result = util.isHex(
|
|
||||||
'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2',
|
|
||||||
);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given a non-hex string', () => {
|
|
||||||
const result = util.isHex(
|
|
||||||
'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714imnotreal',
|
|
||||||
);
|
|
||||||
expect(result).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given a string containing a non letter/number character', () => {
|
|
||||||
const result = util.isHex(
|
|
||||||
'c3ab8ff13720!8ad9047dd39466b3c%8974e592c2fa383d4a396071imnotreal',
|
|
||||||
);
|
|
||||||
expect(result).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true when given a hex string with hex-prefix', () => {
|
|
||||||
const result = util.isHex(
|
|
||||||
'0xc3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2',
|
|
||||||
);
|
|
||||||
expect(result).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#getRandomFileName', () => {
|
describe('#getRandomFileName', () => {
|
||||||
it('should only return a string containing alphanumeric characters', () => {
|
it('should only return a string containing alphanumeric characters', () => {
|
||||||
const result = util.getRandomFileName();
|
const result = util.getRandomFileName();
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import { checkExistingAddresses } from '../../helpers/utils/util';
|
||||||
checkExistingAddresses,
|
|
||||||
isValidAddress,
|
|
||||||
} from '../../helpers/utils/util';
|
|
||||||
import { tokenInfoGetter } from '../../helpers/utils/token-util';
|
import { tokenInfoGetter } from '../../helpers/utils/token-util';
|
||||||
import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes';
|
import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes';
|
||||||
import TextField from '../../components/ui/text-field';
|
import TextField from '../../components/ui/text-field';
|
||||||
import PageContainer from '../../components/ui/page-container';
|
import PageContainer from '../../components/ui/page-container';
|
||||||
import { Tabs, Tab } from '../../components/ui/tabs';
|
import { Tabs, Tab } from '../../components/ui/tabs';
|
||||||
import { addHexPrefix } from '../../../../app/scripts/lib/util';
|
import { addHexPrefix } from '../../../../app/scripts/lib/util';
|
||||||
|
import { isValidHexAddress } from '../../../../shared/modules/hexstring-utils';
|
||||||
import TokenList from './token-list';
|
import TokenList from './token-list';
|
||||||
import TokenSearch from './token-search';
|
import TokenSearch from './token-search';
|
||||||
|
|
||||||
@ -167,7 +165,9 @@ class AddToken extends Component {
|
|||||||
autoFilled: false,
|
autoFilled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const addressIsValid = isValidAddress(customAddress);
|
const addressIsValid = isValidHexAddress(customAddress, {
|
||||||
|
allowNonPrefixed: false,
|
||||||
|
});
|
||||||
const standardAddress = addHexPrefix(customAddress).toLowerCase();
|
const standardAddress = addHexPrefix(customAddress).toLowerCase();
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
|
@ -2,13 +2,16 @@ import React, { Component } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import Identicon from '../../../../components/ui/identicon';
|
import Identicon from '../../../../components/ui/identicon';
|
||||||
import { isValidAddress } from '../../../../helpers/utils/util';
|
|
||||||
import Dialog from '../../../../components/ui/dialog';
|
import Dialog from '../../../../components/ui/dialog';
|
||||||
import ContactList from '../../../../components/app/contact-list';
|
import ContactList from '../../../../components/app/contact-list';
|
||||||
import RecipientGroup from '../../../../components/app/contact-list/recipient-group/recipient-group.component';
|
import RecipientGroup from '../../../../components/app/contact-list/recipient-group/recipient-group.component';
|
||||||
import { ellipsify } from '../../send.utils';
|
import { ellipsify } from '../../send.utils';
|
||||||
import Button from '../../../../components/ui/button';
|
import Button from '../../../../components/ui/button';
|
||||||
import Confusable from '../../../../components/ui/confusable';
|
import Confusable from '../../../../components/ui/confusable';
|
||||||
|
import {
|
||||||
|
isBurnAddress,
|
||||||
|
isValidHexAddress,
|
||||||
|
} from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default class AddRecipient extends Component {
|
export default class AddRecipient extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -101,7 +104,10 @@ export default class AddRecipient extends Component {
|
|||||||
|
|
||||||
let content;
|
let content;
|
||||||
|
|
||||||
if (isValidAddress(query)) {
|
if (
|
||||||
|
!isBurnAddress(query) &&
|
||||||
|
isValidHexAddress(query, { mixedCaseUseChecksum: true })
|
||||||
|
) {
|
||||||
content = this.renderExplicitAddress(query);
|
content = this.renderExplicitAddress(query);
|
||||||
} else if (ensResolution) {
|
} else if (ensResolution) {
|
||||||
content = this.renderExplicitAddress(
|
content = this.renderExplicitAddress(
|
||||||
|
@ -11,18 +11,25 @@ import {
|
|||||||
} from '../../send.constants';
|
} from '../../send.constants';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isValidAddress,
|
|
||||||
checkExistingAddresses,
|
checkExistingAddresses,
|
||||||
isValidDomainName,
|
isValidDomainName,
|
||||||
isOriginContractAddress,
|
isOriginContractAddress,
|
||||||
isDefaultMetaMaskChain,
|
isDefaultMetaMaskChain,
|
||||||
} from '../../../../helpers/utils/util';
|
} from '../../../../helpers/utils/util';
|
||||||
|
import {
|
||||||
|
isBurnAddress,
|
||||||
|
isValidHexAddress,
|
||||||
|
} from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export function getToErrorObject(to, sendTokenAddress, chainId) {
|
export function getToErrorObject(to, sendTokenAddress, chainId) {
|
||||||
let toError = null;
|
let toError = null;
|
||||||
if (!to) {
|
if (!to) {
|
||||||
toError = REQUIRED_ERROR;
|
toError = REQUIRED_ERROR;
|
||||||
} else if (!isValidAddress(to) && !isValidDomainName(to)) {
|
} else if (
|
||||||
|
isBurnAddress(to) ||
|
||||||
|
(!isValidHexAddress(to, { mixedCaseUseChecksum: true }) &&
|
||||||
|
!isValidDomainName(to))
|
||||||
|
) {
|
||||||
toError = isDefaultMetaMaskChain(chainId)
|
toError = isDefaultMetaMaskChain(chainId)
|
||||||
? INVALID_RECIPIENT_ADDRESS_ERROR
|
? INVALID_RECIPIENT_ADDRESS_ERROR
|
||||||
: INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR;
|
: INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR;
|
||||||
|
@ -11,7 +11,6 @@ jest.mock('../../../../../app/helpers/utils/util', () => ({
|
|||||||
isDefaultMetaMaskChain: jest.fn().mockReturnValue(true),
|
isDefaultMetaMaskChain: jest.fn().mockReturnValue(true),
|
||||||
isEthNetwork: jest.fn().mockReturnValue(true),
|
isEthNetwork: jest.fn().mockReturnValue(true),
|
||||||
checkExistingAddresses: jest.fn().mockReturnValue(true),
|
checkExistingAddresses: jest.fn().mockReturnValue(true),
|
||||||
isValidAddress: jest.fn((to) => Boolean(to.match(/^[0xabcdef123456798]+$/u))),
|
|
||||||
isValidDomainName: jest.requireActual('../../../../../app/helpers/utils/util')
|
isValidDomainName: jest.requireActual('../../../../../app/helpers/utils/util')
|
||||||
.isValidDomainName,
|
.isValidDomainName,
|
||||||
isOriginContractAddress: jest.requireActual(
|
isOriginContractAddress: jest.requireActual(
|
||||||
@ -19,6 +18,13 @@ jest.mock('../../../../../app/helpers/utils/util', () => ({
|
|||||||
).isOriginContractAddress,
|
).isOriginContractAddress,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../../../../shared/modules/hexstring-utils', () => ({
|
||||||
|
isValidHexAddress: jest.fn((to) =>
|
||||||
|
Boolean(to.match(/^[0xabcdef123456798]+$/u)),
|
||||||
|
),
|
||||||
|
isBurnAddress: jest.fn(() => false),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('add-recipient utils', () => {
|
describe('add-recipient utils', () => {
|
||||||
describe('getToErrorObject()', () => {
|
describe('getToErrorObject()', () => {
|
||||||
it('should return a required error if "to" is falsy', () => {
|
it('should return a required error if "to" is falsy', () => {
|
||||||
|
@ -7,13 +7,14 @@ import copyToClipboard from 'copy-to-clipboard/index';
|
|||||||
import ENS from 'ethjs-ens';
|
import ENS from 'ethjs-ens';
|
||||||
import networkMap from 'ethereum-ens-network-map';
|
import networkMap from 'ethereum-ens-network-map';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
|
import { isHexString } from 'ethereumjs-util';
|
||||||
import { ellipsify } from '../../send.utils';
|
import { ellipsify } from '../../send.utils';
|
||||||
import {
|
import { isValidDomainName } from '../../../../helpers/utils/util';
|
||||||
isValidDomainName,
|
|
||||||
isValidAddress,
|
|
||||||
isValidAddressHead,
|
|
||||||
} from '../../../../helpers/utils/util';
|
|
||||||
import { MAINNET_NETWORK_ID } from '../../../../../../shared/constants/network';
|
import { MAINNET_NETWORK_ID } from '../../../../../../shared/constants/network';
|
||||||
|
import {
|
||||||
|
isBurnAddress,
|
||||||
|
isValidHexAddress,
|
||||||
|
} from '../../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
// Local Constants
|
// Local Constants
|
||||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
@ -143,7 +144,10 @@ export default class EnsInput extends Component {
|
|||||||
|
|
||||||
onPaste = (event) => {
|
onPaste = (event) => {
|
||||||
event.clipboardData.items[0].getAsString((text) => {
|
event.clipboardData.items[0].getAsString((text) => {
|
||||||
if (isValidAddress(text)) {
|
if (
|
||||||
|
!isBurnAddress(text) &&
|
||||||
|
isValidHexAddress(text, { mixedCaseUseChecksum: true })
|
||||||
|
) {
|
||||||
this.props.onPaste(text);
|
this.props.onPaste(text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -170,8 +174,11 @@ export default class EnsInput extends Component {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!networkHasEnsSupport &&
|
!networkHasEnsSupport &&
|
||||||
!isValidAddress(input) &&
|
!(
|
||||||
!isValidAddressHead(input)
|
isBurnAddress(input) === false &&
|
||||||
|
isValidHexAddress(input, { mixedCaseUseChecksum: true })
|
||||||
|
) &&
|
||||||
|
!isHexString(input)
|
||||||
) {
|
) {
|
||||||
updateEnsResolution('');
|
updateEnsResolution('');
|
||||||
updateEnsResolutionError(
|
updateEnsResolutionError(
|
||||||
@ -182,7 +189,11 @@ export default class EnsInput extends Component {
|
|||||||
|
|
||||||
if (isValidDomainName(input)) {
|
if (isValidDomainName(input)) {
|
||||||
this.lookupEnsName(input);
|
this.lookupEnsName(input);
|
||||||
} else if (onValidAddressTyped && isValidAddress(input)) {
|
} else if (
|
||||||
|
onValidAddressTyped &&
|
||||||
|
!isBurnAddress(input) &&
|
||||||
|
isValidHexAddress(input, { mixedCaseUseChecksum: true })
|
||||||
|
) {
|
||||||
onValidAddressTyped(input);
|
onValidAddressTyped(input);
|
||||||
} else {
|
} else {
|
||||||
updateEnsResolution('');
|
updateEnsResolution('');
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { isValidAddress } from '../../helpers/utils/util';
|
import { isValidHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
import {
|
import {
|
||||||
getAmountErrorObject,
|
getAmountErrorObject,
|
||||||
getGasFeeErrorObject,
|
getGasFeeErrorObject,
|
||||||
@ -171,7 +171,7 @@ export default class SendTransactionScreen extends Component {
|
|||||||
if (qrCodeData) {
|
if (qrCodeData) {
|
||||||
if (qrCodeData.type === 'address') {
|
if (qrCodeData.type === 'address') {
|
||||||
scannedAddress = qrCodeData.values.address.toLowerCase();
|
scannedAddress = qrCodeData.values.address.toLowerCase();
|
||||||
if (isValidAddress(scannedAddress)) {
|
if (isValidHexAddress(scannedAddress, { allowNonPrefixed: false })) {
|
||||||
const currentAddress = prevTo?.toLowerCase();
|
const currentAddress = prevTo?.toLowerCase();
|
||||||
if (currentAddress !== scannedAddress) {
|
if (currentAddress !== scannedAddress) {
|
||||||
updateSendTo(scannedAddress);
|
updateSendTo(scannedAddress);
|
||||||
|
@ -4,12 +4,13 @@ import { debounce } from 'lodash';
|
|||||||
import Identicon from '../../../../components/ui/identicon';
|
import Identicon from '../../../../components/ui/identicon';
|
||||||
import TextField from '../../../../components/ui/text-field';
|
import TextField from '../../../../components/ui/text-field';
|
||||||
import { CONTACT_LIST_ROUTE } from '../../../../helpers/constants/routes';
|
import { CONTACT_LIST_ROUTE } from '../../../../helpers/constants/routes';
|
||||||
import {
|
import { isValidDomainName } from '../../../../helpers/utils/util';
|
||||||
isValidAddress,
|
|
||||||
isValidDomainName,
|
|
||||||
} from '../../../../helpers/utils/util';
|
|
||||||
import EnsInput from '../../../send/send-content/add-recipient/ens-input';
|
import EnsInput from '../../../send/send-content/add-recipient/ens-input';
|
||||||
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer';
|
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer';
|
||||||
|
import {
|
||||||
|
isBurnAddress,
|
||||||
|
isValidHexAddress,
|
||||||
|
} from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default class AddContact extends PureComponent {
|
export default class AddContact extends PureComponent {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -53,7 +54,9 @@ export default class AddContact extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate = (address) => {
|
validate = (address) => {
|
||||||
const valid = isValidAddress(address);
|
const valid =
|
||||||
|
!isBurnAddress(address) &&
|
||||||
|
isValidHexAddress(address, { mixedCaseUseChecksum: true });
|
||||||
const validEnsAddress = isValidDomainName(address);
|
const validEnsAddress = isValidDomainName(address);
|
||||||
|
|
||||||
if (valid || validEnsAddress || address === '') {
|
if (valid || validEnsAddress || address === '') {
|
||||||
|
@ -4,8 +4,11 @@ import { Redirect } from 'react-router-dom';
|
|||||||
import Identicon from '../../../../components/ui/identicon';
|
import Identicon from '../../../../components/ui/identicon';
|
||||||
import Button from '../../../../components/ui/button/button.component';
|
import Button from '../../../../components/ui/button/button.component';
|
||||||
import TextField from '../../../../components/ui/text-field';
|
import TextField from '../../../../components/ui/text-field';
|
||||||
import { isValidAddress } from '../../../../helpers/utils/util';
|
|
||||||
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer';
|
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer';
|
||||||
|
import {
|
||||||
|
isBurnAddress,
|
||||||
|
isValidHexAddress,
|
||||||
|
} from '../../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
export default class EditContact extends PureComponent {
|
export default class EditContact extends PureComponent {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -135,7 +138,12 @@ export default class EditContact extends PureComponent {
|
|||||||
this.state.newAddress !== address
|
this.state.newAddress !== address
|
||||||
) {
|
) {
|
||||||
// if the user makes a valid change to the address field, remove the original address
|
// if the user makes a valid change to the address field, remove the original address
|
||||||
if (isValidAddress(this.state.newAddress)) {
|
if (
|
||||||
|
!isBurnAddress(this.state.newAddress) &&
|
||||||
|
isValidHexAddress(this.state.newAddress, {
|
||||||
|
mixedCaseUseChecksum: true,
|
||||||
|
})
|
||||||
|
) {
|
||||||
await removeFromAddressBook(chainId, address);
|
await removeFromAddressBook(chainId, address);
|
||||||
await addToAddressBook(
|
await addToAddressBook(
|
||||||
this.state.newAddress,
|
this.state.newAddress,
|
||||||
|
@ -2,10 +2,13 @@ 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 { getAddressBookEntryName } from '../../selectors';
|
import { getAddressBookEntryName } from '../../selectors';
|
||||||
import { isValidAddress, isHex } from '../../helpers/utils/util';
|
|
||||||
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
|
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
|
||||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||||
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
||||||
|
import {
|
||||||
|
isValidHexAddress,
|
||||||
|
isBurnAddress,
|
||||||
|
} from '../../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ABOUT_US_ROUTE,
|
ABOUT_US_ROUTE,
|
||||||
@ -64,7 +67,10 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
|
|
||||||
const addressName = getAddressBookEntryName(
|
const addressName = getAddressBookEntryName(
|
||||||
state,
|
state,
|
||||||
isHex(pathNameTail) && isValidAddress(pathNameTail) ? pathNameTail : '',
|
!isBurnAddress(pathNameTail) &&
|
||||||
|
isValidHexAddress(pathNameTail, { mixedCaseUseChecksum: true })
|
||||||
|
? pathNameTail
|
||||||
|
: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import abi from 'human-standard-token-abi';
|
import abi from 'human-standard-token-abi';
|
||||||
import { isValidAddress } from 'ethereumjs-util';
|
|
||||||
import {
|
import {
|
||||||
SWAPS_CHAINID_DEFAULT_TOKEN_MAP,
|
SWAPS_CHAINID_DEFAULT_TOKEN_MAP,
|
||||||
METASWAP_CHAINID_API_HOST_MAP,
|
METASWAP_CHAINID_API_HOST_MAP,
|
||||||
@ -35,6 +34,7 @@ import { formatCurrency } from '../../helpers/utils/confirm-tx.util';
|
|||||||
import fetchWithCache from '../../helpers/utils/fetch-with-cache';
|
import fetchWithCache from '../../helpers/utils/fetch-with-cache';
|
||||||
|
|
||||||
import { calcGasTotal } from '../send/send.utils';
|
import { calcGasTotal } from '../send/send.utils';
|
||||||
|
import { isValidHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
const TOKEN_TRANSFER_LOG_TOPIC_HASH =
|
const TOKEN_TRANSFER_LOG_TOPIC_HASH =
|
||||||
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
||||||
@ -74,8 +74,8 @@ const QUOTE_VALIDATORS = [
|
|||||||
validator: (trade) =>
|
validator: (trade) =>
|
||||||
trade &&
|
trade &&
|
||||||
validHex(trade.data) &&
|
validHex(trade.data) &&
|
||||||
isValidAddress(trade.to) &&
|
isValidHexAddress(trade.to, { allowNonPrefixed: false }) &&
|
||||||
isValidAddress(trade.from) &&
|
isValidHexAddress(trade.from, { allowNonPrefixed: false }) &&
|
||||||
truthyString(trade.value),
|
truthyString(trade.value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -85,8 +85,8 @@ const QUOTE_VALIDATORS = [
|
|||||||
approvalTx === null ||
|
approvalTx === null ||
|
||||||
(approvalTx &&
|
(approvalTx &&
|
||||||
validHex(approvalTx.data) &&
|
validHex(approvalTx.data) &&
|
||||||
isValidAddress(approvalTx.to) &&
|
isValidHexAddress(approvalTx.to, { allowNonPrefixed: false }) &&
|
||||||
isValidAddress(approvalTx.from)),
|
isValidHexAddress(approvalTx.from, { allowNonPrefixed: false })),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: 'sourceAmount',
|
property: 'sourceAmount',
|
||||||
@ -101,12 +101,12 @@ const QUOTE_VALIDATORS = [
|
|||||||
{
|
{
|
||||||
property: 'sourceToken',
|
property: 'sourceToken',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
validator: isValidAddress,
|
validator: (input) => isValidHexAddress(input, { allowNonPrefixed: false }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: 'destinationToken',
|
property: 'destinationToken',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
validator: isValidAddress,
|
validator: (input) => isValidHexAddress(input, { allowNonPrefixed: false }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: 'aggregator',
|
property: 'aggregator',
|
||||||
@ -146,7 +146,7 @@ const TOKEN_VALIDATORS = [
|
|||||||
{
|
{
|
||||||
property: 'address',
|
property: 'address',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
validator: isValidAddress,
|
validator: (input) => isValidHexAddress(input, { allowNonPrefixed: false }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: 'symbol',
|
property: 'symbol',
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import contractMap from '@metamask/contract-metadata';
|
import contractMap from '@metamask/contract-metadata';
|
||||||
import {
|
import { isHexString, addHexPrefix } from 'ethereumjs-util';
|
||||||
isValidAddress,
|
import { isValidHexAddress } from '../../shared/modules/hexstring-utils';
|
||||||
checksumAddress,
|
import { checksumAddress } from '../app/helpers/utils/util';
|
||||||
isHex,
|
|
||||||
} from '../app/helpers/utils/util';
|
|
||||||
|
|
||||||
let iconFactory;
|
let iconFactory;
|
||||||
|
|
||||||
@ -22,8 +20,8 @@ function IconFactory(jazzicon) {
|
|||||||
IconFactory.prototype.iconForAddress = function (address, diameter) {
|
IconFactory.prototype.iconForAddress = function (address, diameter) {
|
||||||
let addr = address;
|
let addr = address;
|
||||||
|
|
||||||
if (isHex(address)) {
|
if (isHexString(addHexPrefix(address))) {
|
||||||
addr = checksumAddress(address);
|
addr = checksumAddress(addHexPrefix(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconExistsFor(addr)) {
|
if (iconExistsFor(addr)) {
|
||||||
@ -56,7 +54,9 @@ IconFactory.prototype.generateNewIdenticon = function (address, diameter) {
|
|||||||
|
|
||||||
function iconExistsFor(address) {
|
function iconExistsFor(address) {
|
||||||
return (
|
return (
|
||||||
contractMap[address] && isValidAddress(address) && contractMap[address].logo
|
contractMap[address] &&
|
||||||
|
isValidHexAddress(address, { allowNonPrefixed: false }) &&
|
||||||
|
contractMap[address].logo
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user