mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
extract determineTransactionType from tx controller (#13737)
This commit is contained in:
parent
4bb3ba4aef
commit
9cea401022
@ -3,8 +3,8 @@ import { warn } from 'loglevel';
|
|||||||
import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi';
|
import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi';
|
||||||
import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts';
|
import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts';
|
||||||
import { MINUTE } from '../../../shared/constants/time';
|
import { MINUTE } from '../../../shared/constants/time';
|
||||||
import { isEqualCaseInsensitive } from '../../../ui/helpers/utils/util';
|
|
||||||
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
|
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
|
|
||||||
// By default, poll every 3 minutes
|
// By default, poll every 3 minutes
|
||||||
const DEFAULT_INTERVAL = MINUTE * 3;
|
const DEFAULT_INTERVAL = MINUTE * 3;
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
} from '../../../ui/pages/swaps/swaps.util';
|
} from '../../../ui/pages/swaps/swaps.util';
|
||||||
import fetchWithCache from '../../../ui/helpers/utils/fetch-with-cache';
|
import fetchWithCache from '../../../ui/helpers/utils/fetch-with-cache';
|
||||||
import { MINUTE, SECOND } from '../../../shared/constants/time';
|
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';
|
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
|
// The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator
|
||||||
|
@ -3,10 +3,8 @@ import { ObservableStore } from '@metamask/obs-store';
|
|||||||
import { bufferToHex, keccak, toBuffer, isHexString } from 'ethereumjs-util';
|
import { bufferToHex, keccak, toBuffer, isHexString } from 'ethereumjs-util';
|
||||||
import EthQuery from 'ethjs-query';
|
import EthQuery from 'ethjs-query';
|
||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import abi from 'human-standard-token-abi';
|
|
||||||
import Common from '@ethereumjs/common';
|
import Common from '@ethereumjs/common';
|
||||||
import { TransactionFactory } from '@ethereumjs/tx';
|
import { TransactionFactory } from '@ethereumjs/tx';
|
||||||
import { ethers } from 'ethers';
|
|
||||||
import NonceTracker from 'nonce-tracker';
|
import NonceTracker from 'nonce-tracker';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
@ -47,16 +45,15 @@ import {
|
|||||||
NETWORK_TYPE_RPC,
|
NETWORK_TYPE_RPC,
|
||||||
CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP,
|
CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP,
|
||||||
} from '../../../../shared/constants/network';
|
} from '../../../../shared/constants/network';
|
||||||
import { isEIP1559Transaction } from '../../../../shared/modules/transaction.utils';
|
import {
|
||||||
import { readAddressAsContract } from '../../../../shared/modules/contract-utils';
|
determineTransactionType,
|
||||||
import { isEqualCaseInsensitive } from '../../../../ui/helpers/utils/util';
|
isEIP1559Transaction,
|
||||||
|
} from '../../../../shared/modules/transaction.utils';
|
||||||
import TransactionStateManager from './tx-state-manager';
|
import TransactionStateManager from './tx-state-manager';
|
||||||
import TxGasUtil from './tx-gas-utils';
|
import TxGasUtil from './tx-gas-utils';
|
||||||
import PendingTransactionTracker from './pending-tx-tracker';
|
import PendingTransactionTracker from './pending-tx-tracker';
|
||||||
import * as txUtils from './lib/util';
|
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 MAX_MEMSTORE_TX_LIST_SIZE = 100; // Number of transactions (by unique nonces) to keep in memory
|
||||||
|
|
||||||
const SWAP_TRANSACTION_TYPES = [
|
const SWAP_TRANSACTION_TYPES = [
|
||||||
@ -641,7 +638,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
* `generateTxMeta` adds the default txMeta properties to the passed object.
|
* `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
|
* 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
|
* 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({
|
let txMeta = this.txStateManager.generateTxMeta({
|
||||||
txParams: normalizedTxParams,
|
txParams: normalizedTxParams,
|
||||||
@ -669,8 +666,9 @@ export default class TransactionController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, getCodeResponse } = await this._determineTransactionType(
|
const { type, getCodeResponse } = await determineTransactionType(
|
||||||
txParams,
|
txParams,
|
||||||
|
this.query,
|
||||||
);
|
);
|
||||||
txMeta.type = transactionType || type;
|
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
|
* Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
||||||
* in the list have the same nonce
|
* in the list have the same nonce
|
||||||
|
@ -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 () {
|
describe('#getPendingTransactions', function () {
|
||||||
it('should show only submitted and approved transactions as pending transaction', function () {
|
it('should show only submitted and approved transactions as pending transaction', function () {
|
||||||
txController.txStateManager._addTransactionsToState([
|
txController.txStateManager._addTransactionsToState([
|
||||||
|
@ -82,7 +82,7 @@ import {
|
|||||||
import { hexToDecimal } from '../../ui/helpers/utils/conversions.util';
|
import { hexToDecimal } from '../../ui/helpers/utils/conversions.util';
|
||||||
import { getTokenValueParam } from '../../ui/helpers/utils/token-util';
|
import { getTokenValueParam } from '../../ui/helpers/utils/token-util';
|
||||||
import { getTransactionData } from '../../ui/helpers/utils/transactions.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 ComposableObservableStore from './lib/ComposableObservableStore';
|
||||||
import AccountTracker from './lib/account-tracker';
|
import AccountTracker from './lib/account-tracker';
|
||||||
import createLoggerMiddleware from './lib/createLoggerMiddleware';
|
import createLoggerMiddleware from './lib/createLoggerMiddleware';
|
||||||
|
6
shared/modules/string-utils.js
Normal file
6
shared/modules/string-utils.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export function isEqualCaseInsensitive(value1, value2) {
|
||||||
|
if (typeof value1 !== 'string' || typeof value2 !== 'string') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value1.toLowerCase() === value2.toLowerCase();
|
||||||
|
}
|
@ -1,4 +1,24 @@
|
|||||||
import { isHexString } from 'ethereumjs-util';
|
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) {
|
export function transactionMatchesNetwork(transaction, chainId, networkId) {
|
||||||
if (typeof transaction.chainId !== 'undefined') {
|
if (typeof transaction.chainId !== 'undefined') {
|
||||||
@ -61,3 +81,53 @@ export function txParamsAreDappSuggested(transaction) {
|
|||||||
transaction?.dappSuggestedGasFees?.maxFeePerGas === maxFeePerGas)
|
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 };
|
||||||
|
}
|
||||||
|
@ -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('Transaction.utils', function () {
|
||||||
describe('isEIP1559Transaction', function () {
|
describe('isEIP1559Transaction', function () {
|
||||||
@ -80,4 +87,143 @@ describe('Transaction.utils', function () {
|
|||||||
).toBe(false);
|
).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',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -18,11 +18,7 @@ import {
|
|||||||
BLOCK_SIZES,
|
BLOCK_SIZES,
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
import {
|
import { getAssetImageURL, shortenAddress } from '../../../helpers/utils/util';
|
||||||
getAssetImageURL,
|
|
||||||
isEqualCaseInsensitive,
|
|
||||||
shortenAddress,
|
|
||||||
} from '../../../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
getCurrentChainId,
|
getCurrentChainId,
|
||||||
getIpfsGateway,
|
getIpfsGateway,
|
||||||
@ -54,6 +50,7 @@ import InfoTooltip from '../../ui/info-tooltip';
|
|||||||
import { ERC721 } from '../../../helpers/constants/common';
|
import { ERC721 } from '../../../helpers/constants/common';
|
||||||
import { usePrevious } from '../../../hooks/usePrevious';
|
import { usePrevious } from '../../../hooks/usePrevious';
|
||||||
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
|
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
||||||
|
|
||||||
export default function CollectibleDetails({ collectible }) {
|
export default function CollectibleDetails({ collectible }) {
|
||||||
const {
|
const {
|
||||||
|
@ -13,7 +13,7 @@ import Button from '../../ui/button';
|
|||||||
import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions';
|
import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions';
|
||||||
import { SWAPS_CHAINID_CONTRACT_ADDRESS_MAP } from '../../../../shared/constants/swaps';
|
import { SWAPS_CHAINID_CONTRACT_ADDRESS_MAP } from '../../../../shared/constants/swaps';
|
||||||
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
|
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
|
||||||
import { isEqualCaseInsensitive } from '../../../helpers/utils/util';
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
||||||
|
|
||||||
const PAGE_INCREMENT = 10;
|
const PAGE_INCREMENT = 10;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import {
|
|||||||
|
|
||||||
import { conversionUtil } from '../../../shared/modules/conversion.utils';
|
import { conversionUtil } from '../../../shared/modules/conversion.utils';
|
||||||
import { getAveragePriceEstimateInHexWEI } from '../../selectors/custom-gas';
|
import { getAveragePriceEstimateInHexWEI } from '../../selectors/custom-gas';
|
||||||
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
const createActionType = (action) => `metamask/confirm-transaction/${action}`;
|
const createActionType = (action) => `metamask/confirm-transaction/${action}`;
|
||||||
|
@ -14,9 +14,9 @@ import {
|
|||||||
import { updateTransaction } from '../../store/actions';
|
import { updateTransaction } from '../../store/actions';
|
||||||
import { setCustomGasLimit, setCustomGasPrice } from '../gas/gas.duck';
|
import { setCustomGasLimit, setCustomGasPrice } from '../gas/gas.duck';
|
||||||
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util';
|
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util';
|
||||||
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
|
|
||||||
|
|
||||||
import { KEYRING_TYPES } from '../../../shared/constants/hardware-wallets';
|
import { KEYRING_TYPES } from '../../../shared/constants/hardware-wallets';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
|
|
||||||
export default function reduceMetamask(state = {}, action) {
|
export default function reduceMetamask(state = {}, action) {
|
||||||
const metamaskState = {
|
const metamaskState = {
|
||||||
|
@ -78,7 +78,6 @@ import {
|
|||||||
isDefaultMetaMaskChain,
|
isDefaultMetaMaskChain,
|
||||||
isOriginContractAddress,
|
isOriginContractAddress,
|
||||||
isValidDomainName,
|
isValidDomainName,
|
||||||
isEqualCaseInsensitive,
|
|
||||||
} from '../../helpers/utils/util';
|
} from '../../helpers/utils/util';
|
||||||
import {
|
import {
|
||||||
getGasEstimateType,
|
getGasEstimateType,
|
||||||
@ -102,6 +101,7 @@ import {
|
|||||||
import { TRANSACTION_ENVELOPE_TYPES } from '../../../shared/constants/transaction';
|
import { TRANSACTION_ENVELOPE_TYPES } from '../../../shared/constants/transaction';
|
||||||
import { readAddressAsContract } from '../../../shared/modules/contract-utils';
|
import { readAddressAsContract } from '../../../shared/modules/contract-utils';
|
||||||
import { INVALID_ASSET_TYPE } from '../../helpers/constants/error-keys';
|
import { INVALID_ASSET_TYPE } from '../../helpers/constants/error-keys';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
// typedefs
|
// typedefs
|
||||||
/**
|
/**
|
||||||
* @typedef {import('@reduxjs/toolkit').PayloadAction} PayloadAction
|
* @typedef {import('@reduxjs/toolkit').PayloadAction} PayloadAction
|
||||||
|
@ -65,14 +65,6 @@ export function isDefaultMetaMaskChain(chainId) {
|
|||||||
return false;
|
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) {
|
export function valuesFor(obj) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -3,11 +3,11 @@ import { useRouteMatch } from 'react-router-dom';
|
|||||||
import { getTokens } from '../ducks/metamask/metamask';
|
import { getTokens } from '../ducks/metamask/metamask';
|
||||||
import { getCurrentChainId } from '../selectors';
|
import { getCurrentChainId } from '../selectors';
|
||||||
import { ASSET_ROUTE } from '../helpers/constants/routes';
|
import { ASSET_ROUTE } from '../helpers/constants/routes';
|
||||||
import { isEqualCaseInsensitive } from '../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
SWAPS_CHAINID_DEFAULT_TOKEN_MAP,
|
SWAPS_CHAINID_DEFAULT_TOKEN_MAP,
|
||||||
ETH_SWAPS_TOKEN_OBJECT,
|
ETH_SWAPS_TOKEN_OBJECT,
|
||||||
} from '../../shared/constants/swaps';
|
} from '../../shared/constants/swaps';
|
||||||
|
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a token object for the asset that is currently being viewed.
|
* Returns a token object for the asset that is currently being viewed.
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
} from '../selectors';
|
} from '../selectors';
|
||||||
import { getTokenFiatAmount } from '../helpers/utils/token-util';
|
import { getTokenFiatAmount } from '../helpers/utils/token-util';
|
||||||
import { getConversionRate } from '../ducks/metamask/metamask';
|
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
|
* Get the token balance converted to fiat and formatted for display
|
||||||
|
@ -3,7 +3,7 @@ import TokenTracker from '@metamask/eth-token-tracker';
|
|||||||
import { shallowEqual, useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import { getCurrentChainId, getSelectedAddress } from '../selectors';
|
import { getCurrentChainId, getSelectedAddress } from '../selectors';
|
||||||
import { SECOND } from '../../shared/constants/time';
|
import { SECOND } from '../../shared/constants/time';
|
||||||
import { isEqualCaseInsensitive } from '../helpers/utils/util';
|
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
|
||||||
import { useEqualityCheck } from './useEqualityCheck';
|
import { useEqualityCheck } from './useEqualityCheck';
|
||||||
|
|
||||||
export function useTokenTracker(
|
export function useTokenTracker(
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
getTokenValueParam,
|
getTokenValueParam,
|
||||||
} from '../helpers/utils/token-util';
|
} from '../helpers/utils/token-util';
|
||||||
import {
|
import {
|
||||||
isEqualCaseInsensitive,
|
|
||||||
formatDateWithYearContext,
|
formatDateWithYearContext,
|
||||||
shortenAddress,
|
shortenAddress,
|
||||||
stripHttpSchemes,
|
stripHttpSchemes,
|
||||||
@ -28,6 +27,7 @@ import {
|
|||||||
TRANSACTION_STATUSES,
|
TRANSACTION_STATUSES,
|
||||||
} from '../../shared/constants/transaction';
|
} from '../../shared/constants/transaction';
|
||||||
import { captureSingleException } from '../store/actions';
|
import { captureSingleException } from '../store/actions';
|
||||||
|
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
|
||||||
import { useI18nContext } from './useI18nContext';
|
import { useI18nContext } from './useI18nContext';
|
||||||
import { useTokenFiatAmount } from './useTokenFiatAmount';
|
import { useTokenFiatAmount } from './useTokenFiatAmount';
|
||||||
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { Redirect, useParams } from 'react-router-dom';
|
import { Redirect, useParams } from 'react-router-dom';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
import CollectibleDetails from '../../components/app/collectible-details/collectible-details';
|
import CollectibleDetails from '../../components/app/collectible-details/collectible-details';
|
||||||
import { getCollectibles, getTokens } from '../../ducks/metamask/metamask';
|
import { getCollectibles, getTokens } from '../../ducks/metamask/metamask';
|
||||||
import { DEFAULT_ROUTE } from '../../helpers/constants/routes';
|
import { DEFAULT_ROUTE } from '../../helpers/constants/routes';
|
||||||
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
|
|
||||||
|
|
||||||
import NativeAsset from './components/native-asset';
|
import NativeAsset from './components/native-asset';
|
||||||
import TokenAsset from './components/token-asset';
|
import TokenAsset from './components/token-asset';
|
||||||
|
@ -7,7 +7,7 @@ import TokenBalance from '../../components/ui/token-balance';
|
|||||||
import { I18nContext } from '../../contexts/i18n';
|
import { I18nContext } from '../../contexts/i18n';
|
||||||
import { MetaMetricsContext } from '../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../contexts/metametrics';
|
||||||
import ZENDESK_URLS from '../../helpers/constants/zendesk-url';
|
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) {
|
function getTokenName(name, symbol) {
|
||||||
return typeof name === 'undefined' ? symbol : `${name} (${symbol})`;
|
return typeof name === 'undefined' ? symbol : `${name} (${symbol})`;
|
||||||
|
@ -43,7 +43,7 @@ import AdvancedGasFeePopover from '../../components/app/advanced-gas-fee-popover
|
|||||||
import EditGasFeePopover from '../../components/app/edit-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 EditGasPopover from '../../components/app/edit-gas-popover/edit-gas-popover.component';
|
||||||
import Loading from '../../components/ui/loading-screen';
|
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 { getCustomTxParamsData } from './confirm-approve.util';
|
||||||
import ConfirmApproveContent from './confirm-approve-content';
|
import ConfirmApproveContent from './confirm-approve-content';
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
getTokenValueParam,
|
getTokenValueParam,
|
||||||
} from '../../helpers/utils/token-util';
|
} from '../../helpers/utils/token-util';
|
||||||
import { hexWEIToDecETH } from '../../helpers/utils/conversions.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';
|
import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
|
@ -14,11 +14,7 @@ import {
|
|||||||
setDefaultHomeActiveTabName,
|
setDefaultHomeActiveTabName,
|
||||||
} from '../../store/actions';
|
} from '../../store/actions';
|
||||||
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils';
|
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils';
|
||||||
import {
|
import { shortenAddress, valuesFor } from '../../helpers/utils/util';
|
||||||
isEqualCaseInsensitive,
|
|
||||||
shortenAddress,
|
|
||||||
valuesFor,
|
|
||||||
} from '../../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
getAdvancedInlineGasShown,
|
getAdvancedInlineGasShown,
|
||||||
getCustomNonceValue,
|
getCustomNonceValue,
|
||||||
@ -55,6 +51,7 @@ import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
|||||||
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
|
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
|
||||||
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
||||||
import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
|
import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
import ConfirmTransactionBase from './confirm-transaction-base.component';
|
import ConfirmTransactionBase from './confirm-transaction-base.component';
|
||||||
|
|
||||||
let customNonceValue = '';
|
let customNonceValue = '';
|
||||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||||
import TextField from '../../../components/ui/text-field';
|
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 {
|
export default class TokenSearch extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
|
@ -7,7 +7,7 @@ import TokenListDisplay from '../../../../components/app/token-list-display';
|
|||||||
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display';
|
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display';
|
||||||
import { ERC20, ERC721, PRIMARY } from '../../../../helpers/constants/common';
|
import { ERC20, ERC721, PRIMARY } from '../../../../helpers/constants/common';
|
||||||
import { ASSET_TYPES } from '../../../../ducks/send';
|
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 {
|
export default class SendAssetRow extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -3,9 +3,9 @@ import PropTypes from 'prop-types';
|
|||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||||
import TextField from '../../../components/ui/text-field';
|
import TextField from '../../../components/ui/text-field';
|
||||||
import { isEqualCaseInsensitive } from '../../../helpers/utils/util';
|
|
||||||
import { I18nContext } from '../../../contexts/i18n';
|
import { I18nContext } from '../../../contexts/i18n';
|
||||||
import SearchIcon from '../../../components/ui/search-icon';
|
import SearchIcon from '../../../components/ui/search-icon';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
||||||
|
|
||||||
export default function SettingsSearch({
|
export default function SettingsSearch({
|
||||||
onSearch,
|
onSearch,
|
||||||
|
@ -77,10 +77,7 @@ import {
|
|||||||
hexToDecimal,
|
hexToDecimal,
|
||||||
} from '../../../helpers/utils/conversions.util';
|
} from '../../../helpers/utils/conversions.util';
|
||||||
import { calcTokenAmount } from '../../../helpers/utils/token-util';
|
import { calcTokenAmount } from '../../../helpers/utils/token-util';
|
||||||
import {
|
import { getURLHostName } from '../../../helpers/utils/util';
|
||||||
getURLHostName,
|
|
||||||
isEqualCaseInsensitive,
|
|
||||||
} from '../../../helpers/utils/util';
|
|
||||||
import { usePrevious } from '../../../hooks/usePrevious';
|
import { usePrevious } from '../../../hooks/usePrevious';
|
||||||
import { useTokenTracker } from '../../../hooks/useTokenTracker';
|
import { useTokenTracker } from '../../../hooks/useTokenTracker';
|
||||||
import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount';
|
import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount';
|
||||||
@ -110,6 +107,7 @@ import {
|
|||||||
shouldEnableDirectWrapping,
|
shouldEnableDirectWrapping,
|
||||||
} from '../swaps.util';
|
} from '../swaps.util';
|
||||||
import SwapsFooter from '../swaps-footer';
|
import SwapsFooter from '../swaps-footer';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
||||||
|
|
||||||
const fuseSearchKeys = [
|
const fuseSearchKeys = [
|
||||||
{ name: 'name', weight: 0.499 },
|
{ name: 'name', weight: 0.499 },
|
||||||
|
@ -59,10 +59,7 @@ import {
|
|||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import { getNativeCurrency, getTokens } from '../../../ducks/metamask/metamask';
|
import { getNativeCurrency, getTokens } from '../../../ducks/metamask/metamask';
|
||||||
|
|
||||||
import {
|
import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util';
|
||||||
toPrecisionWithoutTrailingZeros,
|
|
||||||
isEqualCaseInsensitive,
|
|
||||||
} from '../../../helpers/utils/util';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
safeRefetchQuotes,
|
safeRefetchQuotes,
|
||||||
@ -115,6 +112,7 @@ import CountdownTimer from '../countdown-timer';
|
|||||||
import SwapsFooter from '../swaps-footer';
|
import SwapsFooter from '../swaps-footer';
|
||||||
import PulseLoader from '../../../components/ui/pulse-loader'; // TODO: Replace this with a different loading component.
|
import PulseLoader from '../../../components/ui/pulse-loader'; // TODO: Replace this with a different loading component.
|
||||||
import Box from '../../../components/ui/box';
|
import Box from '../../../components/ui/box';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
||||||
import ViewQuotePriceDifference from './view-quote-price-difference';
|
import ViewQuotePriceDifference from './view-quote-price-difference';
|
||||||
|
|
||||||
let intervalId;
|
let intervalId;
|
||||||
|
@ -4,7 +4,6 @@ import { Redirect, useHistory, useParams } from 'react-router-dom';
|
|||||||
import { getTokens } from '../../ducks/metamask/metamask';
|
import { getTokens } from '../../ducks/metamask/metamask';
|
||||||
import { getUseTokenDetection, getTokenList } from '../../selectors';
|
import { getUseTokenDetection, getTokenList } from '../../selectors';
|
||||||
import { useCopyToClipboard } from '../../hooks/useCopyToClipboard';
|
import { useCopyToClipboard } from '../../hooks/useCopyToClipboard';
|
||||||
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
|
|
||||||
import Identicon from '../../components/ui/identicon';
|
import Identicon from '../../components/ui/identicon';
|
||||||
import { I18nContext } from '../../contexts/i18n';
|
import { I18nContext } from '../../contexts/i18n';
|
||||||
import { useTokenTracker } from '../../hooks/useTokenTracker';
|
import { useTokenTracker } from '../../hooks/useTokenTracker';
|
||||||
@ -25,6 +24,7 @@ import {
|
|||||||
TEXT_ALIGN,
|
TEXT_ALIGN,
|
||||||
OVERFLOW_WRAP,
|
OVERFLOW_WRAP,
|
||||||
} from '../../helpers/constants/design-system';
|
} from '../../helpers/constants/design-system';
|
||||||
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
|
|
||||||
export default function TokenDetailsPage() {
|
export default function TokenDetailsPage() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store';
|
|||||||
import { fireEvent } from '@testing-library/react';
|
import { fireEvent } from '@testing-library/react';
|
||||||
import { renderWithProvider } from '../../../test/lib/render-helpers';
|
import { renderWithProvider } from '../../../test/lib/render-helpers';
|
||||||
import Identicon from '../../components/ui/identicon/identicon.component';
|
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';
|
import TokenDetailsPage from './token-details-page';
|
||||||
|
|
||||||
const testTokenAddress = '0xaD6D458402F60fD3Bd25163575031ACDce07538A';
|
const testTokenAddress = '0xaD6D458402F60fD3Bd25163575031ACDce07538A';
|
||||||
|
@ -25,7 +25,7 @@ import {
|
|||||||
getMaximumGasTotalInHexWei,
|
getMaximumGasTotalInHexWei,
|
||||||
getMinimumGasTotalInHexWei,
|
getMinimumGasTotalInHexWei,
|
||||||
} from '../../shared/modules/gas.utils';
|
} from '../../shared/modules/gas.utils';
|
||||||
import { isEqualCaseInsensitive } from '../helpers/utils/util';
|
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
|
||||||
import { getAveragePriceEstimateInHexWEI } from './custom-gas';
|
import { getAveragePriceEstimateInHexWEI } from './custom-gas';
|
||||||
import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors';
|
import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors';
|
||||||
import { checkNetworkAndAccountSupports1559 } from '.';
|
import { checkNetworkAndAccountSupports1559 } from '.';
|
||||||
|
@ -33,11 +33,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,
|
|
||||||
getAccountByAddress,
|
|
||||||
isEqualCaseInsensitive,
|
|
||||||
} from '../helpers/utils/util';
|
|
||||||
import {
|
import {
|
||||||
getValueFromWeiHex,
|
getValueFromWeiHex,
|
||||||
hexToDecimal,
|
hexToDecimal,
|
||||||
@ -60,6 +56,7 @@ import {
|
|||||||
getLedgerWebHidConnectedStatus,
|
getLedgerWebHidConnectedStatus,
|
||||||
getLedgerTransportStatus,
|
getLedgerTransportStatus,
|
||||||
} from '../ducks/app/app';
|
} 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
|
* One of the only remaining valid uses of selecting the network subkey of the
|
||||||
|
@ -9,7 +9,6 @@ import {
|
|||||||
} from '../helpers/utils/i18n-helper';
|
} from '../helpers/utils/i18n-helper';
|
||||||
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
||||||
import { getSymbolAndDecimals } from '../helpers/utils/token-util';
|
import { getSymbolAndDecimals } from '../helpers/utils/token-util';
|
||||||
import { isEqualCaseInsensitive } from '../helpers/utils/util';
|
|
||||||
import switchDirection from '../helpers/utils/switch-direction';
|
import switchDirection from '../helpers/utils/switch-direction';
|
||||||
import {
|
import {
|
||||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||||
@ -35,6 +34,7 @@ import {
|
|||||||
LEDGER_USB_VENDOR_ID,
|
LEDGER_USB_VENDOR_ID,
|
||||||
} from '../../shared/constants/hardware-wallets';
|
} from '../../shared/constants/hardware-wallets';
|
||||||
import { parseSmartTransactionsError } from '../pages/swaps/swaps.util';
|
import { parseSmartTransactionsError } from '../pages/swaps/swaps.util';
|
||||||
|
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
|
||||||
import * as actionConstants from './actionConstants';
|
import * as actionConstants from './actionConstants';
|
||||||
|
|
||||||
let background = null;
|
let background = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user