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

extract determineTransactionType from tx controller (#13737)

This commit is contained in:
Brad Decker 2022-03-07 12:54:36 -06:00 committed by GitHub
parent 4bb3ba4aef
commit 9cea401022
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 262 additions and 274 deletions

View File

@ -3,8 +3,8 @@ import { warn } from 'loglevel';
import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi';
import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts';
import { MINUTE } from '../../../shared/constants/time';
import { isEqualCaseInsensitive } from '../../../ui/helpers/utils/util';
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
// By default, poll every 3 minutes
const DEFAULT_INTERVAL = MINUTE * 3;

View File

@ -28,7 +28,7 @@ import {
} from '../../../ui/pages/swaps/swaps.util';
import fetchWithCache from '../../../ui/helpers/utils/fetch-with-cache';
import { MINUTE, SECOND } from '../../../shared/constants/time';
import { isEqualCaseInsensitive } from '../../../ui/helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import { NETWORK_EVENTS } from './network';
// The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator

View File

@ -3,10 +3,8 @@ import { ObservableStore } from '@metamask/obs-store';
import { bufferToHex, keccak, toBuffer, isHexString } from 'ethereumjs-util';
import EthQuery from 'ethjs-query';
import { ethErrors } from 'eth-rpc-errors';
import abi from 'human-standard-token-abi';
import Common from '@ethereumjs/common';
import { TransactionFactory } from '@ethereumjs/tx';
import { ethers } from 'ethers';
import NonceTracker from 'nonce-tracker';
import log from 'loglevel';
import BigNumber from 'bignumber.js';
@ -47,16 +45,15 @@ import {
NETWORK_TYPE_RPC,
CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP,
} from '../../../../shared/constants/network';
import { isEIP1559Transaction } from '../../../../shared/modules/transaction.utils';
import { readAddressAsContract } from '../../../../shared/modules/contract-utils';
import { isEqualCaseInsensitive } from '../../../../ui/helpers/utils/util';
import {
determineTransactionType,
isEIP1559Transaction,
} from '../../../../shared/modules/transaction.utils';
import TransactionStateManager from './tx-state-manager';
import TxGasUtil from './tx-gas-utils';
import PendingTransactionTracker from './pending-tx-tracker';
import * as txUtils from './lib/util';
const hstInterface = new ethers.utils.Interface(abi);
const MAX_MEMSTORE_TX_LIST_SIZE = 100; // Number of transactions (by unique nonces) to keep in memory
const SWAP_TRANSACTION_TYPES = [
@ -641,7 +638,7 @@ export default class TransactionController extends EventEmitter {
* `generateTxMeta` adds the default txMeta properties to the passed object.
* These include the tx's `id`. As we use the id for determining order of
* txes in the tx-state-manager, it is necessary to call the asynchronous
* method `this._determineTransactionType` after `generateTxMeta`.
* method `determineTransactionType` after `generateTxMeta`.
*/
let txMeta = this.txStateManager.generateTxMeta({
txParams: normalizedTxParams,
@ -669,8 +666,9 @@ export default class TransactionController extends EventEmitter {
}
}
const { type, getCodeResponse } = await this._determineTransactionType(
const { type, getCodeResponse } = await determineTransactionType(
txParams,
this.query,
);
txMeta.type = transactionType || type;
@ -1726,67 +1724,6 @@ export default class TransactionController extends EventEmitter {
});
}
/**
* @typedef { 'transfer' | 'approve' | 'transferfrom' | 'contractInteraction'| 'simpleSend' } InferrableTransactionTypes
*/
/**
* @typedef {Object} InferTransactionTypeResult
* @property {InferrableTransactionTypes} type - The type of transaction
* @property {string} getCodeResponse - The contract code, in hex format if
* it exists. '0x0' or '0x' are also indicators of non-existent contract
* code
*/
/**
* Determines the type of the transaction by analyzing the txParams.
* This method will return one of the types defined in shared/constants/transactions
* It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these
* represent specific events that we control from the extension and are added manually
* at transaction creation.
*
* @param {Object} txParams - Parameters for the transaction
* @returns {InferTransactionTypeResult}
*/
async _determineTransactionType(txParams) {
const { data, to } = txParams;
let name;
try {
name = data && hstInterface.parseTransaction({ data }).name;
} catch (error) {
log.debug('Failed to parse transaction data.', error, data);
}
const tokenMethodName = [
TRANSACTION_TYPES.TOKEN_METHOD_APPROVE,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM,
].find((methodName) => isEqualCaseInsensitive(methodName, name));
let result;
if (data && tokenMethodName) {
result = tokenMethodName;
} else if (data && !to) {
result = TRANSACTION_TYPES.DEPLOY_CONTRACT;
}
let contractCode;
if (!result) {
const {
contractCode: resultCode,
isContractAddress,
} = await readAddressAsContract(this.query, to);
contractCode = resultCode;
result = isContractAddress
? TRANSACTION_TYPES.CONTRACT_INTERACTION
: TRANSACTION_TYPES.SIMPLE_SEND;
}
return { type: result, getCodeResponse: contractCode };
}
/**
* Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
* in the list have the same nonce

View File

@ -1305,156 +1305,6 @@ describe('Transaction Controller', function () {
});
});
describe('#_determineTransactionType', function () {
it('should return a simple send type when to is truthy but data is falsy', async function () {
const result = await txController._determineTransactionType({
to: '0xabc',
data: '',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: null,
});
});
it('should return a token transfer type when data is for the respective method call', async function () {
const result = await txController._determineTransactionType({
to: '0xabc',
data:
'0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
getCodeResponse: undefined,
});
});
it('should return a token approve type when data is for the respective method call', async function () {
const result = await txController._determineTransactionType({
to: '0xabc',
data:
'0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.TOKEN_METHOD_APPROVE,
getCodeResponse: undefined,
});
});
it('should return a contract deployment type when to is falsy and there is data', async function () {
const result = await txController._determineTransactionType({
to: '',
data: '0xabd',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.DEPLOY_CONTRACT,
getCodeResponse: undefined,
});
});
it('should return a simple send type with a 0x getCodeResponse when there is data and but the to address is not a contract address', async function () {
const result = await txController._determineTransactionType({
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: '0xabd',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: '0x',
});
});
it('should return a simple send type with a null getCodeResponse when to is truthy and there is data and but getCode returns an error', async function () {
const result = await txController._determineTransactionType({
to: '0xabc',
data: '0xabd',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: null,
});
});
it('should return a contract interaction type with the correct getCodeResponse when to is truthy and there is data and it is not a token transaction', async function () {
const _providerResultStub = {
// 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000',
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0xa',
};
const _provider = createTestProviderTools({
scaffold: _providerResultStub,
}).provider;
const _fromAccount = getTestAccounts()[0];
const _blockTrackerStub = new EventEmitter();
_blockTrackerStub.getCurrentBlock = noop;
_blockTrackerStub.getLatestBlock = noop;
const _txController = new TransactionController({
provider: _provider,
getGasPrice() {
return '0xee6b2800';
},
networkStore: new ObservableStore(currentNetworkId),
getCurrentChainId: () => currentChainId,
txHistoryLimit: 10,
blockTracker: _blockTrackerStub,
signTransaction: (ethTx) =>
new Promise((resolve) => {
ethTx.sign(_fromAccount.key);
resolve();
}),
getParticipateInMetrics: () => false,
});
const result = await _txController._determineTransactionType({
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: 'abd',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.CONTRACT_INTERACTION,
getCodeResponse: '0x0a',
});
});
it('should return a contract interaction type with the correct getCodeResponse when to is a contract address and data is falsy', async function () {
const _providerResultStub = {
// 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000',
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0xa',
};
const _provider = createTestProviderTools({
scaffold: _providerResultStub,
}).provider;
const _fromAccount = getTestAccounts()[0];
const _blockTrackerStub = new EventEmitter();
_blockTrackerStub.getCurrentBlock = noop;
_blockTrackerStub.getLatestBlock = noop;
const _txController = new TransactionController({
provider: _provider,
getGasPrice() {
return '0xee6b2800';
},
networkStore: new ObservableStore(currentNetworkId),
getCurrentChainId: () => currentChainId,
txHistoryLimit: 10,
blockTracker: _blockTrackerStub,
signTransaction: (ethTx) =>
new Promise((resolve) => {
ethTx.sign(_fromAccount.key);
resolve();
}),
getParticipateInMetrics: () => false,
});
const result = await _txController._determineTransactionType({
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: '',
});
assert.deepEqual(result, {
type: TRANSACTION_TYPES.CONTRACT_INTERACTION,
getCodeResponse: '0x0a',
});
});
});
describe('#getPendingTransactions', function () {
it('should show only submitted and approved transactions as pending transaction', function () {
txController.txStateManager._addTransactionsToState([

View File

@ -82,7 +82,7 @@ import {
import { hexToDecimal } from '../../ui/helpers/utils/conversions.util';
import { getTokenValueParam } from '../../ui/helpers/utils/token-util';
import { getTransactionData } from '../../ui/helpers/utils/transactions.util';
import { isEqualCaseInsensitive } from '../../ui/helpers/utils/util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
import ComposableObservableStore from './lib/ComposableObservableStore';
import AccountTracker from './lib/account-tracker';
import createLoggerMiddleware from './lib/createLoggerMiddleware';

View File

@ -0,0 +1,6 @@
export function isEqualCaseInsensitive(value1, value2) {
if (typeof value1 !== 'string' || typeof value2 !== 'string') {
return false;
}
return value1.toLowerCase() === value2.toLowerCase();
}

View File

@ -1,4 +1,24 @@
import { isHexString } from 'ethereumjs-util';
import { ethers } from 'ethers';
import abi from 'human-standard-token-abi';
import log from 'loglevel';
import { TRANSACTION_TYPES } from '../constants/transaction';
import { readAddressAsContract } from './contract-utils';
import { isEqualCaseInsensitive } from './string-utils';
/**
* @typedef { 'transfer' | 'approve' | 'transferfrom' | 'contractInteraction'| 'simpleSend' } InferrableTransactionTypes
*/
/**
* @typedef {Object} InferTransactionTypeResult
* @property {InferrableTransactionTypes} type - The type of transaction
* @property {string} getCodeResponse - The contract code, in hex format if
* it exists. '0x0' or '0x' are also indicators of non-existent contract
* code
*/
const hstInterface = new ethers.utils.Interface(abi);
export function transactionMatchesNetwork(transaction, chainId, networkId) {
if (typeof transaction.chainId !== 'undefined') {
@ -61,3 +81,53 @@ export function txParamsAreDappSuggested(transaction) {
transaction?.dappSuggestedGasFees?.maxFeePerGas === maxFeePerGas)
);
}
/**
* Determines the type of the transaction by analyzing the txParams.
* This method will return one of the types defined in shared/constants/transactions
* It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these
* represent specific events that we control from the extension and are added manually
* at transaction creation.
*
* @param {Object} txParams - Parameters for the transaction
* @param {EthQuery} query - EthQuery instance
* @returns {InferTransactionTypeResult}
*/
export async function determineTransactionType(txParams, query) {
const { data, to } = txParams;
let name;
try {
name = data && hstInterface.parseTransaction({ data }).name;
} catch (error) {
log.debug('Failed to parse transaction data.', error, data);
}
const tokenMethodName = [
TRANSACTION_TYPES.TOKEN_METHOD_APPROVE,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM,
].find((methodName) => isEqualCaseInsensitive(methodName, name));
let result;
if (data && tokenMethodName) {
result = tokenMethodName;
} else if (data && !to) {
result = TRANSACTION_TYPES.DEPLOY_CONTRACT;
}
let contractCode;
if (!result) {
const {
contractCode: resultCode,
isContractAddress,
} = await readAddressAsContract(query, to);
contractCode = resultCode;
result = isContractAddress
? TRANSACTION_TYPES.CONTRACT_INTERACTION
: TRANSACTION_TYPES.SIMPLE_SEND;
}
return { type: result, getCodeResponse: contractCode };
}

View File

@ -1,4 +1,11 @@
import { isEIP1559Transaction, isLegacyTransaction } from './transaction.utils';
import EthQuery from 'ethjs-query';
import { createTestProviderTools } from '../../test/stub/provider';
import { TRANSACTION_TYPES } from '../constants/transaction';
import {
determineTransactionType,
isEIP1559Transaction,
isLegacyTransaction,
} from './transaction.utils';
describe('Transaction.utils', function () {
describe('isEIP1559Transaction', function () {
@ -80,4 +87,143 @@ describe('Transaction.utils', function () {
).toBe(false);
});
});
describe('determineTransactionType', function () {
const genericProvider = createTestProviderTools().provider;
const query = new EthQuery(genericProvider);
it('should return a simple send type when to is truthy but data is falsy', async function () {
const result = await determineTransactionType(
{
to: '0xabc',
data: '',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: null,
});
});
it('should return a token transfer type when data is for the respective method call', async function () {
const result = await determineTransactionType(
{
to: '0xabc',
data:
'0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
getCodeResponse: undefined,
});
});
it('should return a token approve type when data is for the respective method call', async function () {
const result = await determineTransactionType(
{
to: '0xabc',
data:
'0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.TOKEN_METHOD_APPROVE,
getCodeResponse: undefined,
});
});
it('should return a contract deployment type when to is falsy and there is data', async function () {
const result = await determineTransactionType(
{
to: '',
data: '0xabd',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.DEPLOY_CONTRACT,
getCodeResponse: undefined,
});
});
it('should return a simple send type with a 0x getCodeResponse when there is data and but the to address is not a contract address', async function () {
const result = await determineTransactionType(
{
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: '0xabd',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: '0x',
});
});
it('should return a simple send type with a null getCodeResponse when to is truthy and there is data and but getCode returns an error', async function () {
const result = await determineTransactionType(
{
to: '0xabc',
data: '0xabd',
},
query,
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.SIMPLE_SEND,
getCodeResponse: null,
});
});
it('should return a contract interaction type with the correct getCodeResponse when to is truthy and there is data and it is not a token transaction', async function () {
const _providerResultStub = {
// 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000',
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0xa',
};
const _provider = createTestProviderTools({
scaffold: _providerResultStub,
}).provider;
const result = await determineTransactionType(
{
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: 'abd',
},
new EthQuery(_provider),
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.CONTRACT_INTERACTION,
getCodeResponse: '0x0a',
});
});
it('should return a contract interaction type with the correct getCodeResponse when to is a contract address and data is falsy', async function () {
const _providerResultStub = {
// 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000',
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0xa',
};
const _provider = createTestProviderTools({
scaffold: _providerResultStub,
}).provider;
const result = await determineTransactionType(
{
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
data: '',
},
new EthQuery(_provider),
);
expect(result).toMatchObject({
type: TRANSACTION_TYPES.CONTRACT_INTERACTION,
getCodeResponse: '0x0a',
});
});
});
});

View File

@ -18,11 +18,7 @@ import {
BLOCK_SIZES,
} from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
getAssetImageURL,
isEqualCaseInsensitive,
shortenAddress,
} from '../../../helpers/utils/util';
import { getAssetImageURL, shortenAddress } from '../../../helpers/utils/util';
import {
getCurrentChainId,
getIpfsGateway,
@ -54,6 +50,7 @@ import InfoTooltip from '../../ui/info-tooltip';
import { ERC721 } from '../../../helpers/constants/common';
import { usePrevious } from '../../../hooks/usePrevious';
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
export default function CollectibleDetails({ collectible }) {
const {

View File

@ -13,7 +13,7 @@ import Button from '../../ui/button';
import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions';
import { SWAPS_CHAINID_CONTRACT_ADDRESS_MAP } from '../../../../shared/constants/swaps';
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
import { isEqualCaseInsensitive } from '../../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
const PAGE_INCREMENT = 10;

View File

@ -20,7 +20,7 @@ import {
import { conversionUtil } from '../../../shared/modules/conversion.utils';
import { getAveragePriceEstimateInHexWEI } from '../../selectors/custom-gas';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
// Actions
const createActionType = (action) => `metamask/confirm-transaction/${action}`;

View File

@ -14,9 +14,9 @@ import {
import { updateTransaction } from '../../store/actions';
import { setCustomGasLimit, setCustomGasPrice } from '../gas/gas.duck';
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { KEYRING_TYPES } from '../../../shared/constants/hardware-wallets';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
export default function reduceMetamask(state = {}, action) {
const metamaskState = {

View File

@ -78,7 +78,6 @@ import {
isDefaultMetaMaskChain,
isOriginContractAddress,
isValidDomainName,
isEqualCaseInsensitive,
} from '../../helpers/utils/util';
import {
getGasEstimateType,
@ -102,6 +101,7 @@ import {
import { TRANSACTION_ENVELOPE_TYPES } from '../../../shared/constants/transaction';
import { readAddressAsContract } from '../../../shared/modules/contract-utils';
import { INVALID_ASSET_TYPE } from '../../helpers/constants/error-keys';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
// typedefs
/**
* @typedef {import('@reduxjs/toolkit').PayloadAction} PayloadAction

View File

@ -65,14 +65,6 @@ export function isDefaultMetaMaskChain(chainId) {
return false;
}
// Both inputs should be strings. This method is currently used to compare tokenAddress hex strings.
export function isEqualCaseInsensitive(value1, value2) {
if (typeof value1 !== 'string' || typeof value2 !== 'string') {
return false;
}
return value1.toLowerCase() === value2.toLowerCase();
}
export function valuesFor(obj) {
if (!obj) {
return [];

View File

@ -3,11 +3,11 @@ import { useRouteMatch } from 'react-router-dom';
import { getTokens } from '../ducks/metamask/metamask';
import { getCurrentChainId } from '../selectors';
import { ASSET_ROUTE } from '../helpers/constants/routes';
import { isEqualCaseInsensitive } from '../helpers/utils/util';
import {
SWAPS_CHAINID_DEFAULT_TOKEN_MAP,
ETH_SWAPS_TOKEN_OBJECT,
} from '../../shared/constants/swaps';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
/**
* Returns a token object for the asset that is currently being viewed.

View File

@ -7,7 +7,7 @@ import {
} from '../selectors';
import { getTokenFiatAmount } from '../helpers/utils/token-util';
import { getConversionRate } from '../ducks/metamask/metamask';
import { isEqualCaseInsensitive } from '../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
/**
* Get the token balance converted to fiat and formatted for display

View File

@ -3,7 +3,7 @@ import TokenTracker from '@metamask/eth-token-tracker';
import { shallowEqual, useSelector } from 'react-redux';
import { getCurrentChainId, getSelectedAddress } from '../selectors';
import { SECOND } from '../../shared/constants/time';
import { isEqualCaseInsensitive } from '../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
import { useEqualityCheck } from './useEqualityCheck';
export function useTokenTracker(

View File

@ -11,7 +11,6 @@ import {
getTokenValueParam,
} from '../helpers/utils/token-util';
import {
isEqualCaseInsensitive,
formatDateWithYearContext,
shortenAddress,
stripHttpSchemes,
@ -28,6 +27,7 @@ import {
TRANSACTION_STATUSES,
} from '../../shared/constants/transaction';
import { captureSingleException } from '../store/actions';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
import { useI18nContext } from './useI18nContext';
import { useTokenFiatAmount } from './useTokenFiatAmount';
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';

View File

@ -1,10 +1,10 @@
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { Redirect, useParams } from 'react-router-dom';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import CollectibleDetails from '../../components/app/collectible-details/collectible-details';
import { getCollectibles, getTokens } from '../../ducks/metamask/metamask';
import { DEFAULT_ROUTE } from '../../helpers/constants/routes';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import NativeAsset from './components/native-asset';
import TokenAsset from './components/token-asset';

View File

@ -7,7 +7,7 @@ import TokenBalance from '../../components/ui/token-balance';
import { I18nContext } from '../../contexts/i18n';
import { MetaMetricsContext } from '../../contexts/metametrics';
import ZENDESK_URLS from '../../helpers/constants/zendesk-url';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
function getTokenName(name, symbol) {
return typeof name === 'undefined' ? symbol : `${name} (${symbol})`;

View File

@ -43,7 +43,7 @@ import AdvancedGasFeePopover from '../../components/app/advanced-gas-fee-popover
import EditGasFeePopover from '../../components/app/edit-gas-fee-popover';
import EditGasPopover from '../../components/app/edit-gas-popover/edit-gas-popover.component';
import Loading from '../../components/ui/loading-screen';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import { getCustomTxParamsData } from './confirm-approve.util';
import ConfirmApproveContent from './confirm-approve-content';

View File

@ -13,7 +13,7 @@ import {
getTokenValueParam,
} from '../../helpers/utils/token-util';
import { hexWEIToDecETH } from '../../helpers/utils/conversions.util';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component';
const mapStateToProps = (state, ownProps) => {

View File

@ -14,11 +14,7 @@ import {
setDefaultHomeActiveTabName,
} from '../../store/actions';
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils';
import {
isEqualCaseInsensitive,
shortenAddress,
valuesFor,
} from '../../helpers/utils/util';
import { shortenAddress, valuesFor } from '../../helpers/utils/util';
import {
getAdvancedInlineGasShown,
getCustomNonceValue,
@ -55,6 +51,7 @@ import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import ConfirmTransactionBase from './confirm-transaction-base.component';
let customNonceValue = '';

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import Fuse from 'fuse.js';
import InputAdornment from '@material-ui/core/InputAdornment';
import TextField from '../../../components/ui/text-field';
import { isEqualCaseInsensitive } from '../../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
export default class TokenSearch extends Component {
static contextTypes = {

View File

@ -7,7 +7,7 @@ import TokenListDisplay from '../../../../components/app/token-list-display';
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display';
import { ERC20, ERC721, PRIMARY } from '../../../../helpers/constants/common';
import { ASSET_TYPES } from '../../../../ducks/send';
import { isEqualCaseInsensitive } from '../../../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../../../shared/modules/string-utils';
export default class SendAssetRow extends Component {
static propTypes = {

View File

@ -3,9 +3,9 @@ import PropTypes from 'prop-types';
import Fuse from 'fuse.js';
import InputAdornment from '@material-ui/core/InputAdornment';
import TextField from '../../../components/ui/text-field';
import { isEqualCaseInsensitive } from '../../../helpers/utils/util';
import { I18nContext } from '../../../contexts/i18n';
import SearchIcon from '../../../components/ui/search-icon';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
export default function SettingsSearch({
onSearch,

View File

@ -77,10 +77,7 @@ import {
hexToDecimal,
} from '../../../helpers/utils/conversions.util';
import { calcTokenAmount } from '../../../helpers/utils/token-util';
import {
getURLHostName,
isEqualCaseInsensitive,
} from '../../../helpers/utils/util';
import { getURLHostName } from '../../../helpers/utils/util';
import { usePrevious } from '../../../hooks/usePrevious';
import { useTokenTracker } from '../../../hooks/useTokenTracker';
import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount';
@ -110,6 +107,7 @@ import {
shouldEnableDirectWrapping,
} from '../swaps.util';
import SwapsFooter from '../swaps-footer';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
const fuseSearchKeys = [
{ name: 'name', weight: 0.499 },

View File

@ -59,10 +59,7 @@ import {
} from '../../../selectors';
import { getNativeCurrency, getTokens } from '../../../ducks/metamask/metamask';
import {
toPrecisionWithoutTrailingZeros,
isEqualCaseInsensitive,
} from '../../../helpers/utils/util';
import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util';
import {
safeRefetchQuotes,
@ -115,6 +112,7 @@ import CountdownTimer from '../countdown-timer';
import SwapsFooter from '../swaps-footer';
import PulseLoader from '../../../components/ui/pulse-loader'; // TODO: Replace this with a different loading component.
import Box from '../../../components/ui/box';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
import ViewQuotePriceDifference from './view-quote-price-difference';
let intervalId;

View File

@ -4,7 +4,6 @@ import { Redirect, useHistory, useParams } from 'react-router-dom';
import { getTokens } from '../../ducks/metamask/metamask';
import { getUseTokenDetection, getTokenList } from '../../selectors';
import { useCopyToClipboard } from '../../hooks/useCopyToClipboard';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import Identicon from '../../components/ui/identicon';
import { I18nContext } from '../../contexts/i18n';
import { useTokenTracker } from '../../hooks/useTokenTracker';
@ -25,6 +24,7 @@ import {
TEXT_ALIGN,
OVERFLOW_WRAP,
} from '../../helpers/constants/design-system';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
export default function TokenDetailsPage() {
const dispatch = useDispatch();

View File

@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
import { renderWithProvider } from '../../../test/lib/render-helpers';
import Identicon from '../../components/ui/identicon/identicon.component';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import TokenDetailsPage from './token-details-page';
const testTokenAddress = '0xaD6D458402F60fD3Bd25163575031ACDce07538A';

View File

@ -25,7 +25,7 @@ import {
getMaximumGasTotalInHexWei,
getMinimumGasTotalInHexWei,
} from '../../shared/modules/gas.utils';
import { isEqualCaseInsensitive } from '../helpers/utils/util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
import { getAveragePriceEstimateInHexWEI } from './custom-gas';
import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors';
import { checkNetworkAndAccountSupports1559 } from '.';

View File

@ -33,11 +33,7 @@ import {
ALLOWED_SWAPS_CHAIN_IDS,
} from '../../shared/constants/swaps';
import {
shortenAddress,
getAccountByAddress,
isEqualCaseInsensitive,
} from '../helpers/utils/util';
import { shortenAddress, getAccountByAddress } from '../helpers/utils/util';
import {
getValueFromWeiHex,
hexToDecimal,
@ -60,6 +56,7 @@ import {
getLedgerWebHidConnectedStatus,
getLedgerTransportStatus,
} from '../ducks/app/app';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
/**
* One of the only remaining valid uses of selecting the network subkey of the

View File

@ -9,7 +9,6 @@ import {
} from '../helpers/utils/i18n-helper';
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
import { getSymbolAndDecimals } from '../helpers/utils/token-util';
import { isEqualCaseInsensitive } from '../helpers/utils/util';
import switchDirection from '../helpers/utils/switch-direction';
import {
ENVIRONMENT_TYPE_NOTIFICATION,
@ -35,6 +34,7 @@ import {
LEDGER_USB_VENDOR_ID,
} from '../../shared/constants/hardware-wallets';
import { parseSmartTransactionsError } from '../pages/swaps/swaps.util';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
import * as actionConstants from './actionConstants';
let background = null;