From 669ab187a1618b2bd0ed105c28979c8e425a7b0e Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 10 Mar 2021 14:56:48 -0330 Subject: [PATCH 01/82] add trezor HD path for ledger wallets (#10616) Co-authored-by: Barry Gitarts --- ui/app/pages/create-account/connect-hardware/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/app/pages/create-account/connect-hardware/index.js b/ui/app/pages/create-account/connect-hardware/index.js index 4af6e501d..20aacb9aa 100644 --- a/ui/app/pages/create-account/connect-hardware/index.js +++ b/ui/app/pages/create-account/connect-hardware/index.js @@ -17,9 +17,11 @@ const U2F_ERROR = 'U2F'; const LEDGER_LIVE_PATH = `m/44'/60'/0'/0/0`; const MEW_PATH = `m/44'/60'/0'`; +const BIP44_PATH = `m/44'/60'/0'/0`; const HD_PATHS = [ { name: 'Ledger Live', value: LEDGER_LIVE_PATH }, { name: 'Legacy (MEW / MyCrypto)', value: MEW_PATH }, + { name: `BIP44 Standard (e.g. Trezor)`, value: BIP44_PATH }, ]; class ConnectHardwareForm extends Component { From 9339278d3c4490a6f4030c8da2d2ccfcfdfead08 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 10 Mar 2021 16:13:18 -0330 Subject: [PATCH 02/82] Replace logic for eth swap token in fetchQuotesAndSetQuoteState with getSwapsEthToken call (#10624) --- ui/app/ducks/swaps/swaps.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 1354596e2..50dd03bd4 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -41,7 +41,6 @@ import { decimalToHex, getValueFromWeiHex, decGWEIToHexWEI, - hexToDecimal, hexWEIToDecGWEI, } from '../../helpers/utils/conversions.util'; import { conversionLessThan } from '../../helpers/utils/conversion-util'; @@ -50,11 +49,11 @@ import { getSelectedAccount, getTokenExchangeRates, getUSDConversionRate, + getSwapsEthToken, } from '../../selectors'; import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, - ETH_SWAPS_TOKEN_OBJECT, SWAP_FAILED_ERROR, SWAPS_FETCH_ORDER_CONFLICT, } from '../../helpers/constants/swaps'; @@ -396,15 +395,7 @@ export const fetchQuotesAndSetQuoteState = ( const balanceError = getBalanceError(state); const fetchParamsFromToken = fetchParams?.metaData?.sourceTokenInfo?.symbol === 'ETH' - ? { - ...ETH_SWAPS_TOKEN_OBJECT, - string: getValueFromWeiHex({ - value: selectedAccount.balance, - numberOfDecimals: 4, - toDenomination: 'ETH', - }), - balance: hexToDecimal(selectedAccount.balance), - } + ? getSwapsEthToken(state) : fetchParams?.metaData?.sourceTokenInfo; const selectedFromToken = getFromToken(state) || fetchParamsFromToken || {}; const selectedToToken = From a29fc51838a5eabf143a9afc168eabfa55d044b4 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Wed, 10 Mar 2021 11:50:06 -0800 Subject: [PATCH 03/82] Ensure permission log will only store JSON-able data (#10524) --- app/scripts/controllers/permissions/permissionsLog.js | 6 +++--- package.json | 2 +- test/unit/app/controllers/permissions/helpers.js | 7 ++++--- yarn.lock | 5 ----- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/app/scripts/controllers/permissions/permissionsLog.js b/app/scripts/controllers/permissions/permissionsLog.js index d0ab55d23..1f1a80b5f 100644 --- a/app/scripts/controllers/permissions/permissionsLog.js +++ b/app/scripts/controllers/permissions/permissionsLog.js @@ -1,4 +1,4 @@ -import { cloneDeep } from 'lodash'; +import stringify from 'fast-safe-stringify'; import { CAVEAT_NAMES } from '../../../../shared/constants/permissions'; import { HISTORY_STORE_KEY, @@ -151,7 +151,7 @@ export default class PermissionsLogController { ? LOG_METHOD_TYPES.internal : LOG_METHOD_TYPES.restricted, origin: request.origin, - request: cloneDeep(request), + request: stringify(request, null, 2), requestTime: Date.now(), response: null, responseTime: null, @@ -174,7 +174,7 @@ export default class PermissionsLogController { return; } - entry.response = cloneDeep(response); + entry.response = stringify(response, null, 2); entry.responseTime = time; entry.success = !response.error; } diff --git a/package.json b/package.json index 690fd6096..8ce98d545 100644 --- a/package.json +++ b/package.json @@ -134,6 +134,7 @@ "extension-port-stream": "^2.0.0", "extensionizer": "^1.0.1", "fast-json-patch": "^2.0.4", + "fast-safe-stringify": "^2.0.7", "fuse.js": "^3.2.0", "globalthis": "^1.0.1", "human-standard-token-abi": "^2.0.0", @@ -175,7 +176,6 @@ "reselect": "^3.0.1", "rpc-cap": "^3.2.1", "safe-event-emitter": "^1.0.1", - "safe-json-stringify": "^1.2.0", "single-call-balance-checker-abi": "^1.0.0", "swappable-obj-proxy": "^1.1.0", "textarea-caret": "^3.0.1", diff --git a/test/unit/app/controllers/permissions/helpers.js b/test/unit/app/controllers/permissions/helpers.js index d0e4f57dd..4317ed683 100644 --- a/test/unit/app/controllers/permissions/helpers.js +++ b/test/unit/app/controllers/permissions/helpers.js @@ -1,4 +1,5 @@ import { strict as assert } from 'assert'; +import stringify from 'fast-safe-stringify'; import { noop } from './mocks'; @@ -84,9 +85,9 @@ function _validateActivityEntry(entry, req, res, methodType, success) { assert.equal(entry.method, req.method); assert.equal(entry.origin, req.origin); assert.equal(entry.methodType, methodType); - assert.deepEqual( + assert.equal( entry.request, - req, + stringify(req, null, 2), 'entry.request should equal the request', ); @@ -104,7 +105,7 @@ function _validateActivityEntry(entry, req, res, methodType, success) { assert.equal(entry.success, success); assert.deepEqual( entry.response, - res, + stringify(res, null, 2), 'entry.response should equal the response', ); } else { diff --git a/yarn.lock b/yarn.lock index 28eb70bbc..df49ca023 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22131,11 +22131,6 @@ safe-json-parse@~1.0.1: resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" integrity sha1-PnZyPjjf3aE8mx0poeB//uSzC1c= -safe-json-stringify@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" - integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" From 2ed5bafa119015049443f17bc2972c4aadab22d9 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Wed, 10 Mar 2021 14:16:44 -0600 Subject: [PATCH 04/82] remove transactionCategory in favor of more types (#10615) * remove transactionCategory in favor of more types * remove reference to STANDARD in stubs --- .../controllers/incoming-transactions.js | 4 +- app/scripts/controllers/transactions/index.js | 58 +++++--- app/scripts/migrations/053.js | 46 ++++++ app/scripts/migrations/index.js | 1 + shared/constants/transaction.js | 71 ++++----- test/data/transaction-data.json | 34 ++--- .../controllers/incoming-transactions.test.js | 12 +- test/unit/app/controllers/network/stubs.js | 7 +- .../transactions/tx-controller.test.js | 51 ++++--- test/unit/migrations/053.test.js | 136 ++++++++++++++++++ .../transaction-breakdown.container.js | 5 +- ...transaction-list-item-details.component.js | 5 +- .../transaction-list.component.js | 12 +- ui/app/ducks/swaps/swaps.js | 6 +- ui/app/helpers/constants/transactions.js | 8 +- ui/app/helpers/utils/transactions.util.js | 41 +++--- .../helpers/utils/transactions.util.test.js | 4 +- ui/app/hooks/tests/useTokenData.test.js | 8 +- .../tests/useTransactionDisplayData.test.js | 4 +- ui/app/hooks/useSwappedTokenValue.js | 10 +- ui/app/hooks/useTransactionDisplayData.js | 44 +++--- .../confirm-approve/confirm-approve.util.js | 4 +- .../confirm-transaction-base.component.js | 20 +-- .../confirm-transaction-base.container.js | 9 +- .../confirm-transaction-switch.component.js | 16 +-- .../confirm-transaction.container.js | 4 +- .../tests/confirm-transaction.test.js | 4 +- ui/app/selectors/transactions.js | 9 +- 28 files changed, 389 insertions(+), 244 deletions(-) create mode 100644 app/scripts/migrations/053.js create mode 100644 test/unit/migrations/053.test.js diff --git a/app/scripts/controllers/incoming-transactions.js b/app/scripts/controllers/incoming-transactions.js index b6227d984..632bd96a4 100644 --- a/app/scripts/controllers/incoming-transactions.js +++ b/app/scripts/controllers/incoming-transactions.js @@ -6,7 +6,7 @@ import { bnToHex } from '../lib/util'; import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_STATUSES, } from '../../../shared/constants/transaction'; import { @@ -296,7 +296,7 @@ export default class IncomingTransactionsController { value: bnToHex(new BN(txMeta.value)), }, hash: txMeta.hash, - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, }; } } diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index f153558d3..d6bfe48c3 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -19,7 +19,6 @@ import { import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/app/helpers/constants/error-keys'; import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/app/pages/swaps/swaps.util'; import { - TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, } from '../../../../shared/constants/transaction'; @@ -235,11 +234,10 @@ 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._determineTransactionCategory` after `generateTxMeta`. + method `this._determineTransactionType` after `generateTxMeta`. */ let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams, - type: TRANSACTION_TYPES.STANDARD, }); if (origin === 'metamask') { @@ -265,11 +263,10 @@ export default class TransactionController extends EventEmitter { txMeta.origin = origin; - const { - transactionCategory, - getCodeResponse, - } = await this._determineTransactionCategory(txParams); - txMeta.transactionCategory = transactionCategory; + const { type, getCodeResponse } = await this._determineTransactionType( + txParams, + ); + txMeta.type = type; // ensure value txMeta.txParams.value = txMeta.txParams.value @@ -347,7 +344,7 @@ export default class TransactionController extends EventEmitter { return {}; } else if ( txMeta.txParams.to && - txMeta.transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER + txMeta.type === TRANSACTION_TYPES.SENT_ETHER ) { // if there's data in the params, but there's no contract code, it's not a valid transaction if (txMeta.txParams.data) { @@ -581,7 +578,7 @@ export default class TransactionController extends EventEmitter { async publishTransaction(txId, rawTx) { const txMeta = this.txStateManager.getTx(txId); txMeta.rawTx = rawTx; - if (txMeta.transactionCategory === TRANSACTION_CATEGORIES.SWAP) { + if (txMeta.type === TRANSACTION_TYPES.SWAP) { const preTxBalance = await this.query.getBalance(txMeta.txParams.from); txMeta.preTxBalance = preTxBalance.toString(16); } @@ -637,7 +634,7 @@ export default class TransactionController extends EventEmitter { 'transactions#confirmTransaction - add txReceipt', ); - if (txMeta.transactionCategory === TRANSACTION_CATEGORIES.SWAP) { + if (txMeta.type === TRANSACTION_TYPES.SWAP) { const postTxBalance = await this.query.getBalance(txMeta.txParams.from); const latestTxMeta = this.txStateManager.getTx(txId); @@ -812,10 +809,27 @@ export default class TransactionController extends EventEmitter { } /** - Returns a "type" for a transaction out of the following list: simpleSend, tokenTransfer, tokenApprove, - contractDeployment, contractMethodCall - */ - async _determineTransactionCategory(txParams) { + * @typedef { 'transfer' | 'approve' | 'transferfrom' | 'contractInteraction'| 'sentEther' } 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 { @@ -825,16 +839,16 @@ export default class TransactionController extends EventEmitter { } const tokenMethodName = [ - TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, - TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, - TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM, + TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, ].find((methodName) => methodName === name && name.toLowerCase()); let result; if (data && tokenMethodName) { result = tokenMethodName; } else if (data && !to) { - result = TRANSACTION_CATEGORIES.DEPLOY_CONTRACT; + result = TRANSACTION_TYPES.DEPLOY_CONTRACT; } let code; @@ -849,11 +863,11 @@ export default class TransactionController extends EventEmitter { const codeIsEmpty = !code || code === '0x' || code === '0x0'; result = codeIsEmpty - ? TRANSACTION_CATEGORIES.SENT_ETHER - : TRANSACTION_CATEGORIES.CONTRACT_INTERACTION; + ? TRANSACTION_TYPES.SENT_ETHER + : TRANSACTION_TYPES.CONTRACT_INTERACTION; } - return { transactionCategory: result, getCodeResponse: code }; + return { type: result, getCodeResponse: code }; } /** diff --git a/app/scripts/migrations/053.js b/app/scripts/migrations/053.js new file mode 100644 index 000000000..f9d4dc55c --- /dev/null +++ b/app/scripts/migrations/053.js @@ -0,0 +1,46 @@ +import { cloneDeep } from 'lodash'; +import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; + +const version = 53; + +/** + * Deprecate transactionCategory and consolidate on 'type' + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; + }, +}; + +function transformState(state) { + const transactions = state?.TransactionController?.transactions; + const incomingTransactions = + state?.IncomingTransactionsController?.incomingTransactions; + if (Array.isArray(transactions)) { + transactions.forEach((transaction) => { + if ( + transaction.type !== TRANSACTION_TYPES.RETRY && + transaction.type !== TRANSACTION_TYPES.CANCEL + ) { + transaction.type = transaction.transactionCategory; + } + delete transaction.transactionCategory; + }); + } + if (incomingTransactions) { + const incomingTransactionsEntries = Object.entries(incomingTransactions); + incomingTransactionsEntries.forEach(([key, transaction]) => { + delete transaction.transactionCategory; + state.IncomingTransactionsController.incomingTransactions[key] = { + ...transaction, + type: TRANSACTION_TYPES.INCOMING, + }; + }); + } + return state; +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index b4368c1b5..b30410202 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -57,6 +57,7 @@ const migrations = [ require('./050').default, require('./051').default, require('./052').default, + require('./053').default, ]; export default migrations; diff --git a/shared/constants/transaction.js b/shared/constants/transaction.js index 833463a60..87c33ebca 100644 --- a/shared/constants/transaction.js +++ b/shared/constants/transaction.js @@ -1,8 +1,26 @@ /** * Transaction Type is a MetaMask construct used internally * @typedef {Object} TransactionTypes - * @property {'standard'} STANDARD - A standard transaction, usually the first with - * a given nonce + * @property {'transfer'} TOKEN_METHOD_TRANSFER - A token transaction where the user + * is sending tokens that they own to another address + * @property {'transferfrom'} TOKEN_METHOD_TRANSFER_FROM - A token transaction + * transferring tokens from an account that the sender has an allowance of. + * For more information on allowances, see the approve type. + * @property {'approve'} TOKEN_METHOD_APPROVE - A token transaction requesting an + * allowance of the token to spend on behalf of the user + * @property {'incoming'} INCOMING - An incoming (deposit) transaction + * @property {'sentEther'} SENT_ETHER - A transaction sending ether to a recipient + * @property {'contractInteraction'} CONTRACT_INTERACTION - A transaction that is + * interacting with a smart contract's methods that we have not treated as a special + * case, such as approve, transfer, and transferfrom + * @property {'contractDeployment'} DEPLOY_CONTRACT - A transaction that deployed + * a smart contract + * @property {'swap'} SWAP - A transaction swapping one token for another through + * MetaMask Swaps + * @property {'swapApproval'} SWAP_APPROVAL - Similar to the approve type, a swap + * approval is a special case of ERC20 approve method that requests an allowance of + * the token to spend on behalf of the user for the MetaMask Swaps contract. The first + * swap for any token will have an accompanying swapApproval transaction. * @property {'cancel'} CANCEL - A transaction submitted with the same nonce as a * previous transaction, a higher gas price and a zeroed out send amount. Useful * for users who accidentally send to erroneous addresses or if they send too much. @@ -16,9 +34,17 @@ * @type {TransactionTypes} */ export const TRANSACTION_TYPES = { - STANDARD: 'standard', CANCEL: 'cancel', RETRY: 'retry', + TOKEN_METHOD_TRANSFER: 'transfer', + TOKEN_METHOD_TRANSFER_FROM: 'transferfrom', + TOKEN_METHOD_APPROVE: 'approve', + INCOMING: 'incoming', + SENT_ETHER: 'sentEther', + CONTRACT_INTERACTION: 'contractInteraction', + DEPLOY_CONTRACT: 'contractDeployment', + SWAP: 'swap', + SWAP_APPROVAL: 'swapApproval', }; /** @@ -53,45 +79,6 @@ export const TRANSACTION_STATUSES = { CONFIRMED: 'confirmed', }; -/** - * @typedef {Object} TransactionCategories - * @property {'transfer'} TOKEN_METHOD_TRANSFER - A token transaction where the user - * is sending tokens that they own to another address - * @property {'transferfrom'} TOKEN_METHOD_TRANSFER_FROM - A token transaction - * transferring tokens from an account that the sender has an allowance of. - * For more information on allowances, see the approve category. - * @property {'approve'} TOKEN_METHOD_APPROVE - A token transaction requesting an - * allowance of the token to spend on behalf of the user - * @property {'incoming'} INCOMING - An incoming (deposit) transaction - * @property {'sentEther'} SENT_ETHER - A transaction sending ether to a recipient - * @property {'contractInteraction'} CONTRACT_INTERACTION - A transaction that is - * interacting with a smart contract's methods that we have not treated as a special - * case, such as approve, transfer, and transferfrom - * @property {'contractDeployment'} DEPLOY_CONTRACT - A transaction that deployed - * a smart contract - * @property {'swap'} SWAP - A transaction swapping one token for another through - * MetaMask Swaps - * @property {'swapApproval'} SWAP_APPROVAL - Similar to the approve category, a swap - * approval is a special case of ERC20 approve method that requests an allowance of - * the token to spend on behalf of the user for the MetaMask Swaps contract. The first - * swap for any token will have an accompanying swapApproval transaction. - */ - -/** - * @type {TransactionCategories} - */ -export const TRANSACTION_CATEGORIES = { - TOKEN_METHOD_TRANSFER: 'transfer', - TOKEN_METHOD_TRANSFER_FROM: 'transferfrom', - TOKEN_METHOD_APPROVE: 'approve', - INCOMING: 'incoming', - SENT_ETHER: 'sentEther', - CONTRACT_INTERACTION: 'contractInteraction', - DEPLOY_CONTRACT: 'contractDeployment', - SWAP: 'swap', - SWAP_APPROVAL: 'swapApproval', -}; - /** * Transaction Group Status is a MetaMask construct to track the status of groups * of transactions. diff --git a/test/data/transaction-data.json b/test/data/transaction-data.json index e5ae1f5b8..37e7659dd 100644 --- a/test/data/transaction-data.json +++ b/test/data/transaction-data.json @@ -15,9 +15,8 @@ "gas": "0x5208", "gasPrice": "0x2540be400" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 12, @@ -76,9 +75,8 @@ "gas": "0x5208", "gasPrice": "0x2540be400" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 12, @@ -142,9 +140,8 @@ "gas": "0x5208", "gasPrice": "0x2540be400" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 0, @@ -203,9 +200,8 @@ "gas": "0x5208", "gasPrice": "0x2540be400" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 0, @@ -269,9 +265,8 @@ "gas": "0x5208", "gasPrice": "0x306dc4200" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 0, @@ -331,9 +326,8 @@ "gas": "0x5208", "gasPrice": "0x306dc4200" }, - "type": "standard", "origin": "metamask", - "transactionCategory": "sentEther", + "type": "sentEther", "nonceDetails": { "params": { "highestLocallyConfirmed": 0, @@ -398,7 +392,7 @@ "value": "0x1043561a882930000" }, "hash": "0x5ca26d1cdcabef1ac2ad5b2b38604c9ced65d143efc7525f848c46f28e0e4116", - "transactionCategory": "incoming" + "type": "incoming" }, "primaryTransaction": { "blockNumber": "6477257", @@ -415,7 +409,7 @@ "value": "0x1043561a882930000" }, "hash": "0x5ca26d1cdcabef1ac2ad5b2b38604c9ced65d143efc7525f848c46f28e0e4116", - "transactionCategory": "incoming" + "type": "incoming" }, "hasRetried": false, "hasCancelled": false @@ -436,7 +430,7 @@ "value": "0x0" }, "hash": "0xa42b2b433e5bd2616b52e30792aedb6a3c374a752a95d43d99e2a8b143937889", - "transactionCategory": "incoming" + "type": "incoming" }, "primaryTransaction": { "blockNumber": "6454493", @@ -453,7 +447,7 @@ "value": "0x0" }, "hash": "0xa42b2b433e5bd2616b52e30792aedb6a3c374a752a95d43d99e2a8b143937889", - "transactionCategory": "incoming" + "type": "incoming" }, "hasRetried": false, "hasCancelled": false @@ -474,7 +468,7 @@ "value": "0xde0b6b3a7640000" }, "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", - "transactionCategory": "incoming" + "type": "incoming" }, "primaryTransaction": { "blockNumber": "6195526", @@ -491,7 +485,7 @@ "value": "0xde0b6b3a7640000" }, "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", - "transactionCategory": "incoming" + "type": "incoming" }, "hasRetried": false, "hasCancelled": false @@ -514,7 +508,7 @@ "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", "destinationTokenSymbol": "ABC", "sourceTokenSymbol": "ETH", - "transactionCategory": "swap" + "type": "swap" }, "primaryTransaction": { "blockNumber": "6195527", @@ -531,7 +525,7 @@ "value": "0xde0b6b3a7640000" }, "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", - "transactionCategory": "swap", + "type": "swap", "destinationTokenSymbol": "ABC", "destinationTokenAddress": "0xabca64466f257793eaa52fcfff5066894b76a149", "sourceTokenSymbol": "ETH" diff --git a/test/unit/app/controllers/incoming-transactions.test.js b/test/unit/app/controllers/incoming-transactions.test.js index d476d18cb..af59bdd92 100644 --- a/test/unit/app/controllers/incoming-transactions.test.js +++ b/test/unit/app/controllers/incoming-transactions.test.js @@ -16,7 +16,7 @@ import { ROPSTEN_NETWORK_ID, } from '../../../../shared/constants/network'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_STATUSES, } from '../../../../shared/constants/transaction'; import { NETWORK_EVENTS } from '../../../../app/scripts/controllers/network'; @@ -276,7 +276,7 @@ describe('IncomingTransactionsController', function () { chainId: ROPSTEN_CHAIN_ID, status: TRANSACTION_STATUSES.CONFIRMED, time: 16000000000000000, - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, txParams: { from: '0xfake', gas: '0x0', @@ -620,7 +620,7 @@ describe('IncomingTransactionsController', function () { chainId: ROPSTEN_CHAIN_ID, status: TRANSACTION_STATUSES.CONFIRMED, time: 16000000000000000, - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, txParams: { from: '0xfake', gas: '0x0', @@ -775,7 +775,7 @@ describe('IncomingTransactionsController', function () { chainId: ROPSTEN_CHAIN_ID, status: TRANSACTION_STATUSES.CONFIRMED, time: 16000000000000000, - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, txParams: { from: '0xfake', gas: '0x0', @@ -1362,7 +1362,7 @@ describe('IncomingTransactionsController', function () { value: '0xf', }, hash: '0xg', - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, }); }); @@ -1408,7 +1408,7 @@ describe('IncomingTransactionsController', function () { value: '0xf', }, hash: '0xg', - transactionCategory: TRANSACTION_CATEGORIES.INCOMING, + type: TRANSACTION_TYPES.INCOMING, }); }); }); diff --git a/test/unit/app/controllers/network/stubs.js b/test/unit/app/controllers/network/stubs.js index 421e125a8..4021bcddd 100644 --- a/test/unit/app/controllers/network/stubs.js +++ b/test/unit/app/controllers/network/stubs.js @@ -1,5 +1,4 @@ import { - TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, } from '../../../../../shared/constants/transaction'; @@ -14,7 +13,7 @@ export const txMetaStub = { metamaskNetworkId: '4', status: TRANSACTION_STATUSES.UNAPPROVED, time: 1572395156620, - transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, + type: TRANSACTION_TYPES.SENT_ETHER, txParams: { from: '0xf231d46dd78806e1dd93442cf33c7671f8538748', gas: '0x5208', @@ -22,7 +21,6 @@ export const txMetaStub = { to: '0xf231d46dd78806e1dd93442cf33c7671f8538748', value: '0x0', }, - type: TRANSACTION_TYPES.STANDARD, }, [ { @@ -196,7 +194,7 @@ export const txMetaStub = { status: TRANSACTION_STATUSES.SUBMITTED, submittedTime: 1572395158570, time: 1572395156620, - transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, + type: TRANSACTION_TYPES.SENT_ETHER, txParams: { from: '0xf231d46dd78806e1dd93442cf33c7671f8538748', gas: '0x5208', @@ -205,6 +203,5 @@ export const txMetaStub = { to: '0xf231d46dd78806e1dd93442cf33c7671f8538748', value: '0x0', }, - type: TRANSACTION_TYPES.STANDARD, v: '0x2c', }; diff --git a/test/unit/app/controllers/transactions/tx-controller.test.js b/test/unit/app/controllers/transactions/tx-controller.test.js index 2dacf3c6a..e6119a948 100644 --- a/test/unit/app/controllers/transactions/tx-controller.test.js +++ b/test/unit/app/controllers/transactions/tx-controller.test.js @@ -11,7 +11,6 @@ import { getTestAccounts, } from '../../../../stub/provider'; import { - TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, } from '../../../../../shared/constants/transaction'; @@ -776,76 +775,76 @@ describe('Transaction Controller', function () { }); }); - describe('#_determineTransactionCategory', function () { - it('should return a simple send transactionCategory when to is truthy but data is falsy', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, + type: TRANSACTION_TYPES.SENT_ETHER, getCodeResponse: null, }); }); - it('should return a token transfer transactionCategory when data is for the respective method call', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, + type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, getCodeResponse: undefined, }); }); - it('should return a token approve transactionCategory when data is for the respective method call', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, + type: TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, getCodeResponse: undefined, }); }); - it('should return a contract deployment transactionCategory when to is falsy and there is data', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.DEPLOY_CONTRACT, + type: TRANSACTION_TYPES.DEPLOY_CONTRACT, getCodeResponse: undefined, }); }); - it('should return a simple send transactionCategory with a 0x getCodeResponse when there is data and but the to address is not a contract address', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, + type: TRANSACTION_TYPES.SENT_ETHER, getCodeResponse: '0x', }); }); - it('should return a simple send transactionCategory with a null getCodeResponse when to is truthy and there is data and but getCode returns an error', async function () { - const result = await txController._determineTransactionCategory({ + 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, { - transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, + type: TRANSACTION_TYPES.SENT_ETHER, getCodeResponse: null, }); }); - it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is truthy and there is data and it is not a token transaction', async function () { + 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', @@ -875,17 +874,17 @@ describe('Transaction Controller', function () { }), getParticipateInMetrics: () => false, }); - const result = await _txController._determineTransactionCategory({ + const result = await _txController._determineTransactionType({ to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: 'abd', }); assert.deepEqual(result, { - transactionCategory: TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + type: TRANSACTION_TYPES.CONTRACT_INTERACTION, getCodeResponse: '0x0a', }); }); - it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is a contract address and data is falsy', async function () { + 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', @@ -915,12 +914,12 @@ describe('Transaction Controller', function () { }), getParticipateInMetrics: () => false, }); - const result = await _txController._determineTransactionCategory({ + const result = await _txController._determineTransactionType({ to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '', }); assert.deepEqual(result, { - transactionCategory: TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + type: TRANSACTION_TYPES.CONTRACT_INTERACTION, getCodeResponse: '0x0a', }); }); diff --git a/test/unit/migrations/053.test.js b/test/unit/migrations/053.test.js new file mode 100644 index 000000000..92d3055bc --- /dev/null +++ b/test/unit/migrations/053.test.js @@ -0,0 +1,136 @@ +import { strict as assert } from 'assert'; +import migration53 from '../../../app/scripts/migrations/053'; +import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; + +describe('migration #53', function () { + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 52, + }, + data: {}, + }; + + const newStorage = await migration53.migrate(oldStorage); + assert.deepEqual(newStorage.meta, { + version: 53, + }); + }); + + it('should update type of standard transactions', async function () { + const oldStorage = { + meta: {}, + data: { + TransactionController: { + transactions: [ + { + type: TRANSACTION_TYPES.CANCEL, + transactionCategory: TRANSACTION_TYPES.SENT_ETHER, + txParams: { foo: 'bar' }, + }, + { + type: 'standard', + transactionCategory: TRANSACTION_TYPES.SENT_ETHER, + txParams: { foo: 'bar' }, + }, + { + type: 'standard', + transactionCategory: TRANSACTION_TYPES.CONTRACT_INTERACTION, + txParams: { foo: 'bar' }, + }, + { + type: TRANSACTION_TYPES.RETRY, + transactionCategory: TRANSACTION_TYPES.SENT_ETHER, + txParams: { foo: 'bar' }, + }, + ], + }, + IncomingTransactionsController: { + incomingTransactions: { + test: { + transactionCategory: 'incoming', + txParams: { + foo: 'bar', + }, + }, + }, + }, + foo: 'bar', + }, + }; + + const newStorage = await migration53.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + TransactionController: { + transactions: [ + { type: TRANSACTION_TYPES.CANCEL, txParams: { foo: 'bar' } }, + { type: TRANSACTION_TYPES.SENT_ETHER, txParams: { foo: 'bar' } }, + { + type: TRANSACTION_TYPES.CONTRACT_INTERACTION, + txParams: { foo: 'bar' }, + }, + { type: TRANSACTION_TYPES.RETRY, txParams: { foo: 'bar' } }, + ], + }, + IncomingTransactionsController: { + incomingTransactions: { + test: { + type: 'incoming', + txParams: { + foo: 'bar', + }, + }, + }, + }, + foo: 'bar', + }); + }); + + it('should do nothing if transactions state does not exist', async function () { + const oldStorage = { + meta: {}, + data: { + TransactionController: { + bar: 'baz', + }, + IncomingTransactionsController: { + foo: 'baz', + }, + foo: 'bar', + }, + }; + + const newStorage = await migration53.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); + + it('should do nothing if transactions state is empty', async function () { + const oldStorage = { + meta: {}, + data: { + TransactionController: { + transactions: [], + bar: 'baz', + }, + IncomingTransactionsController: { + incomingTransactions: {}, + baz: 'bar', + }, + foo: 'bar', + }, + }; + + const newStorage = await migration53.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); + + it('should do nothing if state is empty', async function () { + const oldStorage = { + meta: {}, + data: {}, + }; + + const newStorage = await migration53.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js index 1ab3b4818..d8f39cdd7 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js @@ -6,19 +6,16 @@ import { } from '../../../selectors'; import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util'; import { sumHexes } from '../../../helpers/utils/transactions.util'; -import { TRANSACTION_CATEGORIES } from '../../../../../shared/constants/transaction'; import TransactionBreakdown from './transaction-breakdown.component'; const mapStateToProps = (state, ownProps) => { - const { transaction, transactionCategory } = ownProps; + const { transaction, isTokenApprove } = ownProps; const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {}, } = transaction; const { showFiatInTestnets } = getPreferences(state); const isMainnet = getIsMainnet(state); - const isTokenApprove = - transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE; const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas; diff --git a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js index 3c93ff921..c1256d7cb 100644 --- a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js @@ -10,6 +10,7 @@ import Tooltip from '../../ui/tooltip'; import Copy from '../../ui/icon/copy-icon.component'; import Popover from '../../ui/popover'; import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils'; +import { TRANSACTION_TYPES } from '../../../../../shared/constants/transaction'; export default class TransactionListItemDetails extends PureComponent { static contextTypes = { @@ -156,7 +157,7 @@ export default class TransactionListItemDetails extends PureComponent { } = this.props; const { primaryTransaction: transaction, - initialTransaction: { transactionCategory }, + initialTransaction: { type }, } = transactionGroup; const { hash } = transaction; @@ -255,7 +256,7 @@ export default class TransactionListItemDetails extends PureComponent {
{ }; const tokenTransactionFilter = ({ - initialTransaction: { - transactionCategory, - destinationTokenSymbol, - sourceTokenSymbol, - }, + initialTransaction: { type, destinationTokenSymbol, sourceTokenSymbol }, }) => { - if (TOKEN_CATEGORY_HASH[transactionCategory]) { + if (TOKEN_CATEGORY_HASH[type]) { return false; - } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP) { + } else if (type === TRANSACTION_TYPES.SWAP) { return destinationTokenSymbol === 'ETH' || sourceTokenSymbol === 'ETH'; } return true; diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 50dd03bd4..8fbc372f5 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -57,7 +57,7 @@ import { SWAP_FAILED_ERROR, SWAPS_FETCH_ORDER_CONFLICT, } from '../../helpers/constants/swaps'; -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; const GAS_PRICES_LOADING_STATES = { INITIAL: 'INITIAL', @@ -671,7 +671,7 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { updateTransaction( { ...approveTxMeta, - transactionCategory: TRANSACTION_CATEGORIES.SWAP_APPROVAL, + type: TRANSACTION_TYPES.SWAP_APPROVAL, sourceTokenSymbol: sourceTokenInfo.symbol, }, true, @@ -712,7 +712,7 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { ...tradeTxMeta, sourceTokenSymbol: sourceTokenInfo.symbol, destinationTokenSymbol: destinationTokenInfo.symbol, - transactionCategory: TRANSACTION_CATEGORIES.SWAP, + type: TRANSACTION_TYPES.SWAP, destinationTokenDecimals: destinationTokenInfo.decimals, destinationTokenAddress: destinationTokenInfo.address, swapMetaData, diff --git a/ui/app/helpers/constants/transactions.js b/ui/app/helpers/constants/transactions.js index f349b3ae6..288d497e2 100644 --- a/ui/app/helpers/constants/transactions.js +++ b/ui/app/helpers/constants/transactions.js @@ -1,5 +1,5 @@ import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_STATUSES, } from '../../../../shared/constants/transaction'; @@ -15,7 +15,7 @@ export const PRIORITY_STATUS_HASH = { }; export const TOKEN_CATEGORY_HASH = { - [TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE]: true, - [TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER]: true, - [TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM]: true, + [TRANSACTION_TYPES.TOKEN_METHOD_APPROVE]: true, + [TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER]: true, + [TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM]: true, }; diff --git a/ui/app/helpers/utils/transactions.util.js b/ui/app/helpers/utils/transactions.util.js index ad2af9162..99ce94fe5 100644 --- a/ui/app/helpers/utils/transactions.util.js +++ b/ui/app/helpers/utils/transactions.util.js @@ -5,10 +5,9 @@ import log from 'loglevel'; import { addHexPrefix } from '../../../../app/scripts/lib/util'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, - TRANSACTION_TYPES, } from '../../../../shared/constants/transaction'; import fetchWithCache from './fetch-with-cache'; @@ -112,15 +111,15 @@ export function getFourBytePrefix(data = '') { /** * Given an transaction category, returns a boolean which indicates whether the transaction is calling an erc20 token method * - * @param {string} transactionCategory - The category of transaction being evaluated + * @param {TRANSACTION_TYPES[keyof TRANSACTION_TYPES]} type - The type of transaction being evaluated * @returns {boolean} whether the transaction is calling an erc20 token method */ -export function isTokenMethodAction(transactionCategory) { +export function isTokenMethodAction(type) { return [ - TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, - TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, - TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM, - ].includes(transactionCategory); + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + ].includes(type); } export function getLatestSubmittedTxWithNonce( @@ -197,39 +196,37 @@ export function getStatusKey(transaction) { * * This will throw an error if the transaction category is unrecognized and no default is provided. * @param {function} t - The translation function - * @param {TRANSACTION_CATEGORIES[keyof TRANSACTION_CATEGORIES]} transactionCategory - The transaction category constant + * @param {TRANSACTION_TYPES[keyof TRANSACTION_TYPES]} type - The transaction type constant * @returns {string} The transaction category title */ -export function getTransactionCategoryTitle(t, transactionCategory) { - switch (transactionCategory) { - case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER: { +export function getTransactionTypeTitle(t, type) { + switch (type) { + case TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER: { return t('transfer'); } - case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM: { + case TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM: { return t('transferFrom'); } - case TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE: { + case TRANSACTION_TYPES.TOKEN_METHOD_APPROVE: { return t('approve'); } - case TRANSACTION_CATEGORIES.SENT_ETHER: { + case TRANSACTION_TYPES.SENT_ETHER: { return t('sentEther'); } - case TRANSACTION_CATEGORIES.CONTRACT_INTERACTION: { + case TRANSACTION_TYPES.CONTRACT_INTERACTION: { return t('contractInteraction'); } - case TRANSACTION_CATEGORIES.DEPLOY_CONTRACT: { + case TRANSACTION_TYPES.DEPLOY_CONTRACT: { return t('contractDeployment'); } - case TRANSACTION_CATEGORIES.SWAP: { + case TRANSACTION_TYPES.SWAP: { return t('swap'); } - case TRANSACTION_CATEGORIES.SWAP_APPROVAL: { + case TRANSACTION_TYPES.SWAP_APPROVAL: { return t('swapApproval'); } default: { - throw new Error( - `Unrecognized transaction category: ${transactionCategory}`, - ); + throw new Error(`Unrecognized transaction type: ${type}`); } } } diff --git a/ui/app/helpers/utils/transactions.util.test.js b/ui/app/helpers/utils/transactions.util.test.js index 386edd6f8..9bd410cdb 100644 --- a/ui/app/helpers/utils/transactions.util.test.js +++ b/ui/app/helpers/utils/transactions.util.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, } from '../../../../shared/constants/transaction'; @@ -14,7 +14,7 @@ describe('Transactions utils', function () { ); assert.ok(tokenData); const { name, args } = tokenData; - assert.strictEqual(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER); + assert.strictEqual(name, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER); const to = args._to; const value = args._value.toString(); assert.strictEqual(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706'); diff --git a/ui/app/hooks/tests/useTokenData.test.js b/ui/app/hooks/tests/useTokenData.test.js index 593176105..24fbed5af 100644 --- a/ui/app/hooks/tests/useTokenData.test.js +++ b/ui/app/hooks/tests/useTokenData.test.js @@ -2,14 +2,14 @@ import assert from 'assert'; import { ethers } from 'ethers'; import { renderHook } from '@testing-library/react-hooks'; import { useTokenData } from '../useTokenData'; -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; const tests = [ { data: '0xa9059cbb000000000000000000000000ffe5bc4e8f1f969934d773fa67da095d2e491a970000000000000000000000000000000000000000000000000000000000003a98', tokenData: { - name: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, + name: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, args: [ '0xffe5bc4e8f1f969934d773fa67da095d2e491a97', ethers.BigNumber.from(15000), @@ -20,7 +20,7 @@ const tests = [ data: '0xa9059cbb000000000000000000000000ffe5bc4e8f1f969934d773fa67da095d2e491a9700000000000000000000000000000000000000000000000000000000000061a8', tokenData: { - name: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, + name: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, args: [ '0xffe5bc4e8f1f969934d773fa67da095d2e491a97', ethers.BigNumber.from(25000), @@ -31,7 +31,7 @@ const tests = [ data: '0xa9059cbb000000000000000000000000ffe5bc4e8f1f969934d773fa67da095d2e491a970000000000000000000000000000000000000000000000000000000000002710', tokenData: { - name: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, + name: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, args: [ '0xffe5bc4e8f1f969934d773fa67da095d2e491a97', ethers.BigNumber.from(10000), diff --git a/ui/app/hooks/tests/useTransactionDisplayData.test.js b/ui/app/hooks/tests/useTransactionDisplayData.test.js index 96a24c08b..13079628e 100644 --- a/ui/app/hooks/tests/useTransactionDisplayData.test.js +++ b/ui/app/hooks/tests/useTransactionDisplayData.test.js @@ -19,7 +19,7 @@ import { getMessage } from '../../helpers/utils/i18n-helper'; import messages from '../../../../app/_locales/en/messages.json'; import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, } from '../../../../shared/constants/transaction'; @@ -106,7 +106,7 @@ const expectedResults = [ }, { title: 'Swap ETH to ABC', - category: TRANSACTION_CATEGORIES.SWAP, + category: TRANSACTION_TYPES.SWAP, subtitle: '', subtitleContainsOrigin: false, date: 'May 12, 2020', diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index f48e3de69..64d51fe8a 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -1,4 +1,4 @@ -import { TRANSACTION_CATEGORIES } from '../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util'; import { useTokenFiatAmount } from './useTokenFiatAmount'; @@ -25,7 +25,7 @@ import { useTokenFiatAmount } from './useTokenFiatAmount'; export function useSwappedTokenValue(transactionGroup, currentAsset) { const { symbol, decimals, address } = currentAsset; const { primaryTransaction, initialTransaction } = transactionGroup; - const { transactionCategory } = initialTransaction; + const { type } = initialTransaction; const { from: senderAddress } = initialTransaction.txParams || {}; const isViewingReceivedTokenFromSwap = @@ -34,8 +34,7 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { primaryTransaction.destinationTokenSymbol === 'ETH'); const swapTokenValue = - transactionCategory === TRANSACTION_CATEGORIES.SWAP && - isViewingReceivedTokenFromSwap + type === TRANSACTION_TYPES.SWAP && isViewingReceivedTokenFromSwap ? getSwapsTokensReceivedFromTxMeta( primaryTransaction.destinationTokenSymbol, initialTransaction, @@ -43,8 +42,7 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { senderAddress, decimals, ) - : transactionCategory === TRANSACTION_CATEGORIES.SWAP && - primaryTransaction.swapTokenValue; + : type === TRANSACTION_TYPES.SWAP && primaryTransaction.swapTokenValue; const isNegative = typeof swapTokenValue === 'string' diff --git a/ui/app/hooks/useTransactionDisplayData.js b/ui/app/hooks/useTransactionDisplayData.js index 18b0e7c39..370516170 100644 --- a/ui/app/hooks/useTransactionDisplayData.js +++ b/ui/app/hooks/useTransactionDisplayData.js @@ -2,7 +2,7 @@ import { useSelector } from 'react-redux'; import { getKnownMethodData } from '../selectors/selectors'; import { getStatusKey, - getTransactionCategoryTitle, + getTransactionTypeTitle, } from '../helpers/utils/transactions.util'; import { camelCaseToCapitalize } from '../helpers/utils/common.util'; import { PRIMARY, SECONDARY } from '../helpers/constants/common'; @@ -18,7 +18,7 @@ import { } from '../helpers/constants/transactions'; import { getTokens } from '../ducks/metamask/metamask'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, } from '../../../shared/constants/transaction'; @@ -62,7 +62,7 @@ export function useTransactionDisplayData(transactionGroup) { const t = useI18nContext(); const { initialTransaction, primaryTransaction } = transactionGroup; // initialTransaction contains the data we need to derive the primary purpose of this transaction group - const { transactionCategory } = initialTransaction; + const { type } = initialTransaction; const { from: senderAddress, to } = initialTransaction.txParams || {}; @@ -85,7 +85,7 @@ export function useTransactionDisplayData(transactionGroup) { // This value is used to determine whether we should look inside txParams.data // to pull out and render token related information - const isTokenCategory = TOKEN_CATEGORY_HASH[transactionCategory]; + const isTokenCategory = TOKEN_CATEGORY_HASH[type]; // these values are always instantiated because they are either // used by or returned from hooks. Hooks must be called at the top level, @@ -145,12 +145,12 @@ export function useTransactionDisplayData(transactionGroup) { // 6. Swap // 7. Swap Approval - if (transactionCategory === null || transactionCategory === undefined) { + if (type === null || type === undefined) { category = TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST; title = t('signatureRequest'); subtitle = origin; subtitleContainsOrigin = true; - } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP) { + } else if (type === TRANSACTION_TYPES.SWAP) { category = TRANSACTION_GROUP_CATEGORIES.SWAP; title = t('swapTokenToToken', [ initialTransaction.sourceTokenSymbol, @@ -170,48 +170,43 @@ export function useTransactionDisplayData(transactionGroup) { } else { prefix = '-'; } - } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP_APPROVAL) { + } else if (type === TRANSACTION_TYPES.SWAP_APPROVAL) { category = TRANSACTION_GROUP_CATEGORIES.APPROVAL; title = t('swapApproval', [primaryTransaction.sourceTokenSymbol]); subtitle = origin; subtitleContainsOrigin = true; primarySuffix = primaryTransaction.sourceTokenSymbol; - } else if ( - transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE - ) { + } else if (type === TRANSACTION_TYPES.TOKEN_METHOD_APPROVE) { category = TRANSACTION_GROUP_CATEGORIES.APPROVAL; prefix = ''; title = t('approveSpendLimit', [token?.symbol || t('token')]); subtitle = origin; subtitleContainsOrigin = true; } else if ( - transactionCategory === TRANSACTION_CATEGORIES.DEPLOY_CONTRACT || - transactionCategory === TRANSACTION_CATEGORIES.CONTRACT_INTERACTION + type === TRANSACTION_TYPES.DEPLOY_CONTRACT || + type === TRANSACTION_TYPES.CONTRACT_INTERACTION ) { category = TRANSACTION_GROUP_CATEGORIES.INTERACTION; - const transactionCategoryTitle = getTransactionCategoryTitle( - t, - transactionCategory, - ); + const transactionTypeTitle = getTransactionTypeTitle(t, type); title = (methodData?.name && camelCaseToCapitalize(methodData.name)) || - transactionCategoryTitle; + transactionTypeTitle; subtitle = origin; subtitleContainsOrigin = true; - } else if (transactionCategory === TRANSACTION_CATEGORIES.INCOMING) { + } else if (type === TRANSACTION_TYPES.INCOMING) { category = TRANSACTION_GROUP_CATEGORIES.RECEIVE; title = t('receive'); prefix = ''; subtitle = t('fromAddress', [shortenAddress(senderAddress)]); } else if ( - transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM || - transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER + type === TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM || + type === TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER ) { category = TRANSACTION_GROUP_CATEGORIES.SEND; title = t('sendSpecifiedTokens', [token?.symbol || t('token')]); recipientAddress = getTokenAddressParam(tokenData); subtitle = t('toAddress', [shortenAddress(recipientAddress)]); - } else if (transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER) { + } else if (type === TRANSACTION_TYPES.SENT_ETHER) { category = TRANSACTION_GROUP_CATEGORIES.SEND; title = t('sendETH'); subtitle = t('toAddress', [shortenAddress(recipientAddress)]); @@ -241,15 +236,12 @@ export function useTransactionDisplayData(transactionGroup) { subtitle, subtitleContainsOrigin, primaryCurrency: - transactionCategory === TRANSACTION_CATEGORIES.SWAP && isPending - ? '' - : primaryCurrency, + type === TRANSACTION_TYPES.SWAP && isPending ? '' : primaryCurrency, senderAddress, recipientAddress, secondaryCurrency: (isTokenCategory && !tokenFiatAmount) || - (transactionCategory === TRANSACTION_CATEGORIES.SWAP && - !swapTokenFiatAmount) + (type === TRANSACTION_TYPES.SWAP && !swapTokenFiatAmount) ? undefined : secondaryCurrency, displayedStatusKey, diff --git a/ui/app/pages/confirm-approve/confirm-approve.util.js b/ui/app/pages/confirm-approve/confirm-approve.util.js index e724ba58e..3345b0966 100644 --- a/ui/app/pages/confirm-approve/confirm-approve.util.js +++ b/ui/app/pages/confirm-approve/confirm-approve.util.js @@ -1,4 +1,4 @@ -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; import { decimalToHex } from '../../helpers/utils/conversions.util'; import { calcTokenValue, @@ -14,7 +14,7 @@ export function getCustomTxParamsData( if (!tokenData) { throw new Error('Invalid data'); - } else if (tokenData.name !== TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE) { + } else if (tokenData.name !== TRANSACTION_TYPES.TOKEN_METHOD_APPROVE) { throw new Error( `Invalid data; should be 'approve' method, but instead is '${tokenData.name}'`, ); diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js index d1b702df9..65af5c890 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -19,10 +19,10 @@ import { hexToDecimal } from '../../helpers/utils/conversions.util'; import AdvancedGasInputs from '../../components/app/gas-customization/advanced-gas-inputs'; import TextField from '../../components/ui/text-field'; import { - TRANSACTION_CATEGORIES, + TRANSACTION_TYPES, TRANSACTION_STATUSES, } from '../../../../shared/constants/transaction'; -import { getTransactionCategoryTitle } from '../../helpers/utils/transactions.util'; +import { getTransactionTypeTitle } from '../../helpers/utils/transactions.util'; export default class ConfirmTransactionBase extends Component { static contextTypes = { @@ -87,7 +87,7 @@ export default class ConfirmTransactionBase extends Component { advancedInlineGasShown: PropTypes.bool, insufficientBalance: PropTypes.bool, hideFiatConversion: PropTypes.bool, - transactionCategory: PropTypes.string, + type: PropTypes.string, getNextNonce: PropTypes.func, nextNonce: PropTypes.number, tryReverseResolveAddress: PropTypes.func.isRequired, @@ -218,7 +218,7 @@ export default class ConfirmTransactionBase extends Component { functionType: actionKey || getMethodName(methodData.name) || - TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + TRANSACTION_TYPES.CONTRACT_INTERACTION, origin, }, }); @@ -395,7 +395,7 @@ export default class ConfirmTransactionBase extends Component { functionType: actionKey || getMethodName(methodData.name) || - TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + TRANSACTION_TYPES.CONTRACT_INTERACTION, origin, }, }); @@ -450,7 +450,7 @@ export default class ConfirmTransactionBase extends Component { functionType: actionKey || getMethodName(methodData.name) || - TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + TRANSACTION_TYPES.CONTRACT_INTERACTION, origin, }, }); @@ -500,7 +500,7 @@ export default class ConfirmTransactionBase extends Component { functionType: actionKey || getMethodName(methodData.name) || - TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, + TRANSACTION_TYPES.CONTRACT_INTERACTION, origin, }, }); @@ -667,7 +667,7 @@ export default class ConfirmTransactionBase extends Component { customNonceValue, assetImage, unapprovedTxCount, - transactionCategory, + type, hideSenderToRecipient, showAccountInHeader, txData, @@ -690,8 +690,8 @@ export default class ConfirmTransactionBase extends Component { let functionType = getMethodName(name); if (!functionType) { - if (transactionCategory) { - functionType = getTransactionCategoryTitle(t, transactionCategory); + if (type) { + functionType = getTransactionTypeTitle(t, type); } else { functionType = t('contractInteraction'); } diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js index 69c8fa0d9..cb5332a22 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -81,12 +81,7 @@ const mapStateToProps = (state, ownProps) => { provider: { chainId }, } = metamask; const { tokenData, txData, tokenProps, nonce } = confirmTransaction; - const { - txParams = {}, - lastGasPrice, - id: transactionId, - transactionCategory, - } = txData; + const { txParams = {}, lastGasPrice, id: transactionId, type } = txData; const transaction = Object.values(unapprovedTxs).find( ({ id }) => id === (transactionId || Number(paramsTransactionId)), @@ -189,7 +184,7 @@ const mapStateToProps = (state, ownProps) => { hideSubtitle: !isMainnet && !showFiatInTestnets, hideFiatConversion: !isMainnet && !showFiatInTestnets, metaMetricsSendCount, - transactionCategory, + type, nextNonce, mostRecentOverviewPage: getMostRecentOverviewPage(state), isMainnet, diff --git a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js index 18969e233..83aa7cdbc 100644 --- a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js +++ b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js @@ -15,7 +15,7 @@ import { ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, } from '../../helpers/constants/routes'; import { MESSAGE_TYPE } from '../../../../shared/constants/app'; -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; export default class ConfirmTransactionSwitch extends Component { static propTypes = { @@ -24,29 +24,29 @@ export default class ConfirmTransactionSwitch extends Component { redirectToTransaction() { const { txData } = this.props; - const { id, txParams: { data } = {}, transactionCategory } = txData; + const { id, txParams: { data } = {}, type } = txData; - if (transactionCategory === TRANSACTION_CATEGORIES.DEPLOY_CONTRACT) { + if (type === TRANSACTION_TYPES.DEPLOY_CONTRACT) { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_DEPLOY_CONTRACT_PATH}`; return ; } - if (transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER) { + if (type === TRANSACTION_TYPES.SENT_ETHER) { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}`; return ; } if (data) { - switch (transactionCategory) { - case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER: { + switch (type) { + case TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER: { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_TOKEN_PATH}`; return ; } - case TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE: { + case TRANSACTION_TYPES.TOKEN_METHOD_APPROVE: { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_APPROVE_PATH}`; return ; } - case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM: { + case TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM: { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TRANSFER_FROM_PATH}`; return ; } diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/pages/confirm-transaction/confirm-transaction.container.js index d07665256..68ee7c3ed 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.container.js @@ -27,7 +27,7 @@ const mapStateToProps = (state, ownProps) => { const transaction = totalUnconfirmed ? unapprovedTxs[id] || unconfirmedTransactions[0] : {}; - const { id: transactionId, transactionCategory } = transaction; + const { id: transactionId, type } = transaction; return { totalUnapprovedCount: totalUnconfirmed, @@ -38,7 +38,7 @@ const mapStateToProps = (state, ownProps) => { paramsTransactionId: id && String(id), transactionId: transactionId && String(transactionId), transaction, - isTokenMethodAction: isTokenMethodAction(transactionCategory), + isTokenMethodAction: isTokenMethodAction(type), }; }; diff --git a/ui/app/selectors/tests/confirm-transaction.test.js b/ui/app/selectors/tests/confirm-transaction.test.js index 8f36689cb..647318a9d 100644 --- a/ui/app/selectors/tests/confirm-transaction.test.js +++ b/ui/app/selectors/tests/confirm-transaction.test.js @@ -4,7 +4,7 @@ import { KOVAN_NETWORK_ID, MAINNET_CHAIN_ID, } from '../../../../shared/constants/network'; -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; import { unconfirmedTransactionsCountSelector, sendTokenTokenAmountAndToAddressSelector, @@ -52,7 +52,7 @@ describe('Confirm Transaction Selector', function () { const state = { confirmTransaction: { tokenData: { - name: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, + name: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, args: getEthersArrayLikeFromObj({ _to: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', _value: { toString: () => '1' }, diff --git a/ui/app/selectors/transactions.js b/ui/app/selectors/transactions.js index 3fdcbfe41..dd418c655 100644 --- a/ui/app/selectors/transactions.js +++ b/ui/app/selectors/transactions.js @@ -6,7 +6,6 @@ import { import { hexToDecimal } from '../helpers/utils/conversions.util'; import txHelper from '../../lib/tx-helper'; import { - TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, } from '../../../shared/constants/transaction'; @@ -229,13 +228,9 @@ export const nonceSortedTransactionsSelector = createSelector( status, type, time: txTime, - transactionCategory, } = transaction; - if ( - typeof nonce === 'undefined' || - transactionCategory === TRANSACTION_CATEGORIES.INCOMING - ) { + if (typeof nonce === 'undefined' || type === TRANSACTION_TYPES.INCOMING) { const transactionGroup = { transactions: [transaction], initialTransaction: transaction, @@ -244,7 +239,7 @@ export const nonceSortedTransactionsSelector = createSelector( hasCancelled: false, }; - if (transactionCategory === TRANSACTION_CATEGORIES.INCOMING) { + if (type === TRANSACTION_TYPES.INCOMING) { incomingTransactionGroups.push(transactionGroup); } else { insertTransactionGroupByTime( From 7aaf1c4eb3b8a73655cf08af1f98fc1ced0c1c58 Mon Sep 17 00:00:00 2001 From: ryanml Date: Wed, 10 Mar 2021 16:43:34 -0700 Subject: [PATCH 05/82] Removing double click bug from delete custom network modal (#10628) Fixes MetaMask/metamask-extension#10626 --- ui/app/components/app/dropdowns/network-dropdown.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/components/app/dropdowns/network-dropdown.js b/ui/app/components/app/dropdowns/network-dropdown.js index c0d010517..bc04a2fed 100644 --- a/ui/app/components/app/dropdowns/network-dropdown.js +++ b/ui/app/components/app/dropdowns/network-dropdown.js @@ -25,6 +25,7 @@ const notToggleElementClassnames = [ 'network-indicator', 'network-caret', 'network-component', + 'modal-container__footer-button', ]; const DROP_DOWN_MENU_ITEM_STYLE = { From 90bfaf6ac23c895e96171c9431fea23ea184a383 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Thu, 11 Mar 2021 12:07:41 -0600 Subject: [PATCH 06/82] Hide zero balance tokens at useTokenTracker layer (#10630) --- .../components/app/token-list/token-list.js | 11 +++------ ui/app/ducks/metamask/metamask.js | 3 --- ui/app/hooks/useTokenTracker.js | 23 +++++++++++++------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/ui/app/components/app/token-list/token-list.js b/ui/app/components/app/token-list/token-list.js index 3fcc71d38..9d0fdc77e 100644 --- a/ui/app/components/app/token-list/token-list.js +++ b/ui/app/components/app/token-list/token-list.js @@ -10,10 +10,7 @@ import { getAssetImages, getShouldHideZeroBalanceTokens, } from '../../../selectors'; -import { - getTokens, - getTokensWithBalance, -} from '../../../ducks/metamask/metamask'; +import { getTokens } from '../../../ducks/metamask/metamask'; export default function TokenList({ onTokenClick }) { const t = useI18nContext(); @@ -25,13 +22,11 @@ export default function TokenList({ onTokenClick }) { // from the background so it has a new reference with each background update, // even if the tokens haven't changed const tokens = useSelector(getTokens, isEqual); - const tokensWithBalance = useSelector(getTokensWithBalance, isEqual); - const { loading, tokensWithBalances } = useTokenTracker( - shouldHideZeroBalanceTokens ? tokensWithBalance : tokens, + tokens, true, + shouldHideZeroBalanceTokens, ); - if (loading) { return (
state.metamask.unconnectedAccountAlertShownOrigins; export const getTokens = (state) => state.metamask.tokens; - -export const getTokensWithBalance = (state) => - state.metamask.tokens.filter((token) => Number(token.balance) > 0); diff --git a/ui/app/hooks/useTokenTracker.js b/ui/app/hooks/useTokenTracker.js index ea7892b08..2b2411d1e 100644 --- a/ui/app/hooks/useTokenTracker.js +++ b/ui/app/hooks/useTokenTracker.js @@ -4,21 +4,30 @@ import { useSelector } from 'react-redux'; import { getCurrentNetwork, getSelectedAddress } from '../selectors'; import { useEqualityCheck } from './useEqualityCheck'; -export function useTokenTracker(tokens, includeFailedTokens = false) { +export function useTokenTracker( + tokens, + includeFailedTokens = false, + hideZeroBalanceTokens = false, +) { const network = useSelector(getCurrentNetwork); const userAddress = useSelector(getSelectedAddress); - const [loading, setLoading] = useState(() => tokens?.length >= 0); const [tokensWithBalances, setTokensWithBalances] = useState([]); const [error, setError] = useState(null); const tokenTracker = useRef(null); const memoizedTokens = useEqualityCheck(tokens); - const updateBalances = useCallback((tokenWithBalances) => { - setTokensWithBalances(tokenWithBalances); - setLoading(false); - setError(null); - }, []); + const updateBalances = useCallback( + (tokenWithBalances) => { + const matchingTokens = hideZeroBalanceTokens + ? tokenWithBalances.filter((token) => Number(token.balance) > 0) + : tokenWithBalances; + setTokensWithBalances(matchingTokens); + setLoading(false); + setError(null); + }, + [hideZeroBalanceTokens], + ); const showError = useCallback((err) => { setError(err); From 84b1379b40f547ca047e2a9294068c9dd8da7992 Mon Sep 17 00:00:00 2001 From: Niranjana Binoy <43930900+NiranjanaBinoy@users.noreply.github.com> Date: Fri, 12 Mar 2021 10:20:33 -0500 Subject: [PATCH 07/82] Setting balance to 0x0 when the original value is undefined (#10634) --- app/scripts/lib/account-tracker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index 53c6a5c8d..cb4ec51de 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -286,7 +286,7 @@ export default class AccountTracker { return; } addresses.forEach((address, index) => { - const balance = bnToHex(result[index]); + const balance = result[index] ? bnToHex(result[index]) : '0x0'; accounts[address] = { address, balance }; }); this.store.updateState({ accounts }); From b21cc5660fc7e7977916c82ec2117ea906973f2e Mon Sep 17 00:00:00 2001 From: Shane Date: Fri, 12 Mar 2021 11:26:07 -0800 Subject: [PATCH 08/82] fix: speedup cancellation (#10579) fixes #7305 --- app/scripts/controllers/transactions/index.js | 4 +- app/scripts/metamask-controller.js | 3 +- .../gas-modal-page-container.container.js | 12 +- ...gas-modal-page-container-container.test.js | 224 +----------------- .../cancel-transaction.container.js | 40 ++-- .../app/sidebars/sidebar.component.js | 4 +- .../transaction-list-item.component.js | 16 +- .../hooks/tests/useCancelTransaction.test.js | 51 +++- .../hooks/tests/useRetryTransaction.test.js | 44 ++++ ui/app/hooks/useCancelTransaction.js | 58 ++++- ui/app/hooks/useRetryTransaction.js | 6 +- ui/app/store/actions.js | 3 +- 12 files changed, 193 insertions(+), 272 deletions(-) diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index d6bfe48c3..fe88b897e 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -385,7 +385,7 @@ export default class TransactionController extends EventEmitter { * @param {string} [customGasPrice] - the hex value to use for the cancel transaction * @returns {txMeta} */ - async createCancelTransaction(originalTxId, customGasPrice) { + async createCancelTransaction(originalTxId, customGasPrice, customGasLimit) { const originalTxMeta = this.txStateManager.getTx(originalTxId); const { txParams } = originalTxMeta; const { gasPrice: lastGasPrice, from, nonce } = txParams; @@ -398,7 +398,7 @@ export default class TransactionController extends EventEmitter { from, to: from, nonce, - gas: '0x5208', + gas: customGasLimit || '0x5208', value: '0x0', gasPrice: newGasPrice, }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d0cf9c1a0..f2df85dc5 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1858,10 +1858,11 @@ export default class MetamaskController extends EventEmitter { * @param {string} [customGasPrice] - the hex value to use for the cancel transaction * @returns {Object} MetaMask state */ - async createCancelTransaction(originalTxId, customGasPrice) { + async createCancelTransaction(originalTxId, customGasPrice, customGasLimit) { await this.txController.createCancelTransaction( originalTxId, customGasPrice, + customGasLimit, ); const state = await this.getState(); return state; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 136fdccc8..4d57502b2 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -61,7 +61,7 @@ const mapStateToProps = (state, ownProps) => { const { currentNetworkTxList, send } = state.metamask; const { modalState: { props: modalProps } = {} } = state.appState.modal || {}; const { txData = {} } = modalProps || {}; - const { transaction = {} } = ownProps; + const { transaction = {}, onSubmit } = ownProps; const selectedTransaction = currentNetworkTxList.find( ({ id }) => id === (transaction.id || txData.id), ); @@ -77,7 +77,8 @@ const mapStateToProps = (state, ownProps) => { value: sendToken ? '0x0' : send.amount, }; - const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = txParams; + const { gasPrice: currentGasPrice, gas: currentGasLimit } = txParams; + const value = ownProps.transaction?.txParams?.value || txParams.value; const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice; const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit || '0x5208'; @@ -175,6 +176,7 @@ const mapStateToProps = (state, ownProps) => { tokenBalance: getTokenBalance(state), conversionRate, value, + onSubmit, }; }; @@ -253,6 +255,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...otherDispatchProps, ...ownProps, onSubmit: (gasLimit, gasPrice) => { + if (ownProps.onSubmit) { + dispatchHideSidebar(); + dispatchCancelAndClose(); + ownProps.onSubmit(gasLimit, gasPrice); + return; + } if (isConfirm) { const updatedTx = { ...transaction, diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 0ba5aabbc..9863582e2 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -1,9 +1,7 @@ import assert from 'assert'; import proxyquire from 'proxyquire'; import sinon from 'sinon'; -import { TRANSACTION_STATUSES } from '../../../../../../../shared/constants/transaction'; -let mapStateToProps; let mapDispatchToProps; let mergeProps; @@ -25,8 +23,7 @@ const sendActionSpies = { proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { - connect: (ms, md, mp) => { - mapStateToProps = ms; + connect: (_, md, mp) => { mapDispatchToProps = md; mergeProps = mp; return () => ({}); @@ -48,225 +45,6 @@ proxyquire('../gas-modal-page-container.container.js', { }); describe('gas-modal-page-container container', function () { - describe('mapStateToProps()', function () { - it('should map the correct properties to props', function () { - const baseMockState = { - appState: { - modal: { - modalState: { - props: { - hideBasic: true, - txData: { - id: 34, - }, - }, - }, - }, - }, - metamask: { - send: { - gasLimit: '16', - gasPrice: '32', - amount: '64', - maxModeOn: false, - }, - currentCurrency: 'abc', - conversionRate: 50, - usdConversionRate: 123, - preferences: { - showFiatInTestnets: false, - }, - provider: { - type: 'mainnet', - chainId: '0x1', - }, - currentNetworkTxList: [ - { - id: 34, - txParams: { - gas: '0x1600000', - gasPrice: '0x3200000', - value: '0x640000000000000', - }, - }, - ], - }, - gas: { - basicEstimates: { - blockTime: 12, - safeLow: 2, - }, - customData: { - limit: 'aaaaaaaa', - price: 'ffffffff', - }, - priceAndTimeEstimates: [ - { gasprice: 3, expectedTime: 31 }, - { gasprice: 4, expectedTime: 62 }, - { gasprice: 5, expectedTime: 93 }, - { gasprice: 6, expectedTime: 124 }, - ], - }, - confirmTransaction: { - txData: { - txParams: { - gas: '0x1600000', - gasPrice: '0x3200000', - value: '0x640000000000000', - }, - }, - }, - }; - const baseExpectedResult = { - balance: '0x0', - isConfirm: true, - customGasPrice: 4.294967295, - customGasLimit: 2863311530, - newTotalFiat: '637.41', - conversionRate: 50, - customModalGasLimitInHex: 'aaaaaaaa', - customModalGasPriceInHex: 'ffffffff', - customPriceIsExcessive: false, - customGasTotal: 'aaaaaaa955555556', - customPriceIsSafe: true, - gasPriceButtonGroupProps: { - buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', - gasButtonInfo: 'mockRenderableBasicEstimateData:4', - }, - hideBasic: true, - infoRowProps: { - originalTotalFiat: '637.41', - originalTotalEth: '12.748189 ETH', - newTotalFiat: '637.41', - newTotalEth: '12.748189 ETH', - sendAmount: '0.45036 ETH', - transactionFee: '12.297829 ETH', - }, - insufficientBalance: true, - isSpeedUp: false, - isRetry: false, - txId: 34, - isMainnet: true, - maxModeOn: false, - sendToken: null, - tokenBalance: '0x0', - transaction: { - id: 34, - }, - value: '0x640000000000000', - }; - const baseMockOwnProps = { transaction: { id: 34 } }; - const tests = [ - { - mockState: baseMockState, - expectedResult: baseExpectedResult, - mockOwnProps: baseMockOwnProps, - }, - { - mockState: { - ...baseMockState, - metamask: { - ...baseMockState.metamask, - balance: '0xfffffffffffffffffffff', - }, - }, - expectedResult: { - ...baseExpectedResult, - balance: '0xfffffffffffffffffffff', - insufficientBalance: false, - }, - mockOwnProps: baseMockOwnProps, - }, - { - mockState: baseMockState, - mockOwnProps: { - ...baseMockOwnProps, - transaction: { id: 34, status: TRANSACTION_STATUSES.SUBMITTED }, - }, - expectedResult: { - ...baseExpectedResult, - isSpeedUp: true, - transaction: { id: 34 }, - }, - }, - { - mockState: { - ...baseMockState, - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: false, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'rinkeby', - chainId: '0x4', - }, - }, - }, - mockOwnProps: baseMockOwnProps, - expectedResult: { - ...baseExpectedResult, - infoRowProps: { - ...baseExpectedResult.infoRowProps, - newTotalFiat: '', - }, - isMainnet: false, - }, - }, - { - mockState: { - ...baseMockState, - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: true, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'rinkeby', - chainId: '0x4', - }, - }, - }, - mockOwnProps: baseMockOwnProps, - expectedResult: { - ...baseExpectedResult, - isMainnet: false, - }, - }, - { - mockState: { - ...baseMockState, - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: true, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'mainnet', - chainId: '0x1', - }, - }, - }, - mockOwnProps: baseMockOwnProps, - expectedResult: baseExpectedResult, - }, - ]; - - let result; - tests.forEach(({ mockState, mockOwnProps, expectedResult }) => { - result = mapStateToProps(mockState, mockOwnProps); - assert.deepStrictEqual(result, expectedResult); - }); - }); - }); - describe('mapDispatchToProps()', function () { let dispatchSpy; let mapDispatchToPropsObject; diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js index 687986fa7..f05ecdf51 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js @@ -1,47 +1,40 @@ import { connect } from 'react-redux'; import { compose } from 'redux'; -import { multiplyCurrencies } from '../../../../helpers/utils/conversion-util'; import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; import { showModal, createCancelTransaction } from '../../../../store/actions'; -import { getHexGasTotal } from '../../../../helpers/utils/confirm-tx.util'; -import { addHexPrefix } from '../../../../../../app/scripts/lib/util'; import CancelTransaction from './cancel-transaction.component'; const mapStateToProps = (state, ownProps) => { const { metamask } = state; - const { transactionId, originalGasPrice } = ownProps; + const { + transactionId, + originalGasPrice, + newGasFee, + defaultNewGasPrice, + gasLimit, + } = ownProps; const { currentNetworkTxList } = metamask; const transaction = currentNetworkTxList.find( ({ id }) => id === transactionId, ); const transactionStatus = transaction ? transaction.status : ''; - const defaultNewGasPrice = addHexPrefix( - multiplyCurrencies(originalGasPrice, 1.1, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 10, - }), - ); - - const newGasFee = getHexGasTotal({ - gasPrice: defaultNewGasPrice, - gasLimit: '0x5208', - }); - return { transactionId, transactionStatus, originalGasPrice, defaultNewGasPrice, newGasFee, + gasLimit, }; }; const mapDispatchToProps = (dispatch) => { return { - createCancelTransaction: (txId, customGasPrice) => { - return dispatch(createCancelTransaction(txId, customGasPrice)); + createCancelTransaction: (txId, customGasPrice, customGasLimit) => { + return dispatch( + createCancelTransaction(txId, customGasPrice, customGasLimit), + ); }, showTransactionConfirmedModal: () => dispatch(showModal({ name: 'TRANSACTION_CONFIRMED' })), @@ -49,7 +42,12 @@ const mapDispatchToProps = (dispatch) => { }; const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { transactionId, defaultNewGasPrice, ...restStateProps } = stateProps; + const { + transactionId, + defaultNewGasPrice, + gasLimit, + ...restStateProps + } = stateProps; // eslint-disable-next-line no-shadow const { createCancelTransaction, ...restDispatchProps } = dispatchProps; @@ -58,7 +56,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...restDispatchProps, ...ownProps, createCancelTransaction: () => - createCancelTransaction(transactionId, defaultNewGasPrice), + createCancelTransaction(transactionId, defaultNewGasPrice, gasLimit), }; }; diff --git a/ui/app/components/app/sidebars/sidebar.component.js b/ui/app/components/app/sidebars/sidebar.component.js index 7a31f2be4..7b385db22 100644 --- a/ui/app/components/app/sidebars/sidebar.component.js +++ b/ui/app/components/app/sidebars/sidebar.component.js @@ -30,12 +30,12 @@ export default class Sidebar extends Component { renderSidebarContent() { const { type, sidebarProps = {} } = this.props; - const { transaction = {} } = sidebarProps; + const { transaction = {}, onSubmit } = sidebarProps; switch (type) { case 'customize-gas': return (
- +
); default: diff --git a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js index ec29e04d6..d3f957904 100644 --- a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js @@ -118,13 +118,21 @@ export default function TransactionListItem({ ); - }, [shouldShowSpeedUp, isUnapproved, t, isPending, retryTransaction]); + }, [ + shouldShowSpeedUp, + isUnapproved, + t, + isPending, + retryTransaction, + hasCancelled, + cancelTransaction, + ]); return ( <> diff --git a/ui/app/hooks/tests/useCancelTransaction.test.js b/ui/app/hooks/tests/useCancelTransaction.test.js index 28957eb9c..f88b3cee8 100644 --- a/ui/app/hooks/tests/useCancelTransaction.test.js +++ b/ui/app/hooks/tests/useCancelTransaction.test.js @@ -7,6 +7,7 @@ import { getConversionRate, getSelectedAccount } from '../../selectors'; import { useCancelTransaction } from '../useCancelTransaction'; import { showModal } from '../../store/actions'; import { increaseLastGasPrice } from '../../helpers/utils/confirm-tx.util'; +import * as actionConstants from '../../store/actionConstants'; describe('useCancelTransaction', function () { let useSelector; @@ -46,7 +47,7 @@ describe('useCancelTransaction', function () { ); assert.strictEqual(result.current[0], false); }); - it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { + it(`should return a function that opens the gas sidebar onsubmit kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ); @@ -55,12 +56,35 @@ describe('useCancelTransaction', function () { preventDefault: () => undefined, stopPropagation: () => undefined, }); + const dispatchAction = dispatch.args; + + // calls customize-gas sidebar + // also check type= customize-gas + assert.strictEqual( + dispatchAction[dispatchAction.length - 1][0].type, + actionConstants.SIDEBAR_OPEN, + ); + + assert.strictEqual( + dispatchAction[dispatchAction.length - 1][0].value.props.transaction + .id, + transactionId, + ); + + // call onSubmit myself + dispatchAction[dispatchAction.length - 1][0].value.props.onSubmit( + '0x5208', + '0x1', + ); + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', transactionId, - originalGasPrice, + newGasFee: '0x5208', + defaultNewGasPrice: '0x1', + gasLimit: '0x5208', }), ), true, @@ -98,7 +122,7 @@ describe('useCancelTransaction', function () { ); assert.strictEqual(result.current[0], true); }); - it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { + it(`should return a function that opens the gas sidebar onsubmit kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ); @@ -107,12 +131,31 @@ describe('useCancelTransaction', function () { preventDefault: () => undefined, stopPropagation: () => undefined, }); + const dispatchAction = dispatch.args; + + assert.strictEqual( + dispatchAction[dispatchAction.length - 1][0].type, + actionConstants.SIDEBAR_OPEN, + ); + assert.strictEqual( + dispatchAction[dispatchAction.length - 1][0].value.props.transaction + .id, + transactionId, + ); + + dispatchAction[dispatchAction.length - 1][0].value.props.onSubmit( + '0x5208', + '0x1', + ); + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', transactionId, - originalGasPrice, + newGasFee: '0x5208', + defaultNewGasPrice: '0x1', + gasLimit: '0x5208', }), ), true, diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/tests/useRetryTransaction.test.js index 52be98fc1..aba5d0009 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/tests/useRetryTransaction.test.js @@ -64,6 +64,50 @@ describe('useRetryTransaction', function () { ); }); + it('should handle cancelled or multiple speedup transactions', async function () { + const cancelledTransaction = { + initialTransaction: { + ...transactions[0].initialTransaction, + txParams: { + ...transactions[0].initialTransaction.txParams, + }, + }, + primaryTransaction: { + ...transactions[0].primaryTransaction, + txParams: { + from: '0xee014609ef9e09776ac5fe00bdbfef57bcdefebb', + gas: '0x5308', + gasPrice: '0x77359400', + nonce: '0x3', + to: '0xabca64466f257793eaa52fcfff5066894b76a149', + value: '0x0', + }, + }, + transactions: [ + { + submittedTime: new Date() - 5001, + }, + ], + hasRetried: false, + }; + + const { result } = renderHook(() => + useRetryTransaction(cancelledTransaction, true), + ); + const retry = result.current; + await retry(event); + assert.strictEqual( + dispatch.calledWith( + showSidebar({ + transitionName: 'sidebar-left', + type: 'customize-gas', + props: { transaction: cancelledTransaction.primaryTransaction }, + }), + ), + true, + ); + }); + after(function () { sinon.restore(); }); diff --git a/ui/app/hooks/useCancelTransaction.js b/ui/app/hooks/useCancelTransaction.js index 1ad4c12f8..da4312d2a 100644 --- a/ui/app/hooks/useCancelTransaction.js +++ b/ui/app/hooks/useCancelTransaction.js @@ -1,12 +1,18 @@ import { useDispatch, useSelector } from 'react-redux'; import { useCallback } from 'react'; -import { showModal } from '../store/actions'; +import { addHexPrefix } from 'ethereumjs-util'; +import { showModal, showSidebar } from '../store/actions'; import { isBalanceSufficient } from '../pages/send/send.utils'; import { getHexGasTotal, increaseLastGasPrice, } from '../helpers/utils/confirm-tx.util'; import { getConversionRate, getSelectedAccount } from '../selectors'; +import { + setCustomGasLimit, + setCustomGasPriceForRetry, +} from '../ducks/gas/gas.duck'; +import { multiplyCurrencies } from '../helpers/utils/conversion-util'; /** * Determine whether a transaction can be cancelled and provide a method to @@ -19,27 +25,61 @@ import { getConversionRate, getSelectedAccount } from '../selectors'; * @return {[boolean, Function]} */ export function useCancelTransaction(transactionGroup) { - const { primaryTransaction, initialTransaction } = transactionGroup; + const { primaryTransaction } = transactionGroup; const gasPrice = primaryTransaction.txParams?.gasPrice?.startsWith('-') ? '0x0' : primaryTransaction.txParams?.gasPrice; - const { id } = initialTransaction; + const transaction = primaryTransaction; const dispatch = useDispatch(); const selectedAccount = useSelector(getSelectedAccount); const conversionRate = useSelector(getConversionRate); + const defaultNewGasPrice = addHexPrefix( + multiplyCurrencies(gasPrice, 1.1, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 10, + }), + ); + const cancelTransaction = useCallback( (event) => { event.stopPropagation(); - + dispatch(setCustomGasLimit('0x5208')); + dispatch(setCustomGasPriceForRetry(defaultNewGasPrice)); + const tx = { + ...transaction, + txParams: { + ...transaction.txParams, + gas: '0x5208', + value: '0x0', + }, + }; return dispatch( - showModal({ - name: 'CANCEL_TRANSACTION', - transactionId: id, - originalGasPrice: gasPrice, + showSidebar({ + transitionName: 'sidebar-left', + type: 'customize-gas', + props: { + transaction: tx, + onSubmit: (newGasLimit, newGasPrice) => { + const userCustomizedGasTotal = getHexGasTotal({ + gasPrice: newGasPrice, + gasLimit: newGasLimit, + }); + dispatch( + showModal({ + name: 'CANCEL_TRANSACTION', + newGasFee: userCustomizedGasTotal, + transactionId: transaction.id, + defaultNewGasPrice: newGasPrice, + gasLimit: newGasLimit, + }), + ); + }, + }, }), ); }, - [dispatch, id, gasPrice], + [dispatch, transaction, defaultNewGasPrice], ); const hasEnoughCancelGas = diff --git a/ui/app/hooks/useRetryTransaction.js b/ui/app/hooks/useRetryTransaction.js index 9081ea44d..0f1532014 100644 --- a/ui/app/hooks/useRetryTransaction.js +++ b/ui/app/hooks/useRetryTransaction.js @@ -16,7 +16,7 @@ import { useMetricEvent } from './useMetricEvent'; * @return {Function} */ export function useRetryTransaction(transactionGroup) { - const { primaryTransaction, initialTransaction } = transactionGroup; + const { primaryTransaction } = transactionGroup; // Signature requests do not have a txParams, but this hook is called indiscriminately const gasPrice = primaryTransaction.txParams?.gasPrice; const trackMetricsEvent = useMetricEvent({ @@ -34,7 +34,7 @@ export function useRetryTransaction(transactionGroup) { trackMetricsEvent(); await dispatch(fetchBasicGasEstimates); - const transaction = initialTransaction; + const transaction = primaryTransaction; const increasedGasPrice = increaseLastGasPrice(gasPrice); await dispatch( setCustomGasPriceForRetry( @@ -50,7 +50,7 @@ export function useRetryTransaction(transactionGroup) { }), ); }, - [dispatch, trackMetricsEvent, initialTransaction, gasPrice], + [dispatch, trackMetricsEvent, gasPrice, primaryTransaction], ); return retryTransaction; diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index 06e4d84b7..8b613f0a5 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -1483,7 +1483,7 @@ export function clearPendingTokens() { }; } -export function createCancelTransaction(txId, customGasPrice) { +export function createCancelTransaction(txId, customGasPrice, customGasLimit) { log.debug('background.cancelTransaction'); let newTxId; @@ -1492,6 +1492,7 @@ export function createCancelTransaction(txId, customGasPrice) { background.createCancelTransaction( txId, customGasPrice, + customGasLimit, (err, newState) => { if (err) { dispatch(displayWarning(err.message)); From 661948cd5b5fa3b5f1294fab4de4ede2da33af9f Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Fri, 12 Mar 2021 14:41:58 -0600 Subject: [PATCH 09/82] no more node:console (#10640) --- jsconfig.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 jsconfig.json diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 000000000..d0e8e66fc --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,3 @@ +{ + "exclude": ["node:console"] +} From 3d4dfc74a870ce159d5b1b8733c40388b9a10fe5 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Fri, 12 Mar 2021 16:23:26 -0600 Subject: [PATCH 10/82] prefer chainId over networkId in most cases (#10594) --- app/scripts/lib/buy-eth-url.js | 36 ++++++++----- app/scripts/metamask-controller.js | 54 ++++++------------- shared/constants/network.js | 2 + test/unit/app/buy-eth-url.test.js | 14 +++-- .../loading-network-screen.component.js | 6 +-- .../loading-network-screen.container.js | 6 +-- .../deposit-ether-modal.component.js | 16 +++--- .../deposit-ether-modal.container.js | 13 +++-- .../app/network-display/network-display.js | 7 +-- ui/app/helpers/utils/util.js | 27 +++++++--- ui/app/hooks/useTokenTracker.js | 10 ++-- ui/app/pages/routes/routes.component.js | 9 ++-- ui/app/pages/routes/routes.container.js | 3 +- .../add-recipient/add-recipient.js | 6 +-- ui/app/pages/send/send.component.js | 12 ++--- ui/app/pages/send/send.container.js | 4 +- .../pages/send/tests/send-component.test.js | 20 ++++--- ui/app/selectors/confirm-transaction.js | 8 +-- ui/app/selectors/selectors.js | 36 ++++++++----- ui/app/selectors/send.js | 4 -- ui/app/selectors/tests/send.test.js | 7 --- ui/app/selectors/transactions.js | 4 +- 22 files changed, 159 insertions(+), 145 deletions(-) diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js index bf1b131f0..2cb1b0e81 100644 --- a/app/scripts/lib/buy-eth-url.js +++ b/app/scripts/lib/buy-eth-url.js @@ -1,18 +1,26 @@ +import { + GOERLI_CHAIN_ID, + KOVAN_CHAIN_ID, + MAINNET_CHAIN_ID, + RINKEBY_CHAIN_ID, + ROPSTEN_CHAIN_ID, +} from '../../../shared/constants/network'; + /** * Gives the caller a url at which the user can acquire eth, depending on the network they are in * * @param {Object} opts - Options required to determine the correct url - * @param {string} opts.network - The network for which to return a url - * @param {string} opts.address - The address the bought ETH should be sent to. Only relevant if network === '1'. - * @returns {string|undefined} The url at which the user can access ETH, while in the given network. If the passed - * network does not match any of the specified cases, or if no network is given, returns undefined. + * @param {string} opts.chainId - The chainId for which to return a url + * @param {string} opts.address - The address the bought ETH should be sent to. Only relevant if chainId === '0x1'. + * @returns {string|undefined} The url at which the user can access ETH, while in the given chain. If the passed + * chainId does not match any of the specified cases, or if no chainId is given, returns undefined. * */ -export default function getBuyEthUrl({ network, address, service }) { +export default function getBuyEthUrl({ chainId, address, service }) { // default service by network if not specified if (!service) { // eslint-disable-next-line no-param-reassign - service = getDefaultServiceForNetwork(network); + service = getDefaultServiceForChain(chainId); } switch (service) { @@ -33,21 +41,21 @@ export default function getBuyEthUrl({ network, address, service }) { } } -function getDefaultServiceForNetwork(network) { - switch (network) { - case '1': +function getDefaultServiceForChain(chainId) { + switch (chainId) { + case MAINNET_CHAIN_ID: return 'wyre'; - case '3': + case ROPSTEN_CHAIN_ID: return 'metamask-faucet'; - case '4': + case RINKEBY_CHAIN_ID: return 'rinkeby-faucet'; - case '42': + case KOVAN_CHAIN_ID: return 'kovan-faucet'; - case '5': + case GOERLI_CHAIN_ID: return 'goerli-faucet'; default: throw new Error( - `No default cryptocurrency exchange or faucet for networkId: "${network}"`, + `No default cryptocurrency exchange or faucet for chainId: "${chainId}"`, ); } } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f2df85dc5..9eaaf17f7 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -24,7 +24,6 @@ import { CurrencyRateController, PhishingController, } from '@metamask/controllers'; -import { getBackgroundMetaMetricState } from '../../ui/app/selectors'; import { TRANSACTION_STATUSES } from '../../shared/constants/transaction'; import { MAINNET_CHAIN_ID } from '../../shared/constants/network'; import ComposableObservableStore from './lib/ComposableObservableStore'; @@ -330,12 +329,23 @@ export default class MetamaskController extends EventEmitter { this.platform.showTransactionNotification(txMeta, rpcPrefs); const { txReceipt } = txMeta; + const metamaskState = await this.getState(); + if (txReceipt && txReceipt.status === '0x0') { - this.sendBackgroundMetaMetrics({ - action: 'Transactions', - name: 'On Chain Failure', - customVariables: { errorMessage: txMeta.simulationFails?.reason }, - }); + this.metaMetricsController.trackEvent( + { + category: 'Background', + properties: { + action: 'Transactions', + errorMessage: txMeta.simulationFails?.reason, + numberOfTokens: metamaskState.tokens.length, + numberOfAccounts: Object.keys(metamaskState.accounts).length, + }, + }, + { + matomoEvent: true, + }, + ); } } }); @@ -577,7 +587,7 @@ export default class MetamaskController extends EventEmitter { const isInitialized = Boolean(vault); return { - ...{ isInitialized }, + isInitialized, ...this.memStore.getFlatState(), }; } @@ -1058,10 +1068,6 @@ export default class MetamaskController extends EventEmitter { }); } - getCurrentNetwork = () => { - return this.networkController.store.getState().network; - }; - /** * Collects all the information that we want to share * with the mobile client for syncing purposes @@ -2414,32 +2420,6 @@ export default class MetamaskController extends EventEmitter { return nonceLock.nextNonce; } - async sendBackgroundMetaMetrics({ action, name, customVariables } = {}) { - if (!action || !name) { - throw new Error('Must provide action and name.'); - } - - const metamaskState = await this.getState(); - const additionalProperties = getBackgroundMetaMetricState({ - metamask: metamaskState, - }); - - this.metaMetricsController.trackEvent( - { - event: name, - category: 'Background', - properties: { - action, - ...additionalProperties, - ...customVariables, - }, - }, - { - matomoEvent: true, - }, - ); - } - /** * Migrate address book state from old to new chainId. * diff --git a/shared/constants/network.js b/shared/constants/network.js index a3cb2e7c9..81e87690e 100644 --- a/shared/constants/network.js +++ b/shared/constants/network.js @@ -10,12 +10,14 @@ export const ROPSTEN_NETWORK_ID = '3'; export const RINKEBY_NETWORK_ID = '4'; export const GOERLI_NETWORK_ID = '5'; export const KOVAN_NETWORK_ID = '42'; +export const LOCALHOST_NETWORK_ID = '1337'; export const MAINNET_CHAIN_ID = '0x1'; export const ROPSTEN_CHAIN_ID = '0x3'; export const RINKEBY_CHAIN_ID = '0x4'; export const GOERLI_CHAIN_ID = '0x5'; export const KOVAN_CHAIN_ID = '0x2a'; +export const LOCALHOST_CHAIN_ID = '0x539'; /** * The largest possible chain ID we can handle. diff --git a/test/unit/app/buy-eth-url.test.js b/test/unit/app/buy-eth-url.test.js index d9730b4fb..7cf50bf8f 100644 --- a/test/unit/app/buy-eth-url.test.js +++ b/test/unit/app/buy-eth-url.test.js @@ -1,20 +1,26 @@ import assert from 'assert'; import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url'; +import { + KOVAN_CHAIN_ID, + MAINNET_CHAIN_ID, + RINKEBY_CHAIN_ID, + ROPSTEN_CHAIN_ID, +} from '../../../shared/constants/network'; describe('buy-eth-url', function () { const mainnet = { - network: '1', + chainId: MAINNET_CHAIN_ID, amount: 5, address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', }; const ropsten = { - network: '3', + chainId: ROPSTEN_CHAIN_ID, }; const rinkeby = { - network: '4', + chainId: RINKEBY_CHAIN_ID, }; const kovan = { - network: '42', + chainId: KOVAN_CHAIN_ID, }; it('returns wyre url with address for network 1', function () { diff --git a/ui/app/components/app/loading-network-screen/loading-network-screen.component.js b/ui/app/components/app/loading-network-screen/loading-network-screen.component.js index 0419aed42..9097ca4d8 100644 --- a/ui/app/components/app/loading-network-screen/loading-network-screen.component.js +++ b/ui/app/components/app/loading-network-screen/loading-network-screen.component.js @@ -21,7 +21,7 @@ export default class LoadingNetworkScreen extends PureComponent { setProviderArgs: PropTypes.array, setProviderType: PropTypes.func, rollbackToPreviousProvider: PropTypes.func, - isLoadingNetwork: PropTypes.bool, + isNetworkLoading: PropTypes.bool, }; componentDidMount = () => { @@ -99,9 +99,9 @@ export default class LoadingNetworkScreen extends PureComponent { }; cancelCall = () => { - const { isLoadingNetwork } = this.props; + const { isNetworkLoading } = this.props; - if (isLoadingNetwork) { + if (isNetworkLoading) { this.setState({ showErrorScreen: true }); } }; diff --git a/ui/app/components/app/loading-network-screen/loading-network-screen.container.js b/ui/app/components/app/loading-network-screen/loading-network-screen.container.js index 5ebddae61..bfce78fbe 100644 --- a/ui/app/components/app/loading-network-screen/loading-network-screen.container.js +++ b/ui/app/components/app/loading-network-screen/loading-network-screen.container.js @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; import * as actions from '../../../store/actions'; -import { getNetworkIdentifier } from '../../../selectors'; +import { getNetworkIdentifier, isNetworkLoading } from '../../../selectors'; import LoadingNetworkScreen from './loading-network-screen.component'; const mapStateToProps = (state) => { const { loadingMessage } = state.appState; - const { provider, network } = state.metamask; + const { provider } = state.metamask; const { rpcUrl, chainId, ticker, nickname, type } = provider; const setProviderArgs = @@ -15,7 +15,7 @@ const mapStateToProps = (state) => { : [provider.type]; return { - isLoadingNetwork: network === 'loading', + isNetworkLoading: isNetworkLoading(state), loadingMessage, setProviderArgs, provider, diff --git a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js index 9b86e2b51..147a80e86 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js +++ b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { getNetworkDisplayName } from '../../../../../../app/scripts/controllers/network/util'; +import { NETWORK_TO_NAME_MAP } from '../../../../../../shared/constants/network'; import Button from '../../../ui/button'; export default class DepositEtherModal extends Component { @@ -10,7 +10,7 @@ export default class DepositEtherModal extends Component { }; static propTypes = { - network: PropTypes.string.isRequired, + chainId: PropTypes.string.isRequired, isTestnet: PropTypes.bool.isRequired, isMainnet: PropTypes.bool.isRequired, toWyre: PropTypes.func.isRequired, @@ -21,10 +21,6 @@ export default class DepositEtherModal extends Component { showAccountDetailModal: PropTypes.func.isRequired, }; - faucetRowText = (networkName) => { - return this.context.t('getEtherFromFaucet', [networkName]); - }; - goToAccountDetailsModal = () => { this.props.hideWarning(); this.props.hideModal(); @@ -89,14 +85,14 @@ export default class DepositEtherModal extends Component { render() { const { - network, + chainId, toWyre, address, toFaucet, isTestnet, isMainnet, } = this.props; - const networkName = getNetworkDisplayName(network); + const networkName = NETWORK_TO_NAME_MAP[chainId]; return (
@@ -162,9 +158,9 @@ export default class DepositEtherModal extends Component { {this.renderRow({ logo: , title: this.context.t('testFaucet'), - text: this.faucetRowText(networkName), + text: this.context.t('getEtherFromFaucet', [networkName]), buttonLabel: this.context.t('getEther'), - onButtonClick: () => toFaucet(network), + onButtonClick: () => toFaucet(chainId), hide: !isTestnet, })}
diff --git a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js index f4f5713c9..b393f4497 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js +++ b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js @@ -5,15 +5,20 @@ import { showModal, hideWarning, } from '../../../../store/actions'; -import { getIsTestnet, getIsMainnet } from '../../../../selectors/selectors'; +import { + getIsTestnet, + getIsMainnet, + getCurrentChainId, + getSelectedAddress, +} from '../../../../selectors/selectors'; import DepositEtherModal from './deposit-ether-modal.component'; function mapStateToProps(state) { return { - network: state.metamask.network, + chainId: getCurrentChainId(state), isTestnet: getIsTestnet(state), isMainnet: getIsMainnet(state), - address: state.metamask.selectedAddress, + address: getSelectedAddress(state), }; } @@ -31,7 +36,7 @@ function mapDispatchToProps(dispatch) { showAccountDetailModal: () => { dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); }, - toFaucet: (network) => dispatch(buyEth({ network })), + toFaucet: (chainId) => dispatch(buyEth({ chainId })), }; } diff --git a/ui/app/components/app/network-display/network-display.js b/ui/app/components/app/network-display/network-display.js index 65060abdf..ba83bb5c9 100644 --- a/ui/app/components/app/network-display/network-display.js +++ b/ui/app/components/app/network-display/network-display.js @@ -16,6 +16,7 @@ import { } from '../../../helpers/constants/design-system'; import Chip from '../../ui/chip/chip'; import { useI18nContext } from '../../../hooks/useI18nContext'; +import { isNetworkLoading } from '../../../selectors'; export default function NetworkDisplay({ colored, @@ -27,14 +28,14 @@ export default function NetworkDisplay({ targetNetwork, onClick, }) { + const networkIsLoading = useSelector(isNetworkLoading); const currentNetwork = useSelector((state) => ({ - network: state.metamask.network, nickname: state.metamask.provider.nickname, type: state.metamask.provider.type, })); const t = useI18nContext(); - const { network = '', nickname: networkNickname, type: networkType } = + const { nickname: networkNickname, type: networkType } = targetNetwork ?? currentNetwork; return ( @@ -45,7 +46,7 @@ export default function NetworkDisplay({ ) -> String export function formatDate(date, format = "M/d/y 'at' T") { @@ -40,14 +48,19 @@ Object.keys(valueTable).forEach((currency) => { bnTable[currency] = new ethUtil.BN(valueTable[currency], 10); }); -export function isEthNetwork(netId) { +/** + * Determines if the provided chainId is a default MetaMask chain + * @param {string} chainId - chainId to check + */ +export function isDefaultMetaMaskChain(chainId) { if ( - !netId || - netId === '1' || - netId === '3' || - netId === '4' || - netId === '42' || - netId === '1337' + !chainId || + chainId === MAINNET_CHAIN_ID || + chainId === ROPSTEN_CHAIN_ID || + chainId === RINKEBY_CHAIN_ID || + chainId === KOVAN_CHAIN_ID || + chainId === GOERLI_CHAIN_ID || + chainId === LOCALHOST_CHAIN_ID ) { return true; } diff --git a/ui/app/hooks/useTokenTracker.js b/ui/app/hooks/useTokenTracker.js index 2b2411d1e..448ec32b8 100644 --- a/ui/app/hooks/useTokenTracker.js +++ b/ui/app/hooks/useTokenTracker.js @@ -1,7 +1,7 @@ import { useState, useEffect, useRef, useCallback } from 'react'; import TokenTracker from '@metamask/eth-token-tracker'; import { useSelector } from 'react-redux'; -import { getCurrentNetwork, getSelectedAddress } from '../selectors'; +import { getCurrentChainId, getSelectedAddress } from '../selectors'; import { useEqualityCheck } from './useEqualityCheck'; export function useTokenTracker( @@ -9,7 +9,7 @@ export function useTokenTracker( includeFailedTokens = false, hideZeroBalanceTokens = false, ) { - const network = useSelector(getCurrentNetwork); + const chainId = useSelector(getCurrentChainId); const userAddress = useSelector(getSelectedAddress); const [loading, setLoading] = useState(() => tokens?.length >= 0); const [tokensWithBalances, setTokensWithBalances] = useState([]); @@ -74,14 +74,14 @@ export function useTokenTracker( // Effect to set loading state and initialize tracker when values change useEffect(() => { // This effect will only run initially and when: - // 1. network is updated, + // 1. chainId is updated, // 2. userAddress is changed, // 3. token list is updated and not equal to previous list // in any of these scenarios, we should indicate to the user that their token // values are in the process of updating by setting loading state. setLoading(true); - if (!userAddress || network === 'loading' || !global.ethereumProvider) { + if (!userAddress || chainId === undefined || !global.ethereumProvider) { // If we do not have enough information to build a TokenTracker, we exit early // When the values above change, the effect will be restarted. We also teardown // tracker because inevitably this effect will run again momentarily. @@ -98,7 +98,7 @@ export function useTokenTracker( }, [ userAddress, teardownTracker, - network, + chainId, memoizedTokens, updateBalances, buildTracker, diff --git a/ui/app/pages/routes/routes.component.js b/ui/app/pages/routes/routes.component.js index 1f5e0eef3..09b5c2fca 100644 --- a/ui/app/pages/routes/routes.component.js +++ b/ui/app/pages/routes/routes.component.js @@ -72,7 +72,7 @@ export default class Routes extends Component { loadingMessage: PropTypes.string, alertMessage: PropTypes.string, textDirection: PropTypes.string, - network: PropTypes.string, + isNetworkLoading: PropTypes.bool, provider: PropTypes.object, frequentRpcListDetail: PropTypes.array, sidebar: PropTypes.object, @@ -267,7 +267,7 @@ export default class Routes extends Component { alertMessage, textDirection, loadingMessage, - network, + isNetworkLoading, provider, frequentRpcListDetail, setMouseUserState, @@ -276,9 +276,8 @@ export default class Routes extends Component { isMouseUser, prepareToLeaveSwaps, } = this.props; - const isLoadingNetwork = network === 'loading'; const loadMessage = - loadingMessage || isLoadingNetwork + loadingMessage || isNetworkLoading ? this.getConnectingLabel(loadingMessage) : null; @@ -340,7 +339,7 @@ export default class Routes extends Component {
{isLoading && } - {!isLoading && isLoadingNetwork && } + {!isLoading && isNetworkLoading && } {this.renderRoutes()}
{isUnlocked ? : null} diff --git a/ui/app/pages/routes/routes.container.js b/ui/app/pages/routes/routes.container.js index 0145b4803..527f9791c 100644 --- a/ui/app/pages/routes/routes.container.js +++ b/ui/app/pages/routes/routes.container.js @@ -4,6 +4,7 @@ import { compose } from 'redux'; import { getNetworkIdentifier, getPreferences, + isNetworkLoading, submittedPendingTransactionsSelector, } from '../../selectors'; import { @@ -37,7 +38,7 @@ function mapStateToProps(state) { loadingMessage, isUnlocked: state.metamask.isUnlocked, submittedPendingTransactions: submittedPendingTransactionsSelector(state), - network: state.metamask.network, + isNetworkLoading: isNetworkLoading(state), provider: state.metamask.provider, frequentRpcListDetail: state.metamask.frequentRpcListDetail || [], currentCurrency: state.metamask.currentCurrency, diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index c735957cf..f4830cd7c 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -12,18 +12,18 @@ import { import { isValidAddress, - isEthNetwork, checkExistingAddresses, isValidDomainName, isOriginContractAddress, + isDefaultMetaMaskChain, } from '../../../../helpers/utils/util'; -export function getToErrorObject(to, sendTokenAddress, network) { +export function getToErrorObject(to, sendTokenAddress, chainId) { let toError = null; if (!to) { toError = REQUIRED_ERROR; } else if (!isValidAddress(to)) { - toError = isEthNetwork(network) + toError = isDefaultMetaMaskChain(chainId) ? INVALID_RECIPIENT_ADDRESS_ERROR : INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR; } else if (isOriginContractAddress(to, sendTokenAddress)) { diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 23696807a..65bd49418 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -36,7 +36,7 @@ export default class SendTransactionScreen extends Component { gasPrice: PropTypes.string, gasTotal: PropTypes.string, history: PropTypes.object, - network: PropTypes.string, + chainId: PropTypes.string, primaryCurrency: PropTypes.string, resetSendState: PropTypes.func.isRequired, selectedAddress: PropTypes.string, @@ -84,7 +84,7 @@ export default class SendTransactionScreen extends Component { conversionRate, from: { address, balance }, gasTotal, - network, + chainId, primaryCurrency, sendToken, tokenBalance, @@ -106,7 +106,7 @@ export default class SendTransactionScreen extends Component { from: { balance: prevBalance }, gasTotal: prevGasTotal, tokenBalance: prevTokenBalance, - network: prevNetwork, + chainId: prevChainId, sendToken: prevSendToken, to: prevTo, } = prevProps; @@ -146,7 +146,7 @@ export default class SendTransactionScreen extends Component { } if (!uninitialized) { - if (network !== prevNetwork && network !== 'loading') { + if (chainId !== prevChainId && chainId !== undefined) { updateSendTokenBalance({ sendToken, tokenContract, @@ -259,7 +259,7 @@ export default class SendTransactionScreen extends Component { } validate(query) { - const { tokens, sendToken, network, sendTokenAddress } = this.props; + const { tokens, sendToken, chainId, sendTokenAddress } = this.props; const { internalSearch } = this.state; @@ -268,7 +268,7 @@ export default class SendTransactionScreen extends Component { return; } - const toErrorObject = getToErrorObject(query, sendTokenAddress, network); + const toErrorObject = getToErrorObject(query, sendTokenAddress, chainId); const toWarningObject = getToWarningObject(query, tokens, sendToken); this.setState({ diff --git a/ui/app/pages/send/send.container.js b/ui/app/pages/send/send.container.js index 898546a81..2c710bdc4 100644 --- a/ui/app/pages/send/send.container.js +++ b/ui/app/pages/send/send.container.js @@ -5,7 +5,6 @@ import { compose } from 'redux'; import { getBlockGasLimit, getConversionRate, - getCurrentNetwork, getGasLimit, getGasPrice, getGasTotal, @@ -24,6 +23,7 @@ import { getAddressBook, getSendTokenAddress, isCustomPriceExcessive, + getCurrentChainId, } from '../../selectors'; import { @@ -56,7 +56,7 @@ function mapStateToProps(state) { gasLimit: getGasLimit(state), gasPrice: getGasPrice(state), gasTotal: getGasTotal(state), - network: getCurrentNetwork(state), + chainId: getCurrentChainId(state), primaryCurrency: getPrimaryCurrency(state), qrCodeData: getQrCodeData(state), selectedAddress: getSelectedAddress(state), diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/tests/send-component.test.js index 9a529d480..3f502d6ce 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/tests/send-component.test.js @@ -9,6 +9,10 @@ import AddRecipient from '../send-content/add-recipient/add-recipient.container' import SendHeader from '../send-header/send-header.container'; import SendContent from '../send-content/send-content.container'; import SendFooter from '../send-footer/send-footer.container'; +import { + RINKEBY_CHAIN_ID, + ROPSTEN_CHAIN_ID, +} from '../../../../../shared/constants/network'; describe('Send Component', function () { let wrapper; @@ -59,7 +63,7 @@ describe('Send Component', function () { gasPrice="mockGasPrice" gasTotal="mockGasTotal" history={{ mockProp: 'history-abc' }} - network="3" + chainId={ROPSTEN_CHAIN_ID} primaryCurrency="mockPrimaryCurrency" selectedAddress="mockSelectedAddress" sendToken={{ address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }} @@ -287,7 +291,7 @@ describe('Send Component', function () { from: { balance: 'balanceChanged', }, - network: '3', + chainId: ROPSTEN_CHAIN_ID, sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }); assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0); @@ -298,14 +302,14 @@ describe('Send Component', function () { }); it('should not call updateSendTokenBalance or this.updateGas if network === loading', function () { - wrapper.setProps({ network: 'loading' }); + wrapper.setProps({ chainId: undefined }); SendTransactionScreen.prototype.updateGas.resetHistory(); propsMethodSpies.updateSendTokenBalance.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - network: '3', + chainId: ROPSTEN_CHAIN_ID, sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }); assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0); @@ -322,7 +326,7 @@ describe('Send Component', function () { from: { balance: 'balanceChanged', }, - network: '2', + chainId: RINKEBY_CHAIN_ID, sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }); assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 1); @@ -355,7 +359,7 @@ describe('Send Component', function () { from: { balance: 'balancedChanged', }, - network: '3', // Make sure not to hit updateGas when changing network + chainId: ROPSTEN_CHAIN_ID, // Make sure not to hit updateGas when changing network sendToken: { address: 'newSelectedToken' }, }); assert.strictEqual( @@ -482,7 +486,7 @@ describe('Send Component', function () { }); it('should validate when input changes and has error on a bad network', function () { - wrapper.setProps({ network: 'bad' }); + wrapper.setProps({ chainId: 'bad' }); const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7a3BedD70cd4510', @@ -498,7 +502,7 @@ describe('Send Component', function () { }); it('should synchronously validate when input changes to ""', function () { - wrapper.setProps({ network: 'bad' }); + wrapper.setProps({ chainId: 'bad' }); const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7a3BedD70cd4510', diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js index a6f9f1d94..2ac609be7 100644 --- a/ui/app/selectors/confirm-transaction.js +++ b/ui/app/selectors/confirm-transaction.js @@ -11,7 +11,7 @@ import { } from '../helpers/utils/confirm-tx.util'; import { sumHexes } from '../helpers/utils/transactions.util'; import { transactionMatchesNetwork } from '../../../shared/modules/transaction.utils'; -import { getCurrentChainId, getCurrentNetworkId } from './selectors'; +import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors'; import { getNativeCurrency } from '.'; const unapprovedTxsSelector = (state) => state.metamask.unapprovedTxs; @@ -32,7 +32,7 @@ export const unconfirmedTransactionsListSelector = createSelector( unapprovedDecryptMsgsSelector, unapprovedEncryptionPublicKeyMsgsSelector, unapprovedTypedMessagesSelector, - getCurrentNetworkId, + deprecatedGetCurrentNetworkId, getCurrentChainId, ( unapprovedTxs = {}, @@ -63,7 +63,7 @@ export const unconfirmedTransactionsHashSelector = createSelector( unapprovedDecryptMsgsSelector, unapprovedEncryptionPublicKeyMsgsSelector, unapprovedTypedMessagesSelector, - getCurrentNetworkId, + deprecatedGetCurrentNetworkId, getCurrentChainId, ( unapprovedTxs = {}, @@ -118,7 +118,7 @@ export const unconfirmedTransactionsCountSelector = createSelector( unapprovedDecryptMsgCountSelector, unapprovedEncryptionPublicKeyMsgCountSelector, unapprovedTypedMessagesCountSelector, - getCurrentNetworkId, + deprecatedGetCurrentNetworkId, getCurrentChainId, ( unapprovedTxs = {}, diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 5b6f90c68..0e4f8ceb8 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -17,6 +17,18 @@ import { } from '../helpers/utils/conversions.util'; import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; +/** + * One of the only remaining valid uses of selecting the network subkey of the + * metamask state tree is to determine if the network is currently 'loading'. + * + * This will be used for all cases where this state key is accessed only for that + * purpose. + * @param {Object} state - redux state object + */ +export function isNetworkLoading(state) { + return state.metamask.network === 'loading'; +} + export function getNetworkIdentifier(state) { const { metamask: { @@ -71,7 +83,16 @@ export function getAccountType(state) { } } -export function getCurrentNetworkId(state) { +/** + * get the currently selected networkId which will be 'loading' when the + * network changes. The network id should not be used in most cases, + * instead use chainId in most situations. There are a limited number of + * use cases to use this method still, such as when comparing transaction + * metadata that predates the switch to using chainId. + * @deprecated - use getCurrentChainId instead + * @param {Object} state - redux state object + */ +export function deprecatedGetCurrentNetworkId(state) { return state.metamask.network; } @@ -136,7 +157,7 @@ export function getMetaMaskCachedBalances(state) { // Fallback to fetching cached balances from network id // this can eventually be removed - const network = getCurrentNetworkId(state); + const network = deprecatedGetCurrentNetworkId(state); return ( state.metamask.cachedBalances[chainId] ?? @@ -347,17 +368,6 @@ export function getDomainMetadata(state) { return state.metamask.domainMetadata; } -export const getBackgroundMetaMetricState = (state) => { - return { - network: getCurrentNetworkId(state), - accountType: getAccountType(state), - metaMetricsId: state.metamask.metaMetricsId, - numberOfTokens: getNumberOfTokens(state), - numberOfAccounts: getNumberOfAccounts(state), - participateInMetaMetrics: state.metamask.participateInMetaMetrics, - }; -}; - export function getRpcPrefsForCurrentProvider(state) { const { frequentRpcListDetail, provider } = state.metamask; const selectRpcInfo = frequentRpcListDetail.find( diff --git a/ui/app/selectors/send.js b/ui/app/selectors/send.js index c7a2c870f..fad9b7275 100644 --- a/ui/app/selectors/send.js +++ b/ui/app/selectors/send.js @@ -20,10 +20,6 @@ export function getNativeCurrency(state) { return state.metamask.nativeCurrency; } -export function getCurrentNetwork(state) { - return state.metamask.network; -} - export function getGasLimit(state) { return state.metamask.send.gasLimit || '0'; } diff --git a/ui/app/selectors/tests/send.test.js b/ui/app/selectors/tests/send.test.js index 2dc9598ac..1cc2a60e0 100644 --- a/ui/app/selectors/tests/send.test.js +++ b/ui/app/selectors/tests/send.test.js @@ -8,7 +8,6 @@ import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { getBlockGasLimit, getConversionRate, - getCurrentNetwork, getNativeCurrency, getGasLimit, getGasPrice, @@ -116,12 +115,6 @@ describe('send selectors', function () { }); }); - describe('getCurrentNetwork()', function () { - it('should return the id of the currently selected network', function () { - assert.strictEqual(getCurrentNetwork(mockState), '3'); - }); - }); - describe('getGasLimit()', function () { it('should return the send.gasLimit', function () { assert.strictEqual(getGasLimit(mockState), '0xFFFF'); diff --git a/ui/app/selectors/transactions.js b/ui/app/selectors/transactions.js index dd418c655..628b856f0 100644 --- a/ui/app/selectors/transactions.js +++ b/ui/app/selectors/transactions.js @@ -10,7 +10,7 @@ import { TRANSACTION_TYPES, } from '../../../shared/constants/transaction'; import { transactionMatchesNetwork } from '../../../shared/modules/transaction.utils'; -import { getCurrentChainId, getCurrentNetworkId } from './selectors'; +import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors'; import { getSelectedAddress } from '.'; export const incomingTxListSelector = (state) => { @@ -58,7 +58,7 @@ export const unapprovedMessagesSelector = createSelector( unapprovedDecryptMsgsSelector, unapprovedEncryptionPublicKeyMsgsSelector, unapprovedTypedMessagesSelector, - getCurrentNetworkId, + deprecatedGetCurrentNetworkId, getCurrentChainId, ( unapprovedMsgs = {}, From 153bbc60533289356682a66f98cb0687c07e0343 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 15 Mar 2021 10:51:35 -0230 Subject: [PATCH 11/82] Move swaps constants to the shared constants directory (#10614) --- app/scripts/controllers/swaps.js | 2 +- {ui/app/helpers => shared}/constants/swaps.js | 0 test/unit/app/controllers/swaps.test.js | 2 +- .../app/transaction-list/transaction-list.component.js | 2 +- ui/app/ducks/swaps/swaps.js | 2 +- ui/app/hooks/useCurrentAsset.js | 2 +- ui/app/hooks/useSwappedTokenValue.js | 2 +- ui/app/pages/swaps/awaiting-swap/awaiting-swap.js | 2 +- ui/app/pages/swaps/build-quote/build-quote.js | 2 +- ui/app/pages/swaps/index.js | 2 +- ui/app/pages/swaps/swaps-util-test-constants.js | 2 +- ui/app/pages/swaps/swaps.util.js | 2 +- ui/app/pages/swaps/view-quote/view-quote.js | 2 +- ui/app/selectors/selectors.js | 2 +- 14 files changed, 13 insertions(+), 13 deletions(-) rename {ui/app/helpers => shared}/constants/swaps.js (100%) diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 3aef182fb..0011984b3 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -13,7 +13,7 @@ import { QUOTES_EXPIRED_ERROR, QUOTES_NOT_AVAILABLE_ERROR, SWAPS_FETCH_ORDER_CONFLICT, -} from '../../../ui/app/helpers/constants/swaps'; +} from '../../../shared/constants/swaps'; import { fetchTradesInfo as defaultFetchTradesInfo, fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness, diff --git a/ui/app/helpers/constants/swaps.js b/shared/constants/swaps.js similarity index 100% rename from ui/app/helpers/constants/swaps.js rename to shared/constants/swaps.js diff --git a/test/unit/app/controllers/swaps.test.js b/test/unit/app/controllers/swaps.test.js index 8b9a2b0f6..867eacef3 100644 --- a/test/unit/app/controllers/swaps.test.js +++ b/test/unit/app/controllers/swaps.test.js @@ -9,7 +9,7 @@ import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID, } from '../../../../shared/constants/network'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../ui/app/helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../shared/constants/swaps'; import { createTestProviderTools } from '../../../stub/provider'; import SwapsController, { utils, diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js index 44824e9f1..305fbed98 100644 --- a/ui/app/components/app/transaction-list/transaction-list.component.js +++ b/ui/app/components/app/transaction-list/transaction-list.component.js @@ -9,7 +9,7 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import TransactionListItem from '../transaction-list-item'; import Button from '../../ui/button'; import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions'; -import { SWAPS_CONTRACT_ADDRESS } from '../../../helpers/constants/swaps'; +import { SWAPS_CONTRACT_ADDRESS } from '../../../../../shared/constants/swaps'; import { TRANSACTION_TYPES } from '../../../../../shared/constants/transaction'; const PAGE_INCREMENT = 10; diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 8fbc372f5..40e97428f 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -56,7 +56,7 @@ import { QUOTES_NOT_AVAILABLE_ERROR, SWAP_FAILED_ERROR, SWAPS_FETCH_ORDER_CONFLICT, -} from '../../helpers/constants/swaps'; +} from '../../../../shared/constants/swaps'; import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; const GAS_PRICES_LOADING_STATES = { diff --git a/ui/app/hooks/useCurrentAsset.js b/ui/app/hooks/useCurrentAsset.js index d1d144bed..382250e5f 100644 --- a/ui/app/hooks/useCurrentAsset.js +++ b/ui/app/hooks/useCurrentAsset.js @@ -2,7 +2,7 @@ import { useSelector } from 'react-redux'; import { useRouteMatch } from 'react-router-dom'; import { getTokens } from '../ducks/metamask/metamask'; import { ASSET_ROUTE } from '../helpers/constants/routes'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; /** * Returns a token object for the asset that is currently being viewed. diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index 64d51fe8a..788104bbb 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -1,5 +1,5 @@ import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util'; import { useTokenFiatAmount } from './useTokenFiatAmount'; diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index b02639b26..e218cbb9a 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -30,7 +30,7 @@ import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, OFFLINE_FOR_MAINTENANCE, -} from '../../../helpers/constants/swaps'; +} from '../../../../../shared/constants/swaps'; import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { getRenderableNetworkFeesForQuote } from '../swaps.util'; diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index 9237016ea..b70d5ccf9 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -36,7 +36,7 @@ import { useTokenTracker } from '../../../hooks/useTokenTracker'; import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../../shared/constants/swaps'; import { resetSwapsPostFetchState, removeToken } from '../../../store/actions'; import { fetchTokenPrice, fetchTokenBalance } from '../swaps.util'; diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index 42f7e7e9f..75752d24c 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -44,7 +44,7 @@ import { QUOTES_NOT_AVAILABLE_ERROR, SWAP_FAILED_ERROR, OFFLINE_FOR_MAINTENANCE, -} from '../../helpers/constants/swaps'; +} from '../../../../shared/constants/swaps'; import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { diff --git a/ui/app/pages/swaps/swaps-util-test-constants.js b/ui/app/pages/swaps/swaps-util-test-constants.js index 6bf2207c6..95c4209ea 100644 --- a/ui/app/pages/swaps/swaps-util-test-constants.js +++ b/ui/app/pages/swaps/swaps-util-test-constants.js @@ -1,4 +1,4 @@ -import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../shared/constants/swaps'; export const TRADES_BASE_PROD_URL = 'https://api.metaswap.codefi.network/trades?'; diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index aed3ce2f0..aba17fc58 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -5,7 +5,7 @@ import { isValidAddress } from 'ethereumjs-util'; import { ETH_SWAPS_TOKEN_OBJECT, METASWAP_API_HOST, -} from '../../helpers/constants/swaps'; +} from '../../../../shared/constants/swaps'; import { calcTokenValue, calcTokenAmount, diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index 1efa81751..f16af36a0 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -73,7 +73,7 @@ import { getRenderableNetworkFeesForQuote, } from '../swaps.util'; import { useTokenTracker } from '../../../hooks/useTokenTracker'; -import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps'; +import { QUOTES_EXPIRED_ERROR } from '../../../../../shared/constants/swaps'; import CountdownTimer from '../countdown-timer'; import SwapsFooter from '../swaps-footer'; import ViewQuotePriceDifference from './view-quote-price-difference'; diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 0e4f8ceb8..f0146194f 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -15,7 +15,7 @@ import { getValueFromWeiHex, hexToDecimal, } from '../helpers/utils/conversions.util'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; /** * One of the only remaining valid uses of selecting the network subkey of the From 9ae82046f08fc9da5f8432e9a81eef9d8f7daeed Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 15 Mar 2021 09:56:26 -0500 Subject: [PATCH 12/82] Position the 3dot menu in the same spot on asset screen and home screen (#10642) --- ui/app/pages/asset/asset.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/pages/asset/asset.scss b/ui/app/pages/asset/asset.scss index b9844e8e2..8cbb339e8 100644 --- a/ui/app/pages/asset/asset.scss +++ b/ui/app/pages/asset/asset.scss @@ -37,7 +37,7 @@ font-size: $font-size-paragraph; color: $Black-100; background-color: inherit; - padding: 2px 8px; + padding: 2px 0 2px 8px; } &__icon { From 3e6b2e7f0ab2030fe3a40e742a3ed594818ed60b Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 15 Mar 2021 11:30:01 -0500 Subject: [PATCH 13/82] Ensure swaps detail height doesn't create jump in vertical height (#10644) --- ui/app/pages/swaps/build-quote/index.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/pages/swaps/build-quote/index.scss b/ui/app/pages/swaps/build-quote/index.scss index b07879076..325e795d6 100644 --- a/ui/app/pages/swaps/build-quote/index.scss +++ b/ui/app/pages/swaps/build-quote/index.scss @@ -79,6 +79,7 @@ margin-top: 4px; display: flex; flex-flow: column; + height: 18px; &--error { div:first-of-type { From 60514c12b0ad6ae69d8a6ca793950b0a272acd72 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 15 Mar 2021 14:21:43 -0230 Subject: [PATCH 14/82] Fix: ETH 'token' now only appears once in the swaps to and from dropdowns. (#10650) --- ui/app/hooks/useTokensToSearch.js | 38 +++++++------------ ui/app/pages/swaps/build-quote/build-quote.js | 33 ++++++++++------ .../pages/swaps/swaps-util-test-constants.js | 7 +++- ui/app/pages/swaps/swaps.util.js | 19 ++++++---- ui/app/pages/swaps/swaps.util.test.js | 5 ++- 5 files changed, 55 insertions(+), 47 deletions(-) diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index 3336ceae0..b1af93cdf 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -69,13 +69,7 @@ export function getRenderableTokenData( }; } -export function useTokensToSearch({ - providedTokens, - usersTokens = [], - topTokens = {}, - onlyEth, - singleToken, -}) { +export function useTokensToSearch({ usersTokens = [], topTokens = {} }) { const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); const conversionRate = useSelector(getConversionRate); const currentCurrency = useSelector(getCurrentCurrency); @@ -93,18 +87,16 @@ export function useTokensToSearch({ const memoizedEthToken = useEqualityCheck(ethToken); const swapsTokens = useSelector(getSwapsTokens) || []; - let tokensToSearch; - if (onlyEth) { - tokensToSearch = [memoizedEthToken]; - } else if (singleToken) { - tokensToSearch = providedTokens; - } else if (providedTokens) { - tokensToSearch = [memoizedEthToken, ...providedTokens]; - } else if (swapsTokens.length) { - tokensToSearch = [memoizedEthToken, ...swapsTokens]; - } else { - tokensToSearch = [memoizedEthToken, ...tokenList]; - } + + const tokensToSearch = swapsTokens.length + ? swapsTokens + : [ + memoizedEthToken, + ...tokenList.filter( + (token) => token.symbol !== memoizedEthToken.symbol, + ), + ]; + const memoizedTokensToSearch = useEqualityCheck(tokensToSearch); return useMemo(() => { const usersTokensAddressMap = memoizedUsersToken.reduce( @@ -113,7 +105,7 @@ export function useTokensToSearch({ ); const tokensToSearchBuckets = { - owned: singleToken ? [] : [memoizedEthToken], + owned: [], top: [], others: [], }; @@ -126,8 +118,8 @@ export function useTokensToSearch({ currentCurrency, ); if ( - usersTokensAddressMap[token.address] && - (renderableDataToken.symbol === 'ETH' || + renderableDataToken.symbol === 'ETH' || + (usersTokensAddressMap[token.address] && Number(renderableDataToken.balance ?? 0) !== 0) ) { tokensToSearchBuckets.owned.push(renderableDataToken); @@ -158,7 +150,5 @@ export function useTokensToSearch({ conversionRate, currentCurrency, memoizedTopTokens, - memoizedEthToken, - singleToken, ]); } diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index b70d5ccf9..7648efe47 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -2,10 +2,13 @@ import React, { useContext, useEffect, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import classnames from 'classnames'; -import { uniqBy } from 'lodash'; +import { uniqBy, isEqual } from 'lodash'; import { useHistory } from 'react-router-dom'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; -import { useTokensToSearch } from '../../../hooks/useTokensToSearch'; +import { + useTokensToSearch, + getRenderableTokenData, +} from '../../../hooks/useTokensToSearch'; import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; import { I18nContext } from '../../../contexts/i18n'; import DropdownInputPair from '../dropdown-input-pair'; @@ -25,7 +28,12 @@ import { getTopAssets, getFetchParams, } from '../../../ducks/swaps/swaps'; -import { getSwapsEthToken } from '../../../selectors'; +import { + getSwapsEthToken, + getTokenExchangeRates, + getConversionRate, + getCurrentCurrency, +} from '../../../selectors'; import { getValueFromWeiHex, hexToDecimal, @@ -80,6 +88,10 @@ export default function BuildQuote({ const fetchParamsFromToken = sourceTokenInfo?.symbol === 'ETH' ? swapsEthToken : sourceTokenInfo; + const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); + const conversionRate = useSelector(getConversionRate); + const currentCurrency = useSelector(getCurrentCurrency); + const { loading, tokensWithBalances } = useTokenTracker(tokens); // If the fromToken was set in a call to `onFromSelect` (see below), and that from token has a balance @@ -93,15 +105,12 @@ export default function BuildQuote({ ); const memoizedUsersTokens = useEqualityCheck(usersTokens); - const selectedFromToken = useTokensToSearch({ - providedTokens: - fromToken || fetchParamsFromToken - ? [fromToken || fetchParamsFromToken] - : [], - usersTokens: memoizedUsersTokens, - onlyEth: (fromToken || fetchParamsFromToken)?.symbol === 'ETH', - singleToken: true, - })[0]; + const selectedFromToken = getRenderableTokenData( + fromToken || fetchParamsFromToken, + tokenConversionRates, + conversionRate, + currentCurrency, + ); const tokensToSearch = useTokensToSearch({ usersTokens: memoizedUsersTokens, diff --git a/ui/app/pages/swaps/swaps-util-test-constants.js b/ui/app/pages/swaps/swaps-util-test-constants.js index 95c4209ea..1491b1184 100644 --- a/ui/app/pages/swaps/swaps-util-test-constants.js +++ b/ui/app/pages/swaps/swaps-util-test-constants.js @@ -9,7 +9,7 @@ export const AGGREGATOR_METADATA_BASE_PROD_URL = export const TOP_ASSET_BASE_PROD_URL = 'https://api.metaswap.codefi.network/topAssets'; -export const TOKENS = [ +const BASE_TOKENS = [ { erc20: true, symbol: 'META', @@ -82,9 +82,12 @@ export const TOKENS = [ decimals: 8, address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', }, - ETH_SWAPS_TOKEN_OBJECT, ]; +export const TOKENS = [...BASE_TOKENS, ETH_SWAPS_TOKEN_OBJECT]; + +export const EXPECTED_TOKENS_RESULT = [ETH_SWAPS_TOKEN_OBJECT, ...BASE_TOKENS]; + export const MOCK_TRADE_RESPONSE_1 = [ { trade: { diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index aba17fc58..85c8a5cdf 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -279,13 +279,18 @@ export async function fetchTokens() { { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }, ); - const filteredTokens = tokens.filter((token) => { - return ( - validateData(TOKEN_VALIDATORS, token, tokenUrl) && - token.address !== ETH_SWAPS_TOKEN_OBJECT.address - ); - }); - filteredTokens.push(ETH_SWAPS_TOKEN_OBJECT); + const filteredTokens = [ + ETH_SWAPS_TOKEN_OBJECT, + ...tokens.filter((token) => { + return ( + validateData(TOKEN_VALIDATORS, token, tokenUrl) && + !( + token.symbol === ETH_SWAPS_TOKEN_OBJECT.symbol || + token.address === ETH_SWAPS_TOKEN_OBJECT.address + ) + ); + }), + ]; return filteredTokens; } diff --git a/ui/app/pages/swaps/swaps.util.test.js b/ui/app/pages/swaps/swaps.util.test.js index f3ee2a497..c68cff29b 100644 --- a/ui/app/pages/swaps/swaps.util.test.js +++ b/ui/app/pages/swaps/swaps.util.test.js @@ -6,6 +6,7 @@ import { AGGREGATOR_METADATA_BASE_PROD_URL, TOP_ASSET_BASE_PROD_URL, TOKENS, + EXPECTED_TOKENS_RESULT, MOCK_TRADE_RESPONSE_2, AGGREGATOR_METADATA, TOP_ASSETS, @@ -107,12 +108,12 @@ describe('Swaps Util', function () { describe('fetchTokens', function () { it('should fetch tokens', async function () { const result = await fetchTokens(true); - assert.deepStrictEqual(result, TOKENS); + assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT); }); it('should fetch tokens on prod', async function () { const result = await fetchTokens(false); - assert.deepStrictEqual(result, TOKENS); + assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT); }); }); From b8900140ec3cc02138ad6ebcf8e063dc21e59d17 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 15 Mar 2021 17:34:15 -0500 Subject: [PATCH 15/82] Prevent network menu highlighting (#10643) --- ui/app/components/app/network-display/index.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/components/app/network-display/index.scss b/ui/app/components/app/network-display/index.scss index c07126b6f..fdfdc3302 100644 --- a/ui/app/components/app/network-display/index.scss +++ b/ui/app/components/app/network-display/index.scss @@ -6,6 +6,7 @@ border-radius: 4px; min-height: 25px; cursor: pointer; + user-select: none; &--disabled { cursor: not-allowed; From da90674f595af81bd8197201c2b4e56186b19245 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Tue, 16 Mar 2021 11:24:56 -0500 Subject: [PATCH 16/82] Allow TextField to receive min and max attributes (#10656) --- .../ui/text-field/text-field.component.js | 18 ++++++++++++++++++ ui/app/pages/add-token/add-token.component.js | 9 +++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ui/app/components/ui/text-field/text-field.component.js b/ui/app/components/ui/text-field/text-field.component.js index 49e6ca785..1b72620a5 100644 --- a/ui/app/components/ui/text-field/text-field.component.js +++ b/ui/app/components/ui/text-field/text-field.component.js @@ -88,6 +88,8 @@ const getMaterialThemeInputProps = ({ dir, classes: { materialLabel, materialFocused, materialError, materialUnderline }, startAdornment, + min, + max, }) => ({ InputLabelProps: { classes: { @@ -103,6 +105,8 @@ const getMaterialThemeInputProps = ({ }, inputProps: { dir, + min, + max, }, }, }); @@ -116,6 +120,8 @@ const getMaterialWhitePaddedThemeInputProps = ({ materialWhitePaddedUnderline, }, startAdornment, + min, + max, }) => ({ InputProps: { startAdornment, @@ -127,6 +133,8 @@ const getMaterialWhitePaddedThemeInputProps = ({ }, inputProps: { dir, + min, + max, }, }, }); @@ -145,6 +153,8 @@ const getBorderedThemeInputProps = ({ }, largeLabel, startAdornment, + min, + max, }) => ({ InputLabelProps: { shrink: true, @@ -165,6 +175,8 @@ const getBorderedThemeInputProps = ({ }, inputProps: { dir, + min, + max, }, }, }); @@ -182,6 +194,8 @@ const TextField = ({ startAdornment, largeLabel, dir, + min, + max, ...textFieldProps }) => { const inputProps = themeToInputProps[theme]({ @@ -189,6 +203,8 @@ const TextField = ({ startAdornment, largeLabel, dir, + min, + max, }); return ( @@ -214,6 +230,8 @@ TextField.propTypes = { theme: PropTypes.oneOf(['bordered', 'material', 'material-white-padded']), startAdornment: PropTypes.element, largeLabel: PropTypes.bool, + min: PropTypes.number, + max: PropTypes.number, }; export default withStyles(styles)(TextField); diff --git a/ui/app/pages/add-token/add-token.component.js b/ui/app/pages/add-token/add-token.component.js index 40f4a3675..1bf17facf 100644 --- a/ui/app/pages/add-token/add-token.component.js +++ b/ui/app/pages/add-token/add-token.component.js @@ -13,6 +13,9 @@ import TokenSearch from './token-search'; const emptyAddr = '0x0000000000000000000000000000000000000000'; +const MIN_DECIMAL_VALUE = 0; +const MAX_DECIMAL_VALUE = 36; + class AddToken extends Component { static contextTypes = { t: PropTypes.func, @@ -211,8 +214,8 @@ class AddToken extends Component { const validDecimals = customDecimals !== null && customDecimals !== '' && - customDecimals >= 0 && - customDecimals <= 36; + customDecimals >= MIN_DECIMAL_VALUE && + customDecimals <= MAX_DECIMAL_VALUE; let customDecimalsError = null; if (!validDecimals) { @@ -282,6 +285,8 @@ class AddToken extends Component { fullWidth margin="normal" disabled={autoFilled} + min={MIN_DECIMAL_VALUE} + max={MAX_DECIMAL_VALUE} />
); From 5a233e463457ca2ac9b3342f4cc848303a44e929 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Tue, 16 Mar 2021 16:00:08 -0500 Subject: [PATCH 17/82] colocate tests in flat structure (#10655) --- .eslintrc.js | 6 +- .../account-import-strategies.test.js | 2 +- .../controllers/cached-balances.test.js | 4 +- .../controllers/detect-tokens.test.js | 8 +- .../scripts/controllers/ens/index.test.js | 2 +- .../controllers/incoming-transactions.test.js | 19 ++--- .../scripts}/controllers/metametrics.test.js | 12 +-- .../network/network-controller.test.js | 4 +- .../network/pending-middleware.test.js | 4 +- .../permissions-controller.test.js | 18 ++-- .../permissions-log-controller.test.js | 18 ++-- .../permissions-middleware.test.js | 15 ++-- .../permissions/restricted-methods.test.js | 2 +- .../scripts/controllers/preferences.test.js | 4 +- .../scripts}/controllers/swaps.test.js | 12 ++- .../token-rates-controller.test.js | 2 +- .../controllers/transactions/index.test.js | 8 +- .../lib}/tx-state-history-helpers.test.js | 4 +- .../controllers/transactions/lib/util.test.js | 2 +- .../transactions/pending-tx-tracker.test.js | 4 +- .../transactions/tx-gas-utils.test.js | 4 +- .../transactions/tx-state-manager.test.js | 8 +- .../lib}/ComposableObservableStore.test.js | 2 +- .../scripts/lib}/buy-eth-url.test.js | 2 +- .../scripts/lib}/cleanErrorStack.test.js | 2 +- .../scripts/lib}/message-manager.test.js | 2 +- .../scripts/lib/migrator/index.test.js | 8 +- .../app => app/scripts/lib}/nodeify.test.js | 2 +- .../lib}/personal-message-manager.test.js | 2 +- .../scripts/lib}/seed-phrase-verifier.test.js | 6 +- .../lib}/typed-message-manager.test.js | 2 +- .../unit/app => app/scripts/lib}/util.test.js | 5 +- .../scripts}/metamask-controller.test.js | 34 +++++--- .../scripts}/migrations/021.test.js | 4 +- .../scripts}/migrations/022.test.js | 2 +- .../scripts}/migrations/023.test.js | 2 +- .../scripts}/migrations/024.test.js | 4 +- .../scripts}/migrations/025.test.js | 4 +- .../scripts}/migrations/026.test.js | 4 +- .../scripts}/migrations/027.test.js | 4 +- .../scripts}/migrations/028.test.js | 4 +- .../scripts}/migrations/029.test.js | 2 +- .../scripts}/migrations/030.test.js | 2 +- .../scripts}/migrations/031.test.js | 2 +- .../scripts}/migrations/033.test.js | 2 +- .../scripts}/migrations/034.test.js | 2 +- .../scripts}/migrations/035.test.js | 2 +- .../scripts}/migrations/036.test.js | 2 +- .../scripts}/migrations/037.test.js | 2 +- .../scripts}/migrations/038.test.js | 2 +- .../scripts}/migrations/039.test.js | 2 +- .../scripts}/migrations/040.test.js | 2 +- .../scripts}/migrations/041.test.js | 2 +- .../scripts}/migrations/042.test.js | 2 +- .../scripts}/migrations/043.test.js | 2 +- .../scripts}/migrations/044.test.js | 2 +- .../scripts}/migrations/045.test.js | 2 +- .../scripts}/migrations/046.test.js | 2 +- .../scripts}/migrations/047.test.js | 2 +- .../scripts}/migrations/048.test.js | 2 +- .../scripts}/migrations/049.test.js | 2 +- .../scripts}/migrations/050.test.js | 2 +- .../scripts}/migrations/051.test.js | 2 +- .../scripts}/migrations/052.test.js | 2 +- .../scripts}/migrations/053.test.js | 2 +- .../scripts}/migrations/migrations.test.js | 28 +++---- .../scripts}/migrations/template.test.js | 2 +- package.json | 6 +- .../modules}/fetch-with-timeout.test.js | 2 +- .../permission-controller-helpers.js} | 2 +- test/{helper.js => helpers/setup-helper.js} | 0 .../permission-controller.js} | 6 +- test/setup.js | 2 +- .../network/stubs.js => stub/tx-meta-stub.js} | 2 +- .../balance-formatter.test.js | 0 test/unit/actions/config.test.js | 33 -------- test/unit/actions/set_account_label.test.js | 34 -------- .../unit/actions/set_selected_account.test.js | 24 ------ test/unit/actions/tx.test.js | 54 ------------ test/unit/actions/warning.test.js | 24 ------ test/unit/localhostState.js | 23 ------ .../responsive/components/dropdown.test.js | 44 ---------- .../account-list-item-component.test.js | 6 +- .../{tests => }/account-menu.test.js | 4 +- .../unconnected-account-alert.test.js | 8 +- .../app-header/{tests => }/app-header.test.js | 6 +- .../confirm-detail-row.component.test.js | 2 +- ...rm-page-container-header.component.test.js | 8 +- .../dropdowns/{components => }/dropdown.js | 2 +- .../dropdowns/{tests => }/dropdown.test.js | 2 +- .../app/dropdowns/network-dropdown.js | 2 +- .../{tests => }/network-dropdown.test.js | 8 +- .../advanced-gas-input-component.test.js | 2 +- .../advanced-tab-content-component.test.js | 4 +- .../basic-tab-content-component.test.js | 10 +-- ...gas-modal-page-container-component.test.js | 8 +- ...gas-modal-page-container-container.test.js | 2 +- .../gas-price-button-group-component.test.js | 8 +- .../app/info-box/{tests => }/info-box.test.js | 2 +- .../app/menu-bar/{tests => }/menu-bar.test.js | 6 +- .../modal-content.component.test.js | 2 +- .../modal/{tests => }/modal.component.test.js | 4 +- .../account-details-modal.test.js | 2 +- ...ncel-transaction-gas-fee.component.test.js | 4 +- .../cancel-transaction.component.test.js | 6 +- .../confirm-delete-network.test.js | 2 +- .../confirm-remove-account.test.js | 2 +- .../{tests => }/confirm-reset-account.test.js | 2 +- .../metametrics-opt-in-modal.test.js | 4 +- .../{tests => }/reject-transactions.test.js | 2 +- .../{tests => }/transaction-confirmed.test.js | 2 +- .../selected-account-component.test.js | 2 +- ...nent.test.js => sidebar.component.test.js} | 5 +- ...js => signature-request.component.test.js} | 4 +- .../signature-request.container.test.js} | 2 +- ...transaction-activity-log.component.test.js | 2 +- ...transaction-activity-log.container.test.js | 2 +- .../transaction-activity-log.util.test.js | 6 +- ...ransaction-breakdown-row.component.test.js | 4 +- .../transaction-breakdown.component.test.js | 4 +- ...action-list-item-details.component.test.js | 12 +-- .../transaction-status.component.test.js | 6 +- ...erenced-currency-display.component.test.js | 8 +- ...eferenced-currency-input.component.test.js | 4 +- ...eferenced-currency-input.container.test.js | 2 +- ...-preferenced-token-input.component.test.js | 4 +- ...-preferenced-token-input.container.test.js | 2 +- ...cccount-mismatch-warning.component.test.js | 6 +- .../{tests/alert.test.js => index.test.js} | 2 +- .../{tests => }/breadcrumbs.component.test.js | 2 +- .../button-group-component.test.js | 2 +- .../card/{tests => }/card.component.test.js | 2 +- .../{test => }/confusable.component.test.js | 2 +- .../currency-display.component.test.js | 2 +- .../currency-input.component.test.js | 6 +- .../currency-input.container.test.js | 2 +- .../error-message.component.test.js | 2 +- .../hex-to-decimal.component.test.js | 2 +- .../{tests => }/identicon.component.test.js | 2 +- ...em.test.js => list-item.component.test.js} | 6 +- .../metafox-logo.component.test.js | 2 +- .../page-container-footer.component.test.js | 4 +- .../page-container-header.component.test.js | 2 +- .../{tests => }/token-input.component.test.js | 6 +- .../{tests => }/unit-input.component.test.js | 2 +- .../reducers => ui/app/ducks/app}/app.test.js | 4 +- .../app/ducks/metamask}/metamask.test.js | 4 +- .../{tests => }/with-modal-props.test.js | 2 +- .../{tests => }/useCancelTransaction.test.js | 12 +-- .../{tests => }/useCurrencyDisplay.test.js | 4 +- .../{tests => }/useRetryTransaction.test.js | 10 +-- ui/app/hooks/{tests => }/useTokenData.test.js | 4 +- .../{tests => }/useTokenDisplayValue.test.js | 6 +- .../useTransactionDisplayData.test.js | 20 ++--- .../useUserPreferencedCurrency.test.js | 4 +- .../add-token/{tests => }/add-token.test.js | 4 +- ...confirm-transaction-base.component.test.js | 2 +- .../{tests => }/create-account.test.js | 4 +- .../import-with-seed-phrase.component.test.js | 2 +- .../{tests => }/end-of-flow.test.js | 6 +- .../first-time-flow-switch.test.js | 6 +- .../{tests => }/metametrics-opt-in.test.js | 4 +- .../confirm-seed-phrase-component.test.js | 2 +- .../{tests => }/reveal-seed-phrase.test.js | 2 +- .../{tests => }/select-action.test.js | 4 +- .../welcome/{tests => }/welcome.test.js | 4 +- .../keychains/{tests => }/reveal-seed.test.js | 2 +- ui/app/pages/lock/{tests => }/lock.test.js | 4 +- ...est.js => add-recipient.component.test.js} | 4 +- ...est.js => add-recipient.container.test.js} | 2 +- ...ls.test.js => add-recipient.utils.test.js} | 4 +- ...js => amount-max-button.component.test.js} | 2 +- ...js => amount-max-button.container.test.js} | 2 +- ...est.js => amount-max-button.utils.test.js} | 2 +- ...t.js => send-amount-row.component.test.js} | 8 +- ...t.js => send-amount-row.container.test.js} | 2 +- ...test.js => send-content.component.test.js} | 14 ++-- .../gas-fee-display.component.test.js | 4 +- ...test.js => send-gas-row.component.test.js} | 8 +- ...test.js => send-gas-row.container.test.js} | 2 +- ... send-row-error-message.component.test.js} | 2 +- ... send-row-error-message.container.test.js} | 2 +- ....js => send-row-wrapper.component.test.js} | 4 +- ....test.js => send-footer.component.test.js} | 6 +- ....test.js => send-footer.container.test.js} | 2 +- ...tils.test.js => send-footer.utils.test.js} | 4 +- ....test.js => send-header.component.test.js} | 4 +- ...mponent.test.js => send.component.test.js} | 14 ++-- ...ntainer.test.js => send.container.test.js} | 2 +- .../send-utils.test.js => send.utils.test.js} | 4 +- ...test.js => advanced-tab.component.test.js} | 4 +- ...test.js => security-tab.container.test.js} | 2 +- ...test.js => settings-tab.container.test.js} | 2 +- .../view-quote-price-difference.test.js | 4 +- ....test.js => unlock-page.container.test.js} | 2 +- .../{tests => }/confirm-transaction.test.js | 6 +- .../selectors/{tests => }/custom-gas.test.js | 2 +- .../selectors/{tests => }/permissions.test.js | 4 +- .../selectors/{tests => }/selectors.test.js | 4 +- .../{tests => }/send-selectors-test-data.js | 2 +- ui/app/selectors/{tests => }/send.test.js | 12 +-- .../{tests => }/transactions.test.js | 6 +- ui/app/store/actionConstants.test.js | 82 +++++++++++++++++++ .../ui/app => ui/app/store}/actions.test.js | 58 +++++++++++-- {test/unit => ui}/lib/account-link.test.js | 4 +- .../transactions => ui/lib}/tx-helper.test.js | 4 +- 206 files changed, 571 insertions(+), 677 deletions(-) rename {test/unit/app => app/scripts/account-import-strategies}/account-import-strategies.test.js (97%) rename {test/unit/app => app/scripts}/controllers/cached-balances.test.js (95%) rename {test/unit/app => app/scripts}/controllers/detect-tokens.test.js (96%) rename test/unit/app/controllers/ens-controller.test.js => app/scripts/controllers/ens/index.test.js (98%) rename {test/unit/app => app/scripts}/controllers/incoming-transactions.test.js (99%) rename {test/unit/app => app/scripts}/controllers/metametrics.test.js (97%) rename {test/unit/app => app/scripts}/controllers/network/network-controller.test.js (95%) rename {test/unit/app => app/scripts}/controllers/network/pending-middleware.test.js (96%) rename {test/unit/app => app/scripts}/controllers/permissions/permissions-controller.test.js (99%) rename {test/unit/app => app/scripts}/controllers/permissions/permissions-log-controller.test.js (98%) rename {test/unit/app => app/scripts}/controllers/permissions/permissions-middleware.test.js (98%) rename {test/unit/app => app/scripts}/controllers/permissions/restricted-methods.test.js (98%) rename test/unit/app/controllers/preferences-controller.test.js => app/scripts/controllers/preferences.test.js (99%) rename {test/unit/app => app/scripts}/controllers/swaps.test.js (99%) rename {test/unit/app => app/scripts}/controllers/token-rates-controller.test.js (92%) rename test/unit/app/controllers/transactions/tx-controller.test.js => app/scripts/controllers/transactions/index.test.js (99%) rename {test/unit/app/controllers/transactions => app/scripts/controllers/transactions/lib}/tx-state-history-helpers.test.js (96%) rename test/unit/app/controllers/transactions/tx-utils.test.js => app/scripts/controllers/transactions/lib/util.test.js (98%) rename {test/unit/app => app/scripts}/controllers/transactions/pending-tx-tracker.test.js (99%) rename test/unit/app/controllers/transactions/tx-gas-util.test.js => app/scripts/controllers/transactions/tx-gas-utils.test.js (94%) rename {test/unit/app => app/scripts}/controllers/transactions/tx-state-manager.test.js (98%) rename {test/unit/app => app/scripts/lib}/ComposableObservableStore.test.js (93%) rename {test/unit/app => app/scripts/lib}/buy-eth-url.test.js (95%) rename {test/unit/app => app/scripts/lib}/cleanErrorStack.test.js (92%) rename {test/unit/app => app/scripts/lib}/message-manager.test.js (98%) rename test/unit/migrations/migrator.test.js => app/scripts/lib/migrator/index.test.js (92%) rename {test/unit/app => app/scripts/lib}/nodeify.test.js (97%) rename {test/unit/app => app/scripts/lib}/personal-message-manager.test.js (98%) rename {test/unit/app => app/scripts/lib}/seed-phrase-verifier.test.js (95%) rename {test/unit/app => app/scripts/lib}/typed-message-manager.test.js (97%) rename {test/unit/app => app/scripts/lib}/util.test.js (98%) rename {test/unit/app/controllers => app/scripts}/metamask-controller.test.js (98%) rename {test/unit => app/scripts}/migrations/021.test.js (80%) rename {test/unit => app/scripts}/migrations/022.test.js (95%) rename {test/unit => app/scripts}/migrations/023.test.js (98%) rename {test/unit => app/scripts}/migrations/024.test.js (93%) rename {test/unit => app/scripts}/migrations/025.test.js (93%) rename {test/unit => app/scripts}/migrations/026.test.js (90%) rename {test/unit => app/scripts}/migrations/027.test.js (92%) rename {test/unit => app/scripts}/migrations/028.test.js (94%) rename {test/unit => app/scripts}/migrations/029.test.js (96%) rename {test/unit => app/scripts}/migrations/030.test.js (95%) rename {test/unit => app/scripts}/migrations/031.test.js (96%) rename {test/unit => app/scripts}/migrations/033.test.js (93%) rename {test/unit => app/scripts}/migrations/034.test.js (97%) rename {test/unit => app/scripts}/migrations/035.test.js (97%) rename {test/unit => app/scripts}/migrations/036.test.js (97%) rename {test/unit => app/scripts}/migrations/037.test.js (98%) rename {test/unit => app/scripts}/migrations/038.test.js (95%) rename {test/unit => app/scripts}/migrations/039.test.js (99%) rename {test/unit => app/scripts}/migrations/040.test.js (94%) rename {test/unit => app/scripts}/migrations/041.test.js (96%) rename {test/unit => app/scripts}/migrations/042.test.js (96%) rename {test/unit => app/scripts}/migrations/043.test.js (95%) rename {test/unit => app/scripts}/migrations/044.test.js (96%) rename {test/unit => app/scripts}/migrations/045.test.js (96%) rename {test/unit => app/scripts}/migrations/046.test.js (94%) rename {test/unit => app/scripts}/migrations/047.test.js (97%) rename {test/unit => app/scripts}/migrations/048.test.js (99%) rename {test/unit => app/scripts}/migrations/049.test.js (97%) rename {test/unit => app/scripts}/migrations/050.test.js (97%) rename {test/unit => app/scripts}/migrations/051.test.js (98%) rename {test/unit => app/scripts}/migrations/052.test.js (99%) rename {test/unit => app/scripts}/migrations/053.test.js (98%) rename {test/unit => app/scripts}/migrations/migrations.test.js (89%) rename {test/unit => app/scripts}/migrations/template.test.js (82%) rename {test/unit/app => shared/modules}/fetch-with-timeout.test.js (95%) rename test/{unit/app/controllers/permissions/helpers.js => helpers/permission-controller-helpers.js} (98%) rename test/{helper.js => helpers/setup-helper.js} (100%) rename test/{unit/app/controllers/permissions/mocks.js => mocks/permission-controller.js} (98%) rename test/{unit/app/controllers/network/stubs.js => stub/tx-meta-stub.js} (98%) rename test/{unit => unit-global}/balance-formatter.test.js (100%) delete mode 100644 test/unit/actions/config.test.js delete mode 100644 test/unit/actions/set_account_label.test.js delete mode 100644 test/unit/actions/set_selected_account.test.js delete mode 100644 test/unit/actions/tx.test.js delete mode 100644 test/unit/actions/warning.test.js delete mode 100644 test/unit/localhostState.js delete mode 100644 test/unit/responsive/components/dropdown.test.js rename ui/app/components/app/account-list-item/{tests => }/account-list-item-component.test.js (97%) rename ui/app/components/app/account-menu/{tests => }/account-menu.test.js (98%) rename ui/app/components/app/alerts/unconnected-account-alert/{tests => }/unconnected-account-alert.test.js (94%) rename ui/app/components/app/app-header/{tests => }/app-header.test.js (94%) rename ui/app/components/app/confirm-page-container/confirm-detail-row/{tests => }/confirm-detail-row.component.test.js (97%) rename ui/app/components/app/confirm-page-container/confirm-page-container-header/{tests => }/confirm-page-container-header.component.test.js (86%) rename ui/app/components/app/dropdowns/{components => }/dropdown.js (98%) rename ui/app/components/app/dropdowns/{tests => }/dropdown.test.js (93%) rename ui/app/components/app/dropdowns/{tests => }/network-dropdown.test.js (93%) rename ui/app/components/app/gas-customization/advanced-gas-inputs/{tests => }/advanced-gas-input-component.test.js (98%) rename ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/{tests => }/advanced-tab-content-component.test.js (94%) rename ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/{tests => }/basic-tab-content-component.test.js (90%) rename ui/app/components/app/gas-customization/gas-modal-page-container/{tests => }/gas-modal-page-container-component.test.js (97%) rename ui/app/components/app/gas-customization/gas-modal-page-container/{tests => }/gas-modal-page-container-container.test.js (99%) rename ui/app/components/app/gas-customization/gas-price-button-group/{tests => }/gas-price-button-group-component.test.js (97%) rename ui/app/components/app/info-box/{tests => }/info-box.test.js (95%) rename ui/app/components/app/menu-bar/{tests => }/menu-bar.test.js (90%) rename ui/app/components/app/modal/modal-content/{tests => }/modal-content.component.test.js (96%) rename ui/app/components/app/modal/{tests => }/modal.component.test.js (98%) rename ui/app/components/app/modals/{tests => account-details-modal}/account-details-modal.test.js (96%) rename ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/{tests => }/cancel-transaction-gas-fee.component.test.js (83%) rename ui/app/components/app/modals/cancel-transaction/{tests => }/cancel-transaction.component.test.js (92%) rename ui/app/components/app/modals/confirm-delete-network/{tests => }/confirm-delete-network.test.js (95%) rename ui/app/components/app/modals/confirm-remove-account/{tests => }/confirm-remove-account.test.js (96%) rename ui/app/components/app/modals/confirm-reset-account/{tests => }/confirm-reset-account.test.js (94%) rename ui/app/components/app/modals/metametrics-opt-in-modal/{tests => }/metametrics-opt-in-modal.test.js (92%) rename ui/app/components/app/modals/reject-transactions/{tests => }/reject-transactions.test.js (94%) rename ui/app/components/app/modals/transaction-confirmed/{tests => }/transaction-confirmed.test.js (90%) rename ui/app/components/app/selected-account/{tests => }/selected-account-component.test.js (92%) rename ui/app/components/app/sidebars/{tests/sidebars-component.test.js => sidebar.component.test.js} (96%) rename ui/app/components/app/signature-request/{tests/signature-request.test.js => signature-request.component.test.js} (86%) rename ui/app/components/app/{tests/signature-request.test.js => signature-request/signature-request.container.test.js} (97%) rename ui/app/components/app/transaction-activity-log/{tests => }/transaction-activity-log.component.test.js (98%) rename ui/app/components/app/transaction-activity-log/{tests => }/transaction-activity-log.container.test.js (96%) rename ui/app/components/app/transaction-activity-log/{tests => }/transaction-activity-log.util.test.js (98%) rename ui/app/components/app/transaction-breakdown/transaction-breakdown-row/{tests => }/transaction-breakdown-row.component.test.js (91%) rename ui/app/components/app/transaction-breakdown/{tests => }/transaction-breakdown.component.test.js (83%) rename ui/app/components/app/transaction-list-item-details/{tests => }/transaction-list-item-details.component.test.js (92%) rename ui/app/components/app/transaction-status/{tests => }/transaction-status.component.test.js (91%) rename ui/app/components/app/user-preferenced-currency-display/{tests => }/user-preferenced-currency-display.component.test.js (80%) rename ui/app/components/app/user-preferenced-currency-input/{tests => }/user-preferenced-currency-input.component.test.js (87%) rename ui/app/components/app/user-preferenced-currency-input/{tests => }/user-preferenced-currency-input.container.test.js (91%) rename ui/app/components/app/user-preferenced-token-input/{tests => }/user-preferenced-token-input.component.test.js (88%) rename ui/app/components/app/user-preferenced-token-input/{tests => }/user-preferenced-token-input.container.test.js (91%) rename ui/app/components/ui/account-mismatch-warning/{tests => }/acccount-mismatch-warning.component.test.js (84%) rename ui/app/components/ui/alert/{tests/alert.test.js => index.test.js} (97%) rename ui/app/components/ui/breadcrumbs/{tests => }/breadcrumbs.component.test.js (93%) rename ui/app/components/ui/button-group/{tests => }/button-group-component.test.js (98%) rename ui/app/components/ui/card/{tests => }/card.component.test.js (94%) rename ui/app/components/ui/confusable/{test => }/confusable.component.test.js (94%) rename ui/app/components/ui/currency-display/{tests => }/currency-display.component.test.js (94%) rename ui/app/components/ui/currency-input/{tests => }/currency-input.component.test.js (98%) rename ui/app/components/ui/currency-input/{tests => }/currency-input.container.test.js (98%) rename ui/app/components/ui/error-message/{tests => }/error-message.component.test.js (95%) rename ui/app/components/ui/hex-to-decimal/{tests => }/hex-to-decimal.component.test.js (92%) rename ui/app/components/ui/identicon/{tests => }/identicon.component.test.js (96%) rename ui/app/components/ui/list-item/{tests/list-item.test.js => list-item.component.test.js} (93%) rename ui/app/components/ui/metafox-logo/{tests => }/metafox-logo.component.test.js (96%) rename ui/app/components/ui/page-container/page-container-footer/{tests => }/page-container-footer.component.test.js (96%) rename ui/app/components/ui/page-container/page-container-header/{tests => }/page-container-header.component.test.js (97%) rename ui/app/components/ui/token-input/{tests => }/token-input.component.test.js (98%) rename ui/app/components/ui/unit-input/{tests => }/unit-input.component.test.js (98%) rename {test/unit/ui/app/reducers => ui/app/ducks/app}/app.test.js (98%) rename {test/unit/ui/app/reducers => ui/app/ducks/metamask}/metamask.test.js (98%) rename ui/app/helpers/higher-order-components/with-modal-props/{tests => }/with-modal-props.test.js (96%) rename ui/app/hooks/{tests => }/useCancelTransaction.test.js (92%) rename ui/app/hooks/{tests => }/useCurrencyDisplay.test.js (97%) rename ui/app/hooks/{tests => }/useRetryTransaction.test.js (91%) rename ui/app/hooks/{tests => }/useTokenData.test.js (94%) rename ui/app/hooks/{tests => }/useTokenDisplayValue.test.js (93%) rename ui/app/hooks/{tests => }/useTransactionDisplayData.test.js (93%) rename ui/app/hooks/{tests => }/useUserPreferencedCurrency.test.js (95%) rename ui/app/pages/add-token/{tests => }/add-token.test.js (96%) rename ui/app/pages/confirm-transaction-base/{tests => }/confirm-transaction-base.component.test.js (88%) rename ui/app/pages/create-account/{tests => }/create-account.test.js (92%) rename ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/{tests => }/import-with-seed-phrase.component.test.js (97%) rename ui/app/pages/first-time-flow/end-of-flow/{tests => }/end-of-flow.test.js (80%) rename ui/app/pages/first-time-flow/first-time-flow-switch/{tests => }/first-time-flow-switch.test.js (94%) rename ui/app/pages/first-time-flow/metametrics-opt-in/{tests => }/metametrics-opt-in.test.js (86%) rename ui/app/pages/first-time-flow/seed-phrase/{tests => }/confirm-seed-phrase-component.test.js (98%) rename ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/{tests => }/reveal-seed-phrase.test.js (95%) rename ui/app/pages/first-time-flow/select-action/{tests => }/select-action.test.js (91%) rename ui/app/pages/first-time-flow/welcome/{tests => }/welcome.test.js (92%) rename ui/app/pages/keychains/{tests => }/reveal-seed.test.js (92%) rename ui/app/pages/lock/{tests => }/lock.test.js (89%) rename ui/app/pages/send/send-content/add-recipient/{tests/add-recipient-component.test.js => add-recipient.component.test.js} (98%) rename ui/app/pages/send/send-content/add-recipient/{tests/add-recipient-container.test.js => add-recipient.container.test.js} (97%) rename ui/app/pages/send/send-content/add-recipient/{tests/add-recipient-utils.test.js => add-recipient.utils.test.js} (97%) rename ui/app/pages/send/send-content/send-amount-row/amount-max-button/{tests/amount-max-button-component.test.js => amount-max-button.component.test.js} (97%) rename ui/app/pages/send/send-content/send-amount-row/amount-max-button/{tests/amount-max-button-container.test.js => amount-max-button.container.test.js} (98%) rename ui/app/pages/send/send-content/send-amount-row/amount-max-button/{tests/amount-max-button-utils.test.js => amount-max-button.utils.test.js} (92%) rename ui/app/pages/send/send-content/send-amount-row/{tests/send-amount-row-component.test.js => send-amount-row.component.test.js} (94%) rename ui/app/pages/send/send-content/send-amount-row/{tests/send-amount-row-container.test.js => send-amount-row.container.test.js} (98%) rename ui/app/pages/send/send-content/{tests/send-content-component.test.js => send-content.component.test.js} (90%) rename ui/app/pages/send/send-content/send-gas-row/gas-fee-display/{tests => }/gas-fee-display.component.test.js (91%) rename ui/app/pages/send/send-content/send-gas-row/{tests/send-gas-row-component.test.js => send-gas-row.component.test.js} (92%) rename ui/app/pages/send/send-content/send-gas-row/{tests/send-gas-row-container.test.js => send-gas-row.container.test.js} (99%) rename ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/{tests/send-row-error-message-component.test.js => send-row-error-message.component.test.js} (93%) rename ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/{tests/send-row-error-message-container.test.js => send-row-error-message.container.test.js} (92%) rename ui/app/pages/send/send-content/send-row-wrapper/{tests/send-row-wrapper-component.test.js => send-row-wrapper.component.test.js} (95%) rename ui/app/pages/send/send-footer/{tests/send-footer-component.test.js => send-footer.component.test.js} (97%) rename ui/app/pages/send/send-footer/{tests/send-footer-container.test.js => send-footer.container.test.js} (99%) rename ui/app/pages/send/send-footer/{tests/send-footer-utils.test.js => send-footer.utils.test.js} (97%) rename ui/app/pages/send/send-header/{tests/send-header-component.test.js => send-header.component.test.js} (93%) rename ui/app/pages/send/{tests/send-component.test.js => send.component.test.js} (97%) rename ui/app/pages/send/{tests/send-container.test.js => send.container.test.js} (98%) rename ui/app/pages/send/{tests/send-utils.test.js => send.utils.test.js} (99%) rename ui/app/pages/settings/advanced-tab/{tests/advanced-tab-component.test.js => advanced-tab.component.test.js} (93%) rename ui/app/pages/settings/security-tab/{tests/security-tab.test.js => security-tab.container.test.js} (97%) rename ui/app/pages/settings/settings-tab/{tests/settings-tab.test.js => settings-tab.container.test.js} (97%) rename ui/app/pages/swaps/view-quote/{tests => }/view-quote-price-difference.test.js (97%) rename ui/app/pages/unlock-page/{tests/unlock-page.test.js => unlock-page.container.test.js} (97%) rename ui/app/selectors/{tests => }/confirm-transaction.test.js (94%) rename ui/app/selectors/{tests => }/custom-gas.test.js (99%) rename ui/app/selectors/{tests => }/permissions.test.js (99%) rename ui/app/selectors/{tests => }/selectors.test.js (96%) rename ui/app/selectors/{tests => }/send-selectors-test-data.js (98%) rename ui/app/selectors/{tests => }/send.test.js (99%) rename ui/app/selectors/{tests => }/transactions.test.js (98%) create mode 100644 ui/app/store/actionConstants.test.js rename {test/unit/ui/app => ui/app/store}/actions.test.js (96%) rename {test/unit => ui}/lib/account-link.test.js (93%) rename {test/unit/app/controllers/transactions => ui/lib}/tx-helper.test.js (85%) diff --git a/.eslintrc.js b/.eslintrc.js index 322d41a5e..68d30dcb3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -180,7 +180,11 @@ module.exports = { }, }, { - files: ['development/**/*.js', 'test/e2e/benchmark.js', 'test/helper.js'], + files: [ + 'development/**/*.js', + 'test/e2e/benchmark.js', + 'test/helpers/setup-helper.js', + ], rules: { 'node/no-process-exit': 'off', 'node/shebang': 'off', diff --git a/test/unit/app/account-import-strategies.test.js b/app/scripts/account-import-strategies/account-import-strategies.test.js similarity index 97% rename from test/unit/app/account-import-strategies.test.js rename to app/scripts/account-import-strategies/account-import-strategies.test.js index 5dc706b90..bc2f53ae7 100644 --- a/test/unit/app/account-import-strategies.test.js +++ b/app/scripts/account-import-strategies/account-import-strategies.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; import ethUtil from 'ethereumjs-util'; -import accountImporter from '../../../app/scripts/account-import-strategies'; +import accountImporter from '.'; describe('Account Import Strategies', function () { const privkey = diff --git a/test/unit/app/controllers/cached-balances.test.js b/app/scripts/controllers/cached-balances.test.js similarity index 95% rename from test/unit/app/controllers/cached-balances.test.js rename to app/scripts/controllers/cached-balances.test.js index cf2826024..94e86b41a 100644 --- a/test/unit/app/controllers/cached-balances.test.js +++ b/app/scripts/controllers/cached-balances.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import sinon from 'sinon'; -import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances'; -import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network'; +import { KOVAN_CHAIN_ID } from '../../../shared/constants/network'; +import CachedBalancesController from './cached-balances'; describe('CachedBalancesController', function () { describe('updateCachedBalances', function () { diff --git a/test/unit/app/controllers/detect-tokens.test.js b/app/scripts/controllers/detect-tokens.test.js similarity index 96% rename from test/unit/app/controllers/detect-tokens.test.js rename to app/scripts/controllers/detect-tokens.test.js index 458183d8b..c472c7977 100644 --- a/test/unit/app/controllers/detect-tokens.test.js +++ b/app/scripts/controllers/detect-tokens.test.js @@ -4,10 +4,10 @@ import { ObservableStore } from '@metamask/obs-store'; import contracts from '@metamask/contract-metadata'; import BigNumber from 'bignumber.js'; -import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens'; -import NetworkController from '../../../../app/scripts/controllers/network/network'; -import PreferencesController from '../../../../app/scripts/controllers/preferences'; -import { MAINNET, ROPSTEN } from '../../../../shared/constants/network'; +import { MAINNET, ROPSTEN } from '../../../shared/constants/network'; +import DetectTokensController from './detect-tokens'; +import NetworkController from './network'; +import PreferencesController from './preferences'; describe('DetectTokensController', function () { const sandbox = sinon.createSandbox(); diff --git a/test/unit/app/controllers/ens-controller.test.js b/app/scripts/controllers/ens/index.test.js similarity index 98% rename from test/unit/app/controllers/ens-controller.test.js rename to app/scripts/controllers/ens/index.test.js index d21a723e1..6e1a4c047 100644 --- a/test/unit/app/controllers/ens-controller.test.js +++ b/app/scripts/controllers/ens/index.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; import sinon from 'sinon'; -import EnsController from '../../../../app/scripts/controllers/ens'; +import EnsController from '.'; const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const ZERO_X_ERROR_ADDRESS = '0x'; diff --git a/test/unit/app/controllers/incoming-transactions.test.js b/app/scripts/controllers/incoming-transactions.test.js similarity index 99% rename from test/unit/app/controllers/incoming-transactions.test.js rename to app/scripts/controllers/incoming-transactions.test.js index af59bdd92..b7e52b19f 100644 --- a/test/unit/app/controllers/incoming-transactions.test.js +++ b/app/scripts/controllers/incoming-transactions.test.js @@ -4,7 +4,7 @@ import proxyquire from 'proxyquire'; import nock from 'nock'; import { cloneDeep } from 'lodash'; -import waitUntilCalled from '../../../lib/wait-until-called'; +import waitUntilCalled from '../../../test/lib/wait-until-called'; import { GOERLI, KOVAN, @@ -14,19 +14,16 @@ import { ROPSTEN, ROPSTEN_CHAIN_ID, ROPSTEN_NETWORK_ID, -} from '../../../../shared/constants/network'; +} from '../../../shared/constants/network'; import { TRANSACTION_TYPES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction'; -import { NETWORK_EVENTS } from '../../../../app/scripts/controllers/network'; - -const IncomingTransactionsController = proxyquire( - '../../../../app/scripts/controllers/incoming-transactions', - { - '../lib/random-id': { default: () => 54321 }, - }, -).default; +} from '../../../shared/constants/transaction'; +import { NETWORK_EVENTS } from './network'; + +const IncomingTransactionsController = proxyquire('./incoming-transactions', { + '../lib/random-id': { default: () => 54321 }, +}).default; const FAKE_CHAIN_ID = '0x1338'; const MOCK_SELECTED_ADDRESS = '0x0101'; diff --git a/test/unit/app/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js similarity index 97% rename from test/unit/app/controllers/metametrics.test.js rename to app/scripts/controllers/metametrics.test.js index 839b323c4..0d783badd 100644 --- a/test/unit/app/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -1,14 +1,14 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; -import MetaMetricsController from '../../../../app/scripts/controllers/metametrics'; -import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../shared/constants/app'; -import { createSegmentMock } from '../../../../app/scripts/lib/segment'; +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; +import { createSegmentMock } from '../lib/segment'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, -} from '../../../../shared/constants/metametrics'; -import waitUntilCalled from '../../../lib/wait-until-called'; -import { NETWORK_EVENTS } from '../../../../app/scripts/controllers/network'; +} from '../../../shared/constants/metametrics'; +import waitUntilCalled from '../../../test/lib/wait-until-called'; +import MetaMetricsController from './metametrics'; +import { NETWORK_EVENTS } from './network'; const segment = createSegmentMock(2, 10000); const segmentLegacy = createSegmentMock(2, 10000); diff --git a/test/unit/app/controllers/network/network-controller.test.js b/app/scripts/controllers/network/network-controller.test.js similarity index 95% rename from test/unit/app/controllers/network/network-controller.test.js rename to app/scripts/controllers/network/network-controller.test.js index b7e1ab502..3417241f6 100644 --- a/test/unit/app/controllers/network/network-controller.test.js +++ b/app/scripts/controllers/network/network-controller.test.js @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; -import NetworkController from '../../../../../app/scripts/controllers/network'; -import { getNetworkDisplayName } from '../../../../../app/scripts/controllers/network/util'; +import { getNetworkDisplayName } from './util'; +import NetworkController from './network'; describe('NetworkController', function () { describe('controller', function () { diff --git a/test/unit/app/controllers/network/pending-middleware.test.js b/app/scripts/controllers/network/pending-middleware.test.js similarity index 96% rename from test/unit/app/controllers/network/pending-middleware.test.js rename to app/scripts/controllers/network/pending-middleware.test.js index 65e011d09..1ce327b22 100644 --- a/test/unit/app/controllers/network/pending-middleware.test.js +++ b/app/scripts/controllers/network/pending-middleware.test.js @@ -1,9 +1,9 @@ import assert from 'assert'; +import { txMetaStub } from '../../../../test/stub/tx-meta-stub'; import { createPendingNonceMiddleware, createPendingTxMiddleware, -} from '../../../../../app/scripts/controllers/network/middleware/pending'; -import { txMetaStub } from './stubs'; +} from './middleware/pending'; describe('PendingNonceMiddleware', function () { describe('#createPendingNonceMiddleware', function () { diff --git a/test/unit/app/controllers/permissions/permissions-controller.test.js b/app/scripts/controllers/permissions/permissions-controller.test.js similarity index 99% rename from test/unit/app/controllers/permissions/permissions-controller.test.js rename to app/scripts/controllers/permissions/permissions-controller.test.js index b36467566..46fa9d10f 100644 --- a/test/unit/app/controllers/permissions/permissions-controller.test.js +++ b/app/scripts/controllers/permissions/permissions-controller.test.js @@ -2,22 +2,20 @@ import { strict as assert } from 'assert'; import { find } from 'lodash'; import sinon from 'sinon'; -import { - METADATA_STORE_KEY, - METADATA_CACHE_MAX_SIZE, -} from '../../../../../app/scripts/controllers/permissions/enums'; - -import { PermissionsController } from '../../../../../app/scripts/controllers/permissions'; - -import { getRequestUserApprovalHelper, grantPermissions } from './helpers'; - import { constants, getters, getNotifyDomain, getNotifyAllDomains, getPermControllerOpts, -} from './mocks'; +} from '../../../../test/mocks/permission-controller'; +import { + getRequestUserApprovalHelper, + grantPermissions, +} from '../../../../test/helpers/permission-controller-helpers'; +import { METADATA_STORE_KEY, METADATA_CACHE_MAX_SIZE } from './enums'; + +import { PermissionsController } from '.'; const { ERRORS, NOTIFICATIONS, PERMS } = getters; diff --git a/test/unit/app/controllers/permissions/permissions-log-controller.test.js b/app/scripts/controllers/permissions/permissions-log-controller.test.js similarity index 98% rename from test/unit/app/controllers/permissions/permissions-log-controller.test.js rename to app/scripts/controllers/permissions/permissions-log-controller.test.js index 05ff47a37..c973319e9 100644 --- a/test/unit/app/controllers/permissions/permissions-log-controller.test.js +++ b/app/scripts/controllers/permissions/permissions-log-controller.test.js @@ -3,16 +3,14 @@ import { ObservableStore } from '@metamask/obs-store'; import nanoid from 'nanoid'; import { useFakeTimers } from 'sinon'; -import PermissionsLogController from '../../../../../app/scripts/controllers/permissions/permissionsLog'; - import { - LOG_LIMIT, - LOG_METHOD_TYPES, -} from '../../../../../app/scripts/controllers/permissions/enums'; - -import { validateActivityEntry } from './helpers'; - -import { constants, getters, noop } from './mocks'; + constants, + getters, + noop, +} from '../../../../test/mocks/permission-controller'; +import { validateActivityEntry } from '../../../../test/helpers/permission-controller-helpers'; +import PermissionsLogController from './permissionsLog'; +import { LOG_LIMIT, LOG_METHOD_TYPES } from './enums'; const { PERMS, RPC_REQUESTS } = getters; @@ -50,7 +48,7 @@ const initMiddleware = (permLog) => { const initClock = () => { // useFakeTimers, is in fact, not a react-hook // eslint-disable-next-line - clock = useFakeTimers(1) + clock = useFakeTimers(1); }; const tearDownClock = () => { diff --git a/test/unit/app/controllers/permissions/permissions-middleware.test.js b/app/scripts/controllers/permissions/permissions-middleware.test.js similarity index 98% rename from test/unit/app/controllers/permissions/permissions-middleware.test.js rename to app/scripts/controllers/permissions/permissions-middleware.test.js index acb89ac05..dc027b1e7 100644 --- a/test/unit/app/controllers/permissions/permissions-middleware.test.js +++ b/app/scripts/controllers/permissions/permissions-middleware.test.js @@ -1,18 +1,19 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; -import { METADATA_STORE_KEY } from '../../../../../app/scripts/controllers/permissions/enums'; - -import { PermissionsController } from '../../../../../app/scripts/controllers/permissions'; - -import { getUserApprovalPromise, grantPermissions } from './helpers'; - import { constants, getters, getPermControllerOpts, getPermissionsMiddleware, -} from './mocks'; +} from '../../../../test/mocks/permission-controller'; +import { + getUserApprovalPromise, + grantPermissions, +} from '../../../../test/helpers/permission-controller-helpers'; +import { METADATA_STORE_KEY } from './enums'; + +import { PermissionsController } from '.'; const { CAVEATS, ERRORS, PERMS, RPC_REQUESTS } = getters; diff --git a/test/unit/app/controllers/permissions/restricted-methods.test.js b/app/scripts/controllers/permissions/restricted-methods.test.js similarity index 98% rename from test/unit/app/controllers/permissions/restricted-methods.test.js rename to app/scripts/controllers/permissions/restricted-methods.test.js index a5cf3dc0b..237cce4b5 100644 --- a/test/unit/app/controllers/permissions/restricted-methods.test.js +++ b/app/scripts/controllers/permissions/restricted-methods.test.js @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; import pify from 'pify'; -import getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'; +import getRestrictedMethods from './restrictedMethods'; describe('restricted methods', function () { describe('eth_accounts', function () { diff --git a/test/unit/app/controllers/preferences-controller.test.js b/app/scripts/controllers/preferences.test.js similarity index 99% rename from test/unit/app/controllers/preferences-controller.test.js rename to app/scripts/controllers/preferences.test.js index b56a6d65c..d7a702b6c 100644 --- a/test/unit/app/controllers/preferences-controller.test.js +++ b/app/scripts/controllers/preferences.test.js @@ -1,10 +1,10 @@ import assert from 'assert'; import sinon from 'sinon'; -import PreferencesController from '../../../../app/scripts/controllers/preferences'; import { MAINNET_CHAIN_ID, RINKEBY_CHAIN_ID, -} from '../../../../shared/constants/network'; +} from '../../../shared/constants/network'; +import PreferencesController from './preferences'; describe('preferences controller', function () { let preferencesController; diff --git a/test/unit/app/controllers/swaps.test.js b/app/scripts/controllers/swaps.test.js similarity index 99% rename from test/unit/app/controllers/swaps.test.js rename to app/scripts/controllers/swaps.test.js index 867eacef3..8fd07a18b 100644 --- a/test/unit/app/controllers/swaps.test.js +++ b/app/scripts/controllers/swaps.test.js @@ -8,13 +8,11 @@ import { ObservableStore } from '@metamask/obs-store'; import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID, -} from '../../../../shared/constants/network'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../shared/constants/swaps'; -import { createTestProviderTools } from '../../../stub/provider'; -import SwapsController, { - utils, -} from '../../../../app/scripts/controllers/swaps'; -import { NETWORK_EVENTS } from '../../../../app/scripts/controllers/network'; +} from '../../../shared/constants/network'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; +import { createTestProviderTools } from '../../../test/stub/provider'; +import SwapsController, { utils } from './swaps'; +import { NETWORK_EVENTS } from './network'; const MOCK_FETCH_PARAMS = { slippage: 3, diff --git a/test/unit/app/controllers/token-rates-controller.test.js b/app/scripts/controllers/token-rates-controller.test.js similarity index 92% rename from test/unit/app/controllers/token-rates-controller.test.js rename to app/scripts/controllers/token-rates-controller.test.js index 6c23abbaf..fc5d3af52 100644 --- a/test/unit/app/controllers/token-rates-controller.test.js +++ b/app/scripts/controllers/token-rates-controller.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import sinon from 'sinon'; import { ObservableStore } from '@metamask/obs-store'; -import TokenRatesController from '../../../../app/scripts/controllers/token-rates'; +import TokenRatesController from './token-rates'; describe('TokenRatesController', function () { let nativeCurrency; diff --git a/test/unit/app/controllers/transactions/tx-controller.test.js b/app/scripts/controllers/transactions/index.test.js similarity index 99% rename from test/unit/app/controllers/transactions/tx-controller.test.js rename to app/scripts/controllers/transactions/index.test.js index e6119a948..6a31e57a6 100644 --- a/test/unit/app/controllers/transactions/tx-controller.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -4,17 +4,17 @@ import ethUtil from 'ethereumjs-util'; import EthTx from 'ethereumjs-tx'; import { ObservableStore } from '@metamask/obs-store'; import sinon from 'sinon'; -import TransactionController from '../../../../../app/scripts/controllers/transactions'; import { createTestProviderTools, getTestAccounts, -} from '../../../../stub/provider'; +} from '../../../../test/stub/provider'; import { TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../shared/constants/transaction'; -import { METAMASK_CONTROLLER_EVENTS } from '../../../../../app/scripts/metamask-controller'; +} from '../../../../shared/constants/transaction'; +import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; +import TransactionController from '.'; const noop = () => true; const currentNetworkId = '42'; diff --git a/test/unit/app/controllers/transactions/tx-state-history-helpers.test.js b/app/scripts/controllers/transactions/lib/tx-state-history-helpers.test.js similarity index 96% rename from test/unit/app/controllers/transactions/tx-state-history-helpers.test.js rename to app/scripts/controllers/transactions/lib/tx-state-history-helpers.test.js index 6ff852bae..5e22b5d69 100644 --- a/test/unit/app/controllers/transactions/tx-state-history-helpers.test.js +++ b/app/scripts/controllers/transactions/lib/tx-state-history-helpers.test.js @@ -1,11 +1,11 @@ import { strict as assert } from 'assert'; +import testData from '../../../../../test/data/mock-tx-history.json'; import { snapshotFromTxMeta, migrateFromSnapshotsToDiffs, replayHistory, generateHistoryEntry, -} from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers'; -import testData from '../../../../data/mock-tx-history.json'; +} from './tx-state-history-helpers'; describe('Transaction state history helper', function () { describe('#snapshotFromTxMeta', function () { diff --git a/test/unit/app/controllers/transactions/tx-utils.test.js b/app/scripts/controllers/transactions/lib/util.test.js similarity index 98% rename from test/unit/app/controllers/transactions/tx-utils.test.js rename to app/scripts/controllers/transactions/lib/util.test.js index a643d9dea..f6dd83e4a 100644 --- a/test/unit/app/controllers/transactions/tx-utils.test.js +++ b/app/scripts/controllers/transactions/lib/util.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import * as txUtils from '../../../../../app/scripts/controllers/transactions/lib/util'; +import * as txUtils from './util'; describe('txUtils', function () { describe('#validateTxParams', function () { diff --git a/test/unit/app/controllers/transactions/pending-tx-tracker.test.js b/app/scripts/controllers/transactions/pending-tx-tracker.test.js similarity index 99% rename from test/unit/app/controllers/transactions/pending-tx-tracker.test.js rename to app/scripts/controllers/transactions/pending-tx-tracker.test.js index db0f4d1d3..b359b25f9 100644 --- a/test/unit/app/controllers/transactions/pending-tx-tracker.test.js +++ b/app/scripts/controllers/transactions/pending-tx-tracker.test.js @@ -1,8 +1,8 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; import BN from 'bn.js'; -import PendingTransactionTracker from '../../../../../app/scripts/controllers/transactions/pending-tx-tracker'; -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; +import PendingTransactionTracker from './pending-tx-tracker'; describe('PendingTransactionTracker', function () { describe('#resubmitPendingTxs', function () { diff --git a/test/unit/app/controllers/transactions/tx-gas-util.test.js b/app/scripts/controllers/transactions/tx-gas-utils.test.js similarity index 94% rename from test/unit/app/controllers/transactions/tx-gas-util.test.js rename to app/scripts/controllers/transactions/tx-gas-utils.test.js index d3e9cfddf..635802925 100644 --- a/test/unit/app/controllers/transactions/tx-gas-util.test.js +++ b/app/scripts/controllers/transactions/tx-gas-utils.test.js @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; import Transaction from 'ethereumjs-tx'; -import { hexToBn, bnToHex } from '../../../../../app/scripts/lib/util'; -import TxUtils from '../../../../../app/scripts/controllers/transactions/tx-gas-utils'; +import { hexToBn, bnToHex } from '../../lib/util'; +import TxUtils from './tx-gas-utils'; describe('txUtils', function () { let txUtils; diff --git a/test/unit/app/controllers/transactions/tx-state-manager.test.js b/app/scripts/controllers/transactions/tx-state-manager.test.js similarity index 98% rename from test/unit/app/controllers/transactions/tx-state-manager.test.js rename to app/scripts/controllers/transactions/tx-state-manager.test.js index db9a4bdbc..f9b421eeb 100644 --- a/test/unit/app/controllers/transactions/tx-state-manager.test.js +++ b/app/scripts/controllers/transactions/tx-state-manager.test.js @@ -1,12 +1,12 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; -import TxStateManager from '../../../../../app/scripts/controllers/transactions/tx-state-manager'; -import { snapshotFromTxMeta } from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers'; -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { KOVAN_CHAIN_ID, KOVAN_NETWORK_ID, -} from '../../../../../shared/constants/network'; +} from '../../../../shared/constants/network'; +import TxStateManager from './tx-state-manager'; +import { snapshotFromTxMeta } from './lib/tx-state-history-helpers'; const noop = () => true; diff --git a/test/unit/app/ComposableObservableStore.test.js b/app/scripts/lib/ComposableObservableStore.test.js similarity index 93% rename from test/unit/app/ComposableObservableStore.test.js rename to app/scripts/lib/ComposableObservableStore.test.js index 816e0de59..a079984c1 100644 --- a/test/unit/app/ComposableObservableStore.test.js +++ b/app/scripts/lib/ComposableObservableStore.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; import { ObservableStore } from '@metamask/obs-store'; -import ComposableObservableStore from '../../../app/scripts/lib/ComposableObservableStore'; +import ComposableObservableStore from './ComposableObservableStore'; describe('ComposableObservableStore', function () { it('should register initial state', function () { diff --git a/test/unit/app/buy-eth-url.test.js b/app/scripts/lib/buy-eth-url.test.js similarity index 95% rename from test/unit/app/buy-eth-url.test.js rename to app/scripts/lib/buy-eth-url.test.js index 7cf50bf8f..17ba3d64a 100644 --- a/test/unit/app/buy-eth-url.test.js +++ b/app/scripts/lib/buy-eth-url.test.js @@ -1,11 +1,11 @@ import assert from 'assert'; -import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url'; import { KOVAN_CHAIN_ID, MAINNET_CHAIN_ID, RINKEBY_CHAIN_ID, ROPSTEN_CHAIN_ID, } from '../../../shared/constants/network'; +import getBuyEthUrl from './buy-eth-url'; describe('buy-eth-url', function () { const mainnet = { diff --git a/test/unit/app/cleanErrorStack.test.js b/app/scripts/lib/cleanErrorStack.test.js similarity index 92% rename from test/unit/app/cleanErrorStack.test.js rename to app/scripts/lib/cleanErrorStack.test.js index e6bf8951f..9f01e8252 100644 --- a/test/unit/app/cleanErrorStack.test.js +++ b/app/scripts/lib/cleanErrorStack.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import cleanErrorStack from '../../../app/scripts/lib/cleanErrorStack'; +import cleanErrorStack from './cleanErrorStack'; describe('Clean Error Stack', function () { const testMessage = 'Test Message'; diff --git a/test/unit/app/message-manager.test.js b/app/scripts/lib/message-manager.test.js similarity index 98% rename from test/unit/app/message-manager.test.js rename to app/scripts/lib/message-manager.test.js index 2c0589e63..947cb2688 100644 --- a/test/unit/app/message-manager.test.js +++ b/app/scripts/lib/message-manager.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import MessageManager from '../../../app/scripts/lib/message-manager'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import MessageManager from './message-manager'; describe('Message Manager', function () { let messageManager; diff --git a/test/unit/migrations/migrator.test.js b/app/scripts/lib/migrator/index.test.js similarity index 92% rename from test/unit/migrations/migrator.test.js rename to app/scripts/lib/migrator/index.test.js index bb0771cd9..0fbb3e8a9 100644 --- a/test/unit/migrations/migrator.test.js +++ b/app/scripts/lib/migrator/index.test.js @@ -1,9 +1,9 @@ import fs from 'fs'; import assert from 'assert'; import { cloneDeep } from 'lodash'; -import Migrator from '../../../app/scripts/lib/migrator'; -import liveMigrations from '../../../app/scripts/migrations'; -import data from '../../../app/scripts/first-time-state'; +import liveMigrations from '../../migrations'; +import data from '../../first-time-state'; +import Migrator from '.'; const stubMigrations = [ { @@ -67,7 +67,7 @@ describe('migrations', function () { }); it('should have tests for all migrations', function () { - const fileNames = fs.readdirSync('./test/unit/migrations/'); + const fileNames = fs.readdirSync('./app/scripts/migrations/'); const testNumbers = fileNames .reduce((acc, filename) => { const name = filename.split('.test.')[0]; diff --git a/test/unit/app/nodeify.test.js b/app/scripts/lib/nodeify.test.js similarity index 97% rename from test/unit/app/nodeify.test.js rename to app/scripts/lib/nodeify.test.js index 2418f40bc..4f2c2a2eb 100644 --- a/test/unit/app/nodeify.test.js +++ b/app/scripts/lib/nodeify.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import nodeify from '../../../app/scripts/lib/nodeify'; +import nodeify from './nodeify'; describe('nodeify', function () { const obj = { diff --git a/test/unit/app/personal-message-manager.test.js b/app/scripts/lib/personal-message-manager.test.js similarity index 98% rename from test/unit/app/personal-message-manager.test.js rename to app/scripts/lib/personal-message-manager.test.js index 15035a111..c3ce3f615 100644 --- a/test/unit/app/personal-message-manager.test.js +++ b/app/scripts/lib/personal-message-manager.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import PersonalMessageManager from '../../../app/scripts/lib/personal-message-manager'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import PersonalMessageManager from './personal-message-manager'; describe('Personal Message Manager', function () { let messageManager; diff --git a/test/unit/app/seed-phrase-verifier.test.js b/app/scripts/lib/seed-phrase-verifier.test.js similarity index 95% rename from test/unit/app/seed-phrase-verifier.test.js rename to app/scripts/lib/seed-phrase-verifier.test.js index 650f97eb3..d7ac0143f 100644 --- a/test/unit/app/seed-phrase-verifier.test.js +++ b/app/scripts/lib/seed-phrase-verifier.test.js @@ -1,9 +1,9 @@ import assert from 'assert'; import { cloneDeep } from 'lodash'; import KeyringController from 'eth-keyring-controller'; -import firstTimeState from '../../../app/scripts/first-time-state'; -import seedPhraseVerifier from '../../../app/scripts/lib/seed-phrase-verifier'; -import mockEncryptor from '../../lib/mock-encryptor'; +import firstTimeState from '../first-time-state'; +import mockEncryptor from '../../../test/lib/mock-encryptor'; +import seedPhraseVerifier from './seed-phrase-verifier'; describe('SeedPhraseVerifier', function () { describe('verifyAccounts', function () { diff --git a/test/unit/app/typed-message-manager.test.js b/app/scripts/lib/typed-message-manager.test.js similarity index 97% rename from test/unit/app/typed-message-manager.test.js rename to app/scripts/lib/typed-message-manager.test.js index 5d7333688..c994a586f 100644 --- a/test/unit/app/typed-message-manager.test.js +++ b/app/scripts/lib/typed-message-manager.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import sinon from 'sinon'; -import TypedMessageManager from '../../../app/scripts/lib/typed-message-manager'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import TypedMessageManager from './typed-message-manager'; describe('Typed Message Manager', function () { let typedMessageManager, diff --git a/test/unit/app/util.test.js b/app/scripts/lib/util.test.js similarity index 98% rename from test/unit/app/util.test.js rename to app/scripts/lib/util.test.js index 7f9a285ff..c2753df56 100644 --- a/test/unit/app/util.test.js +++ b/app/scripts/lib/util.test.js @@ -1,8 +1,4 @@ import { strict as assert } from 'assert'; -import { - getEnvironmentType, - sufficientBalance, -} from '../../../app/scripts/lib/util'; import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils'; import { @@ -11,6 +7,7 @@ import { ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_BACKGROUND, } from '../../../shared/constants/app'; +import { getEnvironmentType, sufficientBalance } from './util'; describe('app utils', function () { describe('getEnvironmentType', function () { diff --git a/test/unit/app/controllers/metamask-controller.test.js b/app/scripts/metamask-controller.test.js similarity index 98% rename from test/unit/app/controllers/metamask-controller.test.js rename to app/scripts/metamask-controller.test.js index d92da4ed4..146eb0889 100644 --- a/test/unit/app/controllers/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -6,12 +6,23 @@ import ethUtil from 'ethereumjs-util'; import { obj as createThoughStream } from 'through2'; import EthQuery from 'eth-query'; import proxyquire from 'proxyquire'; -import firstTimeState from '../../localhostState'; -import createTxMeta from '../../../lib/createTxMeta'; -import { addHexPrefix } from '../../../../app/scripts/lib/util'; -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; - -const Ganache = require('../../../e2e/ganache'); +import { TRANSACTION_STATUSES } from '../../shared/constants/transaction'; +import createTxMeta from '../../test/lib/createTxMeta'; +import { NETWORK_TYPE_RPC } from '../../shared/constants/network'; +import { addHexPrefix } from './lib/util'; + +const Ganache = require('../../test/e2e/ganache'); + +const firstTimeState = { + config: {}, + NetworkController: { + provider: { + type: NETWORK_TYPE_RPC, + rpcUrl: 'http://localhost:8545', + chainId: '0x539', + }, + }, +}; const ganacheServer = new Ganache(); @@ -67,13 +78,10 @@ const createLoggerMiddlewareMock = () => (req, res, next) => { next(); }; -const MetaMaskController = proxyquire( - '../../../../app/scripts/metamask-controller', - { - './controllers/threebox': { default: ThreeBoxControllerMock }, - './lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock }, - }, -).default; +const MetaMaskController = proxyquire('./metamask-controller', { + './controllers/threebox': { default: ThreeBoxControllerMock }, + './lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock }, +}).default; const currentNetworkId = '42'; const DEFAULT_LABEL = 'Account 1'; diff --git a/test/unit/migrations/021.test.js b/app/scripts/migrations/021.test.js similarity index 80% rename from test/unit/migrations/021.test.js rename to app/scripts/migrations/021.test.js index d17615713..45c727e57 100644 --- a/test/unit/migrations/021.test.js +++ b/app/scripts/migrations/021.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import wallet2 from '../../lib/migrations/002.json'; -import migration21 from '../../../app/scripts/migrations/021'; +import wallet2 from '../../../test/lib/migrations/002.json'; +import migration21 from './021'; describe('wallet2 is migrated successfully with out the BlacklistController', function () { it('should delete BlacklistController key', function (done) { diff --git a/test/unit/migrations/022.test.js b/app/scripts/migrations/022.test.js similarity index 95% rename from test/unit/migrations/022.test.js rename to app/scripts/migrations/022.test.js index 537a2ba41..a102bcb7e 100644 --- a/test/unit/migrations/022.test.js +++ b/app/scripts/migrations/022.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import migration22 from '../../../app/scripts/migrations/022'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration22 from './022'; const properTime = new Date().getTime(); const storage = { diff --git a/test/unit/migrations/023.test.js b/app/scripts/migrations/023.test.js similarity index 98% rename from test/unit/migrations/023.test.js rename to app/scripts/migrations/023.test.js index d1eb7109b..0b40679b2 100644 --- a/test/unit/migrations/023.test.js +++ b/app/scripts/migrations/023.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import migration23 from '../../../app/scripts/migrations/023'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration23 from './023'; const storage = { meta: {}, diff --git a/test/unit/migrations/024.test.js b/app/scripts/migrations/024.test.js similarity index 93% rename from test/unit/migrations/024.test.js rename to app/scripts/migrations/024.test.js index a90729c5d..b2056193d 100644 --- a/test/unit/migrations/024.test.js +++ b/app/scripts/migrations/024.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; -import migration24 from '../../../app/scripts/migrations/024'; -import data from '../../../app/scripts/first-time-state'; +import data from '../first-time-state'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration24 from './024'; const firstTimeState = { meta: {}, diff --git a/test/unit/migrations/025.test.js b/app/scripts/migrations/025.test.js similarity index 93% rename from test/unit/migrations/025.test.js rename to app/scripts/migrations/025.test.js index f99db5010..7d666c517 100644 --- a/test/unit/migrations/025.test.js +++ b/app/scripts/migrations/025.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; -import migration25 from '../../../app/scripts/migrations/025'; -import data from '../../../app/scripts/first-time-state'; +import data from '../first-time-state'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration25 from './025'; const firstTimeState = { meta: {}, diff --git a/test/unit/migrations/026.test.js b/app/scripts/migrations/026.test.js similarity index 90% rename from test/unit/migrations/026.test.js rename to app/scripts/migrations/026.test.js index 684300ba5..71245115b 100644 --- a/test/unit/migrations/026.test.js +++ b/app/scripts/migrations/026.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import firstTimeState from '../../../app/scripts/first-time-state'; -import migration26 from '../../../app/scripts/migrations/026'; +import firstTimeState from '../first-time-state'; +import migration26 from './026'; const oldStorage = { meta: { version: 25 }, diff --git a/test/unit/migrations/027.test.js b/app/scripts/migrations/027.test.js similarity index 92% rename from test/unit/migrations/027.test.js rename to app/scripts/migrations/027.test.js index c6d2ada97..2687e17c2 100644 --- a/test/unit/migrations/027.test.js +++ b/app/scripts/migrations/027.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; -import firstTimeState from '../../../app/scripts/first-time-state'; -import migration27 from '../../../app/scripts/migrations/027'; +import firstTimeState from '../first-time-state'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration27 from './027'; const oldStorage = { meta: {}, diff --git a/test/unit/migrations/028.test.js b/app/scripts/migrations/028.test.js similarity index 94% rename from test/unit/migrations/028.test.js rename to app/scripts/migrations/028.test.js index d7483d116..01381e754 100644 --- a/test/unit/migrations/028.test.js +++ b/app/scripts/migrations/028.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import firstTimeState from '../../../app/scripts/first-time-state'; -import migration28 from '../../../app/scripts/migrations/028'; +import firstTimeState from '../first-time-state'; +import migration28 from './028'; const oldStorage = { meta: {}, diff --git a/test/unit/migrations/029.test.js b/app/scripts/migrations/029.test.js similarity index 96% rename from test/unit/migrations/029.test.js rename to app/scripts/migrations/029.test.js index 2eb97c128..90d698fd7 100644 --- a/test/unit/migrations/029.test.js +++ b/app/scripts/migrations/029.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import migration29 from '../../../app/scripts/migrations/029'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import migration29 from './029'; const properTime = new Date().getTime(); const storage = { diff --git a/test/unit/migrations/030.test.js b/app/scripts/migrations/030.test.js similarity index 95% rename from test/unit/migrations/030.test.js rename to app/scripts/migrations/030.test.js index 3610a72b0..985aa02e1 100644 --- a/test/unit/migrations/030.test.js +++ b/app/scripts/migrations/030.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migrationTemplate from '../../../app/scripts/migrations/030'; +import migrationTemplate from './030'; const storage = { meta: {}, diff --git a/test/unit/migrations/031.test.js b/app/scripts/migrations/031.test.js similarity index 96% rename from test/unit/migrations/031.test.js rename to app/scripts/migrations/031.test.js index 57159176b..d7b6ee046 100644 --- a/test/unit/migrations/031.test.js +++ b/app/scripts/migrations/031.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration31 from '../../../app/scripts/migrations/031'; +import migration31 from './031'; describe('migration #31', function () { it('should set completedOnboarding to true if vault exists', function (done) { diff --git a/test/unit/migrations/033.test.js b/app/scripts/migrations/033.test.js similarity index 93% rename from test/unit/migrations/033.test.js rename to app/scripts/migrations/033.test.js index ca8018460..bb12e83d7 100644 --- a/test/unit/migrations/033.test.js +++ b/app/scripts/migrations/033.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration33 from '../../../app/scripts/migrations/033'; +import migration33 from './033'; describe('Migration to delete notice controller', function () { const oldStorage = { diff --git a/test/unit/migrations/034.test.js b/app/scripts/migrations/034.test.js similarity index 97% rename from test/unit/migrations/034.test.js rename to app/scripts/migrations/034.test.js index e9554793d..bfb929997 100644 --- a/test/unit/migrations/034.test.js +++ b/app/scripts/migrations/034.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration34 from '../../../app/scripts/migrations/034'; +import migration34 from './034'; describe('migration #34', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/035.test.js b/app/scripts/migrations/035.test.js similarity index 97% rename from test/unit/migrations/035.test.js rename to app/scripts/migrations/035.test.js index f3e600df2..385f12fb5 100644 --- a/test/unit/migrations/035.test.js +++ b/app/scripts/migrations/035.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration35 from '../../../app/scripts/migrations/035'; +import migration35 from './035'; describe('migration #35', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/036.test.js b/app/scripts/migrations/036.test.js similarity index 97% rename from test/unit/migrations/036.test.js rename to app/scripts/migrations/036.test.js index 679fc8a3b..679080bf7 100644 --- a/test/unit/migrations/036.test.js +++ b/app/scripts/migrations/036.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration36 from '../../../app/scripts/migrations/036'; +import migration36 from './036'; describe('migration #36', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/037.test.js b/app/scripts/migrations/037.test.js similarity index 98% rename from test/unit/migrations/037.test.js rename to app/scripts/migrations/037.test.js index 78fe85cb5..0c145bccf 100644 --- a/test/unit/migrations/037.test.js +++ b/app/scripts/migrations/037.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration37 from '../../../app/scripts/migrations/037'; +import migration37 from './037'; describe('migration #37', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/038.test.js b/app/scripts/migrations/038.test.js similarity index 95% rename from test/unit/migrations/038.test.js rename to app/scripts/migrations/038.test.js index c1e8e2a1e..93d826f78 100644 --- a/test/unit/migrations/038.test.js +++ b/app/scripts/migrations/038.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration38 from '../../../app/scripts/migrations/038'; +import migration38 from './038'; describe('migration #38', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/039.test.js b/app/scripts/migrations/039.test.js similarity index 99% rename from test/unit/migrations/039.test.js rename to app/scripts/migrations/039.test.js index 8cfc3e0b1..55ba12982 100644 --- a/test/unit/migrations/039.test.js +++ b/app/scripts/migrations/039.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration39 from '../../../app/scripts/migrations/039'; +import migration39 from './039'; describe('migration #39', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/040.test.js b/app/scripts/migrations/040.test.js similarity index 94% rename from test/unit/migrations/040.test.js rename to app/scripts/migrations/040.test.js index 98fce305b..f4d1de68e 100644 --- a/test/unit/migrations/040.test.js +++ b/app/scripts/migrations/040.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration40 from '../../../app/scripts/migrations/040'; +import migration40 from './040'; describe('migration #40', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/041.test.js b/app/scripts/migrations/041.test.js similarity index 96% rename from test/unit/migrations/041.test.js rename to app/scripts/migrations/041.test.js index e61ce66e2..7c6e4c567 100644 --- a/test/unit/migrations/041.test.js +++ b/app/scripts/migrations/041.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration41 from '../../../app/scripts/migrations/041'; +import migration41 from './041'; describe('migration #41', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/042.test.js b/app/scripts/migrations/042.test.js similarity index 96% rename from test/unit/migrations/042.test.js rename to app/scripts/migrations/042.test.js index 9159fb756..7cca8d2a7 100644 --- a/test/unit/migrations/042.test.js +++ b/app/scripts/migrations/042.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration42 from '../../../app/scripts/migrations/042'; +import migration42 from './042'; describe('migration #42', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/043.test.js b/app/scripts/migrations/043.test.js similarity index 95% rename from test/unit/migrations/043.test.js rename to app/scripts/migrations/043.test.js index 25ac0336d..aa37f13d7 100644 --- a/test/unit/migrations/043.test.js +++ b/app/scripts/migrations/043.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration43 from '../../../app/scripts/migrations/043'; +import migration43 from './043'; describe('migration #43', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/044.test.js b/app/scripts/migrations/044.test.js similarity index 96% rename from test/unit/migrations/044.test.js rename to app/scripts/migrations/044.test.js index 0b53b506b..35b95762d 100644 --- a/test/unit/migrations/044.test.js +++ b/app/scripts/migrations/044.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration44 from '../../../app/scripts/migrations/044'; +import migration44 from './044'; describe('migration #44', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/045.test.js b/app/scripts/migrations/045.test.js similarity index 96% rename from test/unit/migrations/045.test.js rename to app/scripts/migrations/045.test.js index bd102a927..907489195 100644 --- a/test/unit/migrations/045.test.js +++ b/app/scripts/migrations/045.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration45 from '../../../app/scripts/migrations/045'; +import migration45 from './045'; describe('migration #45', function () { it('should update the version metadata', function (done) { diff --git a/test/unit/migrations/046.test.js b/app/scripts/migrations/046.test.js similarity index 94% rename from test/unit/migrations/046.test.js rename to app/scripts/migrations/046.test.js index 43a79da94..05e3b93dd 100644 --- a/test/unit/migrations/046.test.js +++ b/app/scripts/migrations/046.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration46 from '../../../app/scripts/migrations/046'; +import migration46 from './046'; describe('migration #46', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/047.test.js b/app/scripts/migrations/047.test.js similarity index 97% rename from test/unit/migrations/047.test.js rename to app/scripts/migrations/047.test.js index 12dc35fdf..7124a274c 100644 --- a/test/unit/migrations/047.test.js +++ b/app/scripts/migrations/047.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration47 from '../../../app/scripts/migrations/047'; +import migration47 from './047'; describe('migration #47', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/048.test.js b/app/scripts/migrations/048.test.js similarity index 99% rename from test/unit/migrations/048.test.js rename to app/scripts/migrations/048.test.js index cd731c38e..a46212cfd 100644 --- a/test/unit/migrations/048.test.js +++ b/app/scripts/migrations/048.test.js @@ -1,5 +1,5 @@ import { strict as assert } from 'assert'; -import migration48 from '../../../app/scripts/migrations/048'; +import migration48 from './048'; const localhostNetwork = { rpcUrl: 'http://localhost:8545', diff --git a/test/unit/migrations/049.test.js b/app/scripts/migrations/049.test.js similarity index 97% rename from test/unit/migrations/049.test.js rename to app/scripts/migrations/049.test.js index df441a47a..5242fab52 100644 --- a/test/unit/migrations/049.test.js +++ b/app/scripts/migrations/049.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migration49 from '../../../app/scripts/migrations/049'; +import migration49 from './049'; describe('migration #49', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/050.test.js b/app/scripts/migrations/050.test.js similarity index 97% rename from test/unit/migrations/050.test.js rename to app/scripts/migrations/050.test.js index 05aa735ae..fd942ee87 100644 --- a/test/unit/migrations/050.test.js +++ b/app/scripts/migrations/050.test.js @@ -1,6 +1,6 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; -import migration50 from '../../../app/scripts/migrations/050'; +import migration50 from './050'; const LEGACY_LOCAL_STORAGE_KEYS = [ 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', diff --git a/test/unit/migrations/051.test.js b/app/scripts/migrations/051.test.js similarity index 98% rename from test/unit/migrations/051.test.js rename to app/scripts/migrations/051.test.js index 4d1428a87..8d32fbf2c 100644 --- a/test/unit/migrations/051.test.js +++ b/app/scripts/migrations/051.test.js @@ -1,9 +1,9 @@ import { strict as assert } from 'assert'; -import migration51 from '../../../app/scripts/migrations/051'; import { INFURA_PROVIDER_TYPES, NETWORK_TYPE_TO_ID_MAP, } from '../../../shared/constants/network'; +import migration51 from './051'; describe('migration #51', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/052.test.js b/app/scripts/migrations/052.test.js similarity index 99% rename from test/unit/migrations/052.test.js rename to app/scripts/migrations/052.test.js index 23dc7c603..8d9d13afb 100644 --- a/test/unit/migrations/052.test.js +++ b/app/scripts/migrations/052.test.js @@ -1,5 +1,4 @@ import assert from 'assert'; -import migration52 from '../../../app/scripts/migrations/052'; import { GOERLI, GOERLI_CHAIN_ID, @@ -13,6 +12,7 @@ import { ROPSTEN, ROPSTEN_CHAIN_ID, } from '../../../shared/constants/network'; +import migration52 from './052'; const TOKEN1 = { symbol: 'TST', address: '0x10', decimals: 18 }; const TOKEN2 = { symbol: 'TXT', address: '0x11', decimals: 18 }; diff --git a/test/unit/migrations/053.test.js b/app/scripts/migrations/053.test.js similarity index 98% rename from test/unit/migrations/053.test.js rename to app/scripts/migrations/053.test.js index 92d3055bc..788110afa 100644 --- a/test/unit/migrations/053.test.js +++ b/app/scripts/migrations/053.test.js @@ -1,6 +1,6 @@ import { strict as assert } from 'assert'; -import migration53 from '../../../app/scripts/migrations/053'; import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; +import migration53 from './053'; describe('migration #53', function () { it('should update the version metadata', async function () { diff --git a/test/unit/migrations/migrations.test.js b/app/scripts/migrations/migrations.test.js similarity index 89% rename from test/unit/migrations/migrations.test.js rename to app/scripts/migrations/migrations.test.js index d5fcd6bdc..a7c921323 100644 --- a/test/unit/migrations/migrations.test.js +++ b/app/scripts/migrations/migrations.test.js @@ -1,18 +1,18 @@ import assert from 'assert'; -import wallet1 from '../../lib/migrations/001.json'; -import vault4 from '../../lib/migrations/004.json'; -import migration2 from '../../../app/scripts/migrations/002'; -import migration3 from '../../../app/scripts/migrations/003'; -import migration4 from '../../../app/scripts/migrations/004'; -import migration5 from '../../../app/scripts/migrations/005'; -import migration6 from '../../../app/scripts/migrations/006'; -import migration7 from '../../../app/scripts/migrations/007'; -import migration8 from '../../../app/scripts/migrations/008'; -import migration9 from '../../../app/scripts/migrations/009'; -import migration10 from '../../../app/scripts/migrations/010'; -import migration11 from '../../../app/scripts/migrations/011'; -import migration12 from '../../../app/scripts/migrations/012'; -import migration13 from '../../../app/scripts/migrations/013'; +import wallet1 from '../../../test/lib/migrations/001.json'; +import vault4 from '../../../test/lib/migrations/004.json'; +import migration2 from './002'; +import migration3 from './003'; +import migration4 from './004'; +import migration5 from './005'; +import migration6 from './006'; +import migration7 from './007'; +import migration8 from './008'; +import migration9 from './009'; +import migration10 from './010'; +import migration11 from './011'; +import migration12 from './012'; +import migration13 from './013'; let vault5, vault6, vault7, vault8, vault9; // vault10, vault11 diff --git a/test/unit/migrations/template.test.js b/app/scripts/migrations/template.test.js similarity index 82% rename from test/unit/migrations/template.test.js rename to app/scripts/migrations/template.test.js index 79b127ed9..92a4e8937 100644 --- a/test/unit/migrations/template.test.js +++ b/app/scripts/migrations/template.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import migrationTemplate from '../../../app/scripts/migrations/template'; +import migrationTemplate from './template'; const storage = { meta: {}, diff --git a/package.json b/package.json index 8ce98d545..3fa468bce 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ "forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010", "dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'", "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", - "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", + "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive './{ui,app,shared}/**/*.test.js'", "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js", - "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", - "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.test.js\"", + "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive './{ui,app,shared}/{,**/!(permissions)}/*.test.js'", + "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive 'app/scripts/controllers/permissions/*.test.js'", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", "test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js", diff --git a/test/unit/app/fetch-with-timeout.test.js b/shared/modules/fetch-with-timeout.test.js similarity index 95% rename from test/unit/app/fetch-with-timeout.test.js rename to shared/modules/fetch-with-timeout.test.js index 9a8aae403..a7b1daa1a 100644 --- a/test/unit/app/fetch-with-timeout.test.js +++ b/shared/modules/fetch-with-timeout.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import nock from 'nock'; -import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; +import getFetchWithTimeout from './fetch-with-timeout'; describe('getFetchWithTimeout', function () { it('fetches a url', async function () { diff --git a/test/unit/app/controllers/permissions/helpers.js b/test/helpers/permission-controller-helpers.js similarity index 98% rename from test/unit/app/controllers/permissions/helpers.js rename to test/helpers/permission-controller-helpers.js index 4317ed683..5100da5a5 100644 --- a/test/unit/app/controllers/permissions/helpers.js +++ b/test/helpers/permission-controller-helpers.js @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; import stringify from 'fast-safe-stringify'; -import { noop } from './mocks'; +import { noop } from '../mocks/permission-controller'; /** * Grants the given permissions to the given origin, using the given permissions diff --git a/test/helper.js b/test/helpers/setup-helper.js similarity index 100% rename from test/helper.js rename to test/helpers/setup-helper.js diff --git a/test/unit/app/controllers/permissions/mocks.js b/test/mocks/permission-controller.js similarity index 98% rename from test/unit/app/controllers/permissions/mocks.js rename to test/mocks/permission-controller.js index ddbf9ff41..2d1a61555 100644 --- a/test/unit/app/controllers/permissions/mocks.js +++ b/test/mocks/permission-controller.js @@ -3,13 +3,13 @@ import deepFreeze from 'deep-freeze-strict'; import { ApprovalController } from '@metamask/controllers'; -import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'; +import _getRestrictedMethods from '../../app/scripts/controllers/permissions/restrictedMethods'; -import { CAVEAT_NAMES } from '../../../../../shared/constants/permissions'; +import { CAVEAT_NAMES } from '../../shared/constants/permissions'; import { CAVEAT_TYPES, NOTIFICATION_NAMES, -} from '../../../../../app/scripts/controllers/permissions/enums'; +} from '../../app/scripts/controllers/permissions/enums'; /** * README diff --git a/test/setup.js b/test/setup.js index a4795b61b..57e79a557 100644 --- a/test/setup.js +++ b/test/setup.js @@ -1,6 +1,6 @@ require('@babel/register'); -require('./helper'); +require('./helpers/setup-helper'); window.SVGPathElement = window.SVGPathElement || { prototype: {} }; global.indexedDB = {}; diff --git a/test/unit/app/controllers/network/stubs.js b/test/stub/tx-meta-stub.js similarity index 98% rename from test/unit/app/controllers/network/stubs.js rename to test/stub/tx-meta-stub.js index 4021bcddd..0af67dd20 100644 --- a/test/unit/app/controllers/network/stubs.js +++ b/test/stub/tx-meta-stub.js @@ -1,7 +1,7 @@ import { TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../shared/constants/transaction'; +} from '../../shared/constants/transaction'; export const txMetaStub = { firstRetryBlockNumber: '0x51a402', diff --git a/test/unit/balance-formatter.test.js b/test/unit-global/balance-formatter.test.js similarity index 100% rename from test/unit/balance-formatter.test.js rename to test/unit-global/balance-formatter.test.js diff --git a/test/unit/actions/config.test.js b/test/unit/actions/config.test.js deleted file mode 100644 index 7b31cd84f..000000000 --- a/test/unit/actions/config.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import assert from 'assert'; -import freeze from 'deep-freeze-strict'; -import reducers from '../../../ui/app/ducks'; -import * as actionConstants from '../../../ui/app/store/actionConstants'; -import { NETWORK_TYPE_RPC } from '../../../shared/constants/network'; - -describe('config view actions', function () { - const initialState = { - metamask: { - rpcUrl: 'foo', - frequentRpcList: [], - }, - appState: { - currentView: { - name: 'accounts', - }, - }, - }; - freeze(initialState); - - describe('SET_RPC_TARGET', function () { - it('sets the state.metamask.rpcUrl property of the state to the action.value', function () { - const action = { - type: actionConstants.SET_RPC_TARGET, - value: 'foo', - }; - - const result = reducers(initialState, action); - assert.equal(result.metamask.provider.type, NETWORK_TYPE_RPC); - assert.equal(result.metamask.provider.rpcUrl, 'foo'); - }); - }); -}); diff --git a/test/unit/actions/set_account_label.test.js b/test/unit/actions/set_account_label.test.js deleted file mode 100644 index 7bdb0d22c..000000000 --- a/test/unit/actions/set_account_label.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import assert from 'assert'; -import freeze from 'deep-freeze-strict'; -import reducers from '../../../ui/app/ducks'; -import * as actionConstants from '../../../ui/app/store/actionConstants'; - -describe('SET_ACCOUNT_LABEL', function () { - it('updates the state.metamask.identities[:i].name property of the state to the action.value.label', function () { - const initialState = { - metamask: { - identities: { - foo: { - name: 'bar', - }, - }, - }, - }; - freeze(initialState); - - const action = { - type: actionConstants.SET_ACCOUNT_LABEL, - value: { - account: 'foo', - label: 'baz', - }, - }; - freeze(action); - - const resultingState = reducers(initialState, action); - assert.equal( - resultingState.metamask.identities.foo.name, - action.value.label, - ); - }); -}); diff --git a/test/unit/actions/set_selected_account.test.js b/test/unit/actions/set_selected_account.test.js deleted file mode 100644 index 9f9a79036..000000000 --- a/test/unit/actions/set_selected_account.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import assert from 'assert'; -import freeze from 'deep-freeze-strict'; -import reducers from '../../../ui/app/ducks'; -import * as actionConstants from '../../../ui/app/store/actionConstants'; - -describe('SHOW_ACCOUNT_DETAIL', function () { - it('updates metamask state', function () { - const initialState = { - metamask: { - selectedAddress: 'foo', - }, - }; - freeze(initialState); - - const action = { - type: actionConstants.SHOW_ACCOUNT_DETAIL, - value: 'bar', - }; - freeze(action); - - const resultingState = reducers(initialState, action); - assert.equal(resultingState.metamask.selectedAddress, action.value); - }); -}); diff --git a/test/unit/actions/tx.test.js b/test/unit/actions/tx.test.js deleted file mode 100644 index 120fcdb73..000000000 --- a/test/unit/actions/tx.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import assert from 'assert'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import * as actions from '../../../ui/app/store/actions'; -import * as actionConstants from '../../../ui/app/store/actionConstants'; -import { ROPSTEN_CHAIN_ID } from '../../../shared/constants/network'; - -const middlewares = [thunk]; -const mockStore = configureMockStore(middlewares); - -describe('tx confirmation screen', function () { - const txId = 1457634084250832; - const initialState = { - appState: {}, - metamask: { - unapprovedTxs: { - [txId]: { - id: txId, - status: 'unconfirmed', - time: 1457634084250, - }, - }, - provider: { - chainId: ROPSTEN_CHAIN_ID, - }, - }, - }; - - const store = mockStore(initialState); - - describe('cancelTx', function () { - it('creates COMPLETED_TX with the cancelled transaction ID', async function () { - actions._setBackgroundConnection({ - approveTransaction(_, cb) { - cb(new Error('An error!')); - }, - cancelTransaction(_, cb) { - cb(); - }, - getState(cb) { - cb(null, {}); - }, - }); - - await store.dispatch(actions.cancelTx({ id: txId })); - const storeActions = store.getActions(); - const completedTxAction = storeActions.find( - ({ type }) => type === actionConstants.COMPLETED_TX, - ); - const { id } = completedTxAction.value; - assert.equal(id, txId); - }); - }); -}); diff --git a/test/unit/actions/warning.test.js b/test/unit/actions/warning.test.js deleted file mode 100644 index 2ec35525b..000000000 --- a/test/unit/actions/warning.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import assert from 'assert'; -import freeze from 'deep-freeze-strict'; -import * as actions from '../../../ui/app/store/actions'; -import reducers from '../../../ui/app/ducks'; - -describe('action DISPLAY_WARNING', function () { - it('sets appState.warning to provided value', function () { - const initialState = { - appState: {}, - }; - freeze(initialState); - - const warningText = 'This is a sample warning message'; - - const action = actions.displayWarning(warningText); - const resultingState = reducers(initialState, action); - - assert.equal( - resultingState.appState.warning, - warningText, - 'warning text set', - ); - }); -}); diff --git a/test/unit/localhostState.js b/test/unit/localhostState.js deleted file mode 100644 index b758b9120..000000000 --- a/test/unit/localhostState.js +++ /dev/null @@ -1,23 +0,0 @@ -import { NETWORK_TYPE_RPC } from '../../shared/constants/network'; - -/** - * @typedef {Object} FirstTimeState - * @property {Object} config Initial configuration parameters - * @property {Object} NetworkController Network controller state - */ - -/** - * @type {FirstTimeState} - */ -const initialState = { - config: {}, - NetworkController: { - provider: { - type: NETWORK_TYPE_RPC, - rpcUrl: 'http://localhost:8545', - chainId: '0x539', - }, - }, -}; - -export default initialState; diff --git a/test/unit/responsive/components/dropdown.test.js b/test/unit/responsive/components/dropdown.test.js deleted file mode 100644 index a7f83b07d..000000000 --- a/test/unit/responsive/components/dropdown.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import assert from 'assert'; -import React from 'react'; -import configureMockStore from 'redux-mock-store'; -import { fireEvent } from '@testing-library/react'; -import sinon from 'sinon'; -import { renderWithProvider } from '../../../lib/render-helpers'; -import { Dropdown } from '../../../../ui/app/components/app/dropdowns/components/dropdown'; - -describe('Dropdown components', function () { - const mockState = { - metamask: {}, - }; - - const props = { - isOpen: true, - zIndex: 11, - onClickOutside: sinon.spy(), - style: { - position: 'absolute', - right: 0, - top: '36px', - }, - innerStyle: {}, - }; - - it('invokes click handler when item clicked', function () { - const store = configureMockStore()(mockState); - - const onClickSpy = sinon.spy(); - - const { getByText } = renderWithProvider( - -
  • Item 1
  • -
  • Item 2
  • -
    , - store, - ); - - const item1 = getByText(/Item 1/u); - fireEvent.click(item1); - - assert.ok(onClickSpy.calledOnce); - }); -}); diff --git a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/app/account-list-item/account-list-item-component.test.js similarity index 97% rename from ui/app/components/app/account-list-item/tests/account-list-item-component.test.js rename to ui/app/components/app/account-list-item/account-list-item-component.test.js index 558f9cebe..e4d894c58 100644 --- a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js +++ b/ui/app/components/app/account-list-item/account-list-item-component.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import * as utils from '../../../../helpers/utils/util'; -import Identicon from '../../../ui/identicon'; -import AccountListItem from '../account-list-item'; +import * as utils from '../../../helpers/utils/util'; +import Identicon from '../../ui/identicon'; +import AccountListItem from './account-list-item'; describe('AccountListItem Component', function () { let wrapper, propsMethodSpies, checksumAddressStub; diff --git a/ui/app/components/app/account-menu/tests/account-menu.test.js b/ui/app/components/app/account-menu/account-menu.test.js similarity index 98% rename from ui/app/components/app/account-menu/tests/account-menu.test.js rename to ui/app/components/app/account-menu/account-menu.test.js index 147cbb09e..bbc4675d3 100644 --- a/ui/app/components/app/account-menu/tests/account-menu.test.js +++ b/ui/app/components/app/account-menu/account-menu.test.js @@ -3,8 +3,8 @@ import React from 'react'; import sinon from 'sinon'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import AccountMenu from '..'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import AccountMenu from '.'; describe('Account Menu', function () { let wrapper; diff --git a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js b/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js similarity index 94% rename from ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js rename to ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js index 57cae337e..e9219a145 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js @@ -7,11 +7,11 @@ import thunk from 'redux-thunk'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; -import * as actions from '../../../../../store/actions'; -import UnconnectedAccountAlert from '..'; -import { KOVAN_CHAIN_ID } from '../../../../../../../shared/constants/network'; +import * as actions from '../../../../store/actions'; +import { KOVAN_CHAIN_ID } from '../../../../../../shared/constants/network'; +import UnconnectedAccountAlert from '.'; describe('Unconnected Account Alert', function () { const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b'; diff --git a/ui/app/components/app/app-header/tests/app-header.test.js b/ui/app/components/app/app-header/app-header.test.js similarity index 94% rename from ui/app/components/app/app-header/tests/app-header.test.js rename to ui/app/components/app/app-header/app-header.test.js index 40045defc..bee0ee2e0 100644 --- a/ui/app/components/app/app-header/tests/app-header.test.js +++ b/ui/app/components/app/app-header/app-header.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import MetaFoxLogo from '../../../ui/metafox-logo'; -import AppHeader from '..'; -import NetworkDisplay from '../../network-display'; +import MetaFoxLogo from '../../ui/metafox-logo'; +import NetworkDisplay from '../network-display'; +import AppHeader from './app-header.container'; describe('App Header', function () { let wrapper; diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.test.js similarity index 97% rename from ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js rename to ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.test.js index c019f3a5b..ea958d529 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import ConfirmDetailRow from '../confirm-detail-row.component'; +import ConfirmDetailRow from './confirm-detail-row.component'; const propsMethodSpies = { onHeaderClick: sinon.spy(), diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/tests/confirm-page-container-header.component.test.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.test.js similarity index 86% rename from ui/app/components/app/confirm-page-container/confirm-page-container-header/tests/confirm-page-container-header.component.test.js rename to ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.test.js index 24da85a38..e75893572 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-header/tests/confirm-page-container-header.component.test.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.test.js @@ -3,11 +3,11 @@ import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import { Provider } from 'react-redux'; -import ConfirmPageContainerHeader from '../confirm-page-container-header.component'; -import configureStore from '../../../../../store/store'; -import testData from '../../../../../../../.storybook/test-data'; +import configureStore from '../../../../store/store'; +import testData from '../../../../../../.storybook/test-data'; +import ConfirmPageContainerHeader from './confirm-page-container-header.component'; -const util = require('../../../../../../../app/scripts/lib/util'); +const util = require('../../../../../../app/scripts/lib/util'); describe('Confirm Detail Row Component', function () { describe('render', function () { diff --git a/ui/app/components/app/dropdowns/components/dropdown.js b/ui/app/components/app/dropdowns/dropdown.js similarity index 98% rename from ui/app/components/app/dropdowns/components/dropdown.js rename to ui/app/components/app/dropdowns/dropdown.js index 0c1a7f88f..79dc5be2d 100644 --- a/ui/app/components/app/dropdowns/components/dropdown.js +++ b/ui/app/components/app/dropdowns/dropdown.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import MenuDroppo from '../../menu-droppo'; +import MenuDroppo from '../menu-droppo'; export class Dropdown extends Component { render() { diff --git a/ui/app/components/app/dropdowns/tests/dropdown.test.js b/ui/app/components/app/dropdowns/dropdown.test.js similarity index 93% rename from ui/app/components/app/dropdowns/tests/dropdown.test.js rename to ui/app/components/app/dropdowns/dropdown.test.js index 63faf3341..e0a7a2ae4 100644 --- a/ui/app/components/app/dropdowns/tests/dropdown.test.js +++ b/ui/app/components/app/dropdowns/dropdown.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import { DropdownMenuItem } from '../components/dropdown'; +import { DropdownMenuItem } from './dropdown'; describe('Dropdown', function () { let wrapper; diff --git a/ui/app/components/app/dropdowns/network-dropdown.js b/ui/app/components/app/dropdowns/network-dropdown.js index bc04a2fed..e0742722d 100644 --- a/ui/app/components/app/dropdowns/network-dropdown.js +++ b/ui/app/components/app/dropdowns/network-dropdown.js @@ -16,7 +16,7 @@ import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; import ColorIndicator from '../../ui/color-indicator'; import { COLORS, SIZES } from '../../../helpers/constants/design-system'; -import { Dropdown, DropdownMenuItem } from './components/dropdown'; +import { Dropdown, DropdownMenuItem } from './dropdown'; // classes from nodes of the toggle element. const notToggleElementClassnames = [ diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js b/ui/app/components/app/dropdowns/network-dropdown.test.js similarity index 93% rename from ui/app/components/app/dropdowns/tests/network-dropdown.test.js rename to ui/app/components/app/dropdowns/network-dropdown.test.js index c7f872c6a..83bd713a7 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js +++ b/ui/app/components/app/dropdowns/network-dropdown.test.js @@ -2,10 +2,10 @@ import assert from 'assert'; import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import NetworkDropdown from '../network-dropdown'; -import { DropdownMenuItem } from '../components/dropdown'; -import ColorIndicator from '../../../ui/color-indicator'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import ColorIndicator from '../../ui/color-indicator'; +import NetworkDropdown from './network-dropdown'; +import { DropdownMenuItem } from './dropdown'; describe('Network Dropdown', function () { let wrapper; diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js similarity index 98% rename from ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js rename to ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js index 59c762619..bccef80ab 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import AdvancedTabContent from '..'; +import AdvancedTabContent from './advanced-gas-inputs.container'; describe('Advanced Gas Inputs', function () { let wrapper, clock; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content-component.test.js similarity index 94% rename from ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js rename to ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content-component.test.js index 4b1bdc21d..f98546649 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content-component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import shallow from '../../../../../../../lib/shallow-with-context'; -import AdvancedTabContent from '../advanced-tab-content.component'; +import shallow from '../../../../../../lib/shallow-with-context'; +import AdvancedTabContent from './advanced-tab-content.component'; describe('AdvancedTabContent Component', function () { let wrapper; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content-component.test.js similarity index 90% rename from ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js rename to ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content-component.test.js index e0597a5a0..77d18c8cf 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content-component.test.js @@ -1,10 +1,10 @@ import assert from 'assert'; import React from 'react'; -import shallow from '../../../../../../../lib/shallow-with-context'; -import BasicTabContent from '../basic-tab-content.component'; -import GasPriceButtonGroup from '../../../gas-price-button-group'; -import Loading from '../../../../../ui/loading-screen'; -import { GAS_ESTIMATE_TYPES } from '../../../../../../helpers/constants/common'; +import shallow from '../../../../../../lib/shallow-with-context'; +import GasPriceButtonGroup from '../../gas-price-button-group'; +import Loading from '../../../../ui/loading-screen'; +import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common'; +import BasicTabContent from './basic-tab-content.component'; const mockGasPriceButtonGroupProps = { buttonDataLoading: false, diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-component.test.js similarity index 97% rename from ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js rename to ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-component.test.js index 1fede0503..ba0793740 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-component.test.js @@ -1,12 +1,12 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import shallow from '../../../../../../lib/shallow-with-context'; -import GasModalPageContainer from '../gas-modal-page-container.component'; +import shallow from '../../../../../lib/shallow-with-context'; -import PageContainer from '../../../../ui/page-container'; +import PageContainer from '../../../ui/page-container'; -import { Tab } from '../../../../ui/tabs'; +import { Tab } from '../../../ui/tabs'; +import GasModalPageContainer from './gas-modal-page-container.component'; const mockBasicGasEstimates = { average: '20', diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js similarity index 99% rename from ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js rename to ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js index 9863582e2..2e9008e8e 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js @@ -21,7 +21,7 @@ const sendActionSpies = { hideGasButtonGroup: sinon.spy(), }; -proxyquire('../gas-modal-page-container.container.js', { +proxyquire('./gas-modal-page-container.container.js', { 'react-redux': { connect: (_, md, mp) => { mapDispatchToProps = md; diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group-component.test.js similarity index 97% rename from ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js rename to ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group-component.test.js index 7bf35c1a8..04426e6b7 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group-component.test.js @@ -1,11 +1,11 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import shallow from '../../../../../../lib/shallow-with-context'; -import GasPriceButtonGroup from '../gas-price-button-group.component'; -import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common'; +import shallow from '../../../../../lib/shallow-with-context'; +import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; -import ButtonGroup from '../../../../ui/button-group'; +import ButtonGroup from '../../../ui/button-group'; +import GasPriceButtonGroup from './gas-price-button-group.component'; describe('GasPriceButtonGroup Component', function () { let mockButtonPropsAndFlags; diff --git a/ui/app/components/app/info-box/tests/info-box.test.js b/ui/app/components/app/info-box/info-box.test.js similarity index 95% rename from ui/app/components/app/info-box/tests/info-box.test.js rename to ui/app/components/app/info-box/info-box.test.js index 04c5056d5..7b1107336 100644 --- a/ui/app/components/app/info-box/tests/info-box.test.js +++ b/ui/app/components/app/info-box/info-box.test.js @@ -3,7 +3,7 @@ import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import InfoBox from '..'; +import InfoBox from './info-box.component'; describe('InfoBox', function () { let wrapper; diff --git a/ui/app/components/app/menu-bar/tests/menu-bar.test.js b/ui/app/components/app/menu-bar/menu-bar.test.js similarity index 90% rename from ui/app/components/app/menu-bar/tests/menu-bar.test.js rename to ui/app/components/app/menu-bar/menu-bar.test.js index fbac945f2..a1bfba6d4 100644 --- a/ui/app/components/app/menu-bar/tests/menu-bar.test.js +++ b/ui/app/components/app/menu-bar/menu-bar.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import MenuBar from '..'; -import { ROPSTEN_CHAIN_ID } from '../../../../../../shared/constants/network'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import { ROPSTEN_CHAIN_ID } from '../../../../../shared/constants/network'; +import MenuBar from './menu-bar'; const initState = { activeTab: {}, diff --git a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js b/ui/app/components/app/modal/modal-content/modal-content.component.test.js similarity index 96% rename from ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js rename to ui/app/components/app/modal/modal-content/modal-content.component.test.js index 485b2f951..5d6de2f38 100644 --- a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js +++ b/ui/app/components/app/modal/modal-content/modal-content.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import ModalContent from '../modal-content.component'; +import ModalContent from './modal-content.component'; describe('ModalContent Component', function () { it('should render a title', function () { diff --git a/ui/app/components/app/modal/tests/modal.component.test.js b/ui/app/components/app/modal/modal.component.test.js similarity index 98% rename from ui/app/components/app/modal/tests/modal.component.test.js rename to ui/app/components/app/modal/modal.component.test.js index 8af9d394b..0e4ccc9e8 100644 --- a/ui/app/components/app/modal/tests/modal.component.test.js +++ b/ui/app/components/app/modal/modal.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import { mount, shallow } from 'enzyme'; import sinon from 'sinon'; -import Modal from '../modal.component'; -import Button from '../../../ui/button'; +import Button from '../../ui/button'; +import Modal from './modal.component'; describe('Modal Component', function () { it('should render a modal with a submit button', function () { diff --git a/ui/app/components/app/modals/tests/account-details-modal.test.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.test.js similarity index 96% rename from ui/app/components/app/modals/tests/account-details-modal.test.js rename to ui/app/components/app/modals/account-details-modal/account-details-modal.test.js index 304b76d7c..1de8b1d23 100644 --- a/ui/app/components/app/modals/tests/account-details-modal.test.js +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import AccountDetailsModal from '../account-details-modal'; +import AccountDetailsModal from './account-details-modal.container'; describe('Account Details Modal', function () { let wrapper; diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js similarity index 83% rename from ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js rename to ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js index 5d4ca39e6..0630d1f08 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import CancelTransactionGasFee from '../cancel-transaction-gas-fee.component'; -import UserPreferencedCurrencyDisplay from '../../../../user-preferenced-currency-display'; +import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display'; +import CancelTransactionGasFee from './cancel-transaction-gas-fee.component'; describe('CancelTransactionGasFee Component', function () { it('should render', function () { diff --git a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.test.js similarity index 92% rename from ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js rename to ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.test.js index 9d75d3dab..9cba4687c 100644 --- a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import CancelTransaction from '../cancel-transaction.component'; -import CancelTransactionGasFee from '../cancel-transaction-gas-fee'; -import Modal from '../../../modal'; +import Modal from '../../modal'; +import CancelTransaction from './cancel-transaction.component'; +import CancelTransactionGasFee from './cancel-transaction-gas-fee'; describe('CancelTransaction Component', function () { const t = (key) => key; diff --git a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.test.js similarity index 95% rename from ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js rename to ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.test.js index 28d7e8214..3984971fb 100644 --- a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js +++ b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import ConfirmDeleteNetwork from '..'; +import ConfirmDeleteNetwork from './confirm-delete-network.container'; describe('Confirm Delete Network', function () { let wrapper; diff --git a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js similarity index 96% rename from ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js rename to ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js index f070092c2..c73ce8458 100644 --- a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js +++ b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js @@ -5,7 +5,7 @@ import { Provider } from 'react-redux'; import sinon from 'sinon'; import configureStore from 'redux-mock-store'; import { mount } from 'enzyme'; -import ConfirmRemoveAccount from '..'; +import ConfirmRemoveAccount from './confirm-remove-account.container'; describe('Confirm Remove Account', function () { let wrapper; diff --git a/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.test.js similarity index 94% rename from ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js rename to ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.test.js index 38af4a5a3..1239ddf4e 100644 --- a/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js +++ b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import ConfirmResetAccount from '..'; +import ConfirmResetAccount from './confirm-reset-account.container'; describe('Confirm Reset Account', function () { let wrapper; diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.test.js similarity index 92% rename from ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js rename to ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.test.js index a34ad9905..4c0f60003 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import MetaMetricsOptIn from '..'; -import messages from '../../../../../../../app/_locales/en/messages.json'; +import messages from '../../../../../../app/_locales/en/messages.json'; +import MetaMetricsOptIn from './metametrics-opt-in-modal.container'; describe('MetaMetrics Opt In', function () { let wrapper; diff --git a/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js b/ui/app/components/app/modals/reject-transactions/reject-transactions.test.js similarity index 94% rename from ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js rename to ui/app/components/app/modals/reject-transactions/reject-transactions.test.js index 7988d2681..439faa3ab 100644 --- a/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js +++ b/ui/app/components/app/modals/reject-transactions/reject-transactions.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import RejectTransactionsModal from '..'; +import RejectTransactionsModal from './reject-transactions.container'; describe('Reject Transactions Model', function () { let wrapper; diff --git a/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.test.js similarity index 90% rename from ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js rename to ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.test.js index 5ca602785..e005a38d8 100644 --- a/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js +++ b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import TransactionConfirmed from '..'; +import TransactionConfirmed from './transaction-confirmed.container'; describe('Transaction Confirmed', function () { it('clicks ok to submit and hide modal', function () { diff --git a/ui/app/components/app/selected-account/tests/selected-account-component.test.js b/ui/app/components/app/selected-account/selected-account-component.test.js similarity index 92% rename from ui/app/components/app/selected-account/tests/selected-account-component.test.js rename to ui/app/components/app/selected-account/selected-account-component.test.js index 4cc81396d..dbf0afad3 100644 --- a/ui/app/components/app/selected-account/tests/selected-account-component.test.js +++ b/ui/app/components/app/selected-account/selected-account-component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { render } from 'enzyme'; -import SelectedAccount from '../selected-account.component'; +import SelectedAccount from './selected-account.component'; describe('SelectedAccount Component', function () { it('should render checksummed address', function () { diff --git a/ui/app/components/app/sidebars/tests/sidebars-component.test.js b/ui/app/components/app/sidebars/sidebar.component.test.js similarity index 96% rename from ui/app/components/app/sidebars/tests/sidebars-component.test.js rename to ui/app/components/app/sidebars/sidebar.component.test.js index 6ce792716..d8d325e71 100644 --- a/ui/app/components/app/sidebars/tests/sidebars-component.test.js +++ b/ui/app/components/app/sidebars/sidebar.component.test.js @@ -3,9 +3,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; -import Sidebar from '../sidebar.component'; - -import CustomizeGas from '../../gas-customization/gas-modal-page-container'; +import CustomizeGas from '../gas-customization/gas-modal-page-container'; +import Sidebar from './sidebar.component'; const propsMethodSpies = { hideSidebar: sinon.spy(), diff --git a/ui/app/components/app/signature-request/tests/signature-request.test.js b/ui/app/components/app/signature-request/signature-request.component.test.js similarity index 86% rename from ui/app/components/app/signature-request/tests/signature-request.test.js rename to ui/app/components/app/signature-request/signature-request.component.test.js index 261576f16..fb2526c20 100644 --- a/ui/app/components/app/signature-request/tests/signature-request.test.js +++ b/ui/app/components/app/signature-request/signature-request.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; -import shallow from '../../../../../lib/shallow-with-context'; -import SignatureRequest from '../signature-request.component'; +import shallow from '../../../../lib/shallow-with-context'; +import SignatureRequest from './signature-request.component'; describe('Signature Request Component', function () { describe('render', function () { diff --git a/ui/app/components/app/tests/signature-request.test.js b/ui/app/components/app/signature-request/signature-request.container.test.js similarity index 97% rename from ui/app/components/app/tests/signature-request.test.js rename to ui/app/components/app/signature-request/signature-request.container.test.js index 700b99a91..35453d513 100644 --- a/ui/app/components/app/tests/signature-request.test.js +++ b/ui/app/components/app/signature-request/signature-request.container.test.js @@ -4,7 +4,7 @@ import { Provider } from 'react-redux'; import sinon from 'sinon'; import configureMockStore from 'redux-mock-store'; import { mountWithRouter } from '../../../../../test/lib/render-helpers'; -import SignatureRequest from '../signature-request'; +import SignatureRequest from './signature-request.container'; describe('Signature Request', function () { let wrapper; diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.test.js similarity index 98% rename from ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js rename to ui/app/components/app/transaction-activity-log/transaction-activity-log.component.test.js index 149ebd4c4..8fac60422 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import TransactionActivityLog from '../transaction-activity-log.component'; +import TransactionActivityLog from './transaction-activity-log.component'; describe('TransactionActivityLog Component', function () { it('should render properly', function () { diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.test.js similarity index 96% rename from ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js rename to ui/app/components/app/transaction-activity-log/transaction-activity-log.container.test.js index 612a0f046..6ca0d8787 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.test.js @@ -3,7 +3,7 @@ import proxyquire from 'proxyquire'; let mapStateToProps; -proxyquire('../transaction-activity-log.container.js', { +proxyquire('./transaction-activity-log.container.js', { 'react-redux': { connect: (ms) => { mapStateToProps = ms; diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.test.js similarity index 98% rename from ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js rename to ui/app/components/app/transaction-activity-log/transaction-activity-log.util.test.js index 8421dca96..2d9987850 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.test.js @@ -2,15 +2,15 @@ import assert from 'assert'; import { ROPSTEN_CHAIN_ID, ROPSTEN_NETWORK_ID, -} from '../../../../../../shared/constants/network'; +} from '../../../../../shared/constants/network'; import { TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../../shared/constants/transaction'; +} from '../../../../../shared/constants/transaction'; import { combineTransactionHistories, getActivities, -} from '../transaction-activity-log.util'; +} from './transaction-activity-log.util'; describe('TransactionActivityLog utils', function () { describe('combineTransactionHistories', function () { diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js similarity index 91% rename from ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js rename to ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js index 70929e527..7d2aff7a6 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import TransactionBreakdownRow from '../transaction-breakdown-row.component'; -import Button from '../../../../ui/button'; +import Button from '../../../ui/button'; +import TransactionBreakdownRow from './transaction-breakdown-row.component'; describe('TransactionBreakdownRow Component', function () { it('should render text properly', function () { diff --git a/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.test.js similarity index 83% rename from ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js rename to ui/app/components/app/transaction-breakdown/transaction-breakdown.component.test.js index 1e4b89a8f..1d5dcf0f5 100644 --- a/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import TransactionBreakdown from '../transaction-breakdown.component'; -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; +import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; +import TransactionBreakdown from './transaction-breakdown.component'; describe('TransactionBreakdown Component', function () { it('should render properly', function () { diff --git a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js similarity index 92% rename from ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js rename to ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js index a333ecd98..e92a8b2dd 100644 --- a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js +++ b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js @@ -1,12 +1,12 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import TransactionListItemDetails from '../transaction-list-item-details.component'; -import Button from '../../../ui/button'; -import SenderToRecipient from '../../../ui/sender-to-recipient'; -import TransactionBreakdown from '../../transaction-breakdown'; -import TransactionActivityLog from '../../transaction-activity-log'; -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; +import Button from '../../ui/button'; +import SenderToRecipient from '../../ui/sender-to-recipient'; +import TransactionBreakdown from '../transaction-breakdown'; +import TransactionActivityLog from '../transaction-activity-log'; +import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; +import TransactionListItemDetails from './transaction-list-item-details.component'; describe('TransactionListItemDetails Component', function () { it('should render properly', function () { diff --git a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js b/ui/app/components/app/transaction-status/transaction-status.component.test.js similarity index 91% rename from ui/app/components/app/transaction-status/tests/transaction-status.component.test.js rename to ui/app/components/app/transaction-status/transaction-status.component.test.js index 2300081de..f824160b5 100644 --- a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js +++ b/ui/app/components/app/transaction-status/transaction-status.component.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import { mount } from 'enzyme'; import sinon from 'sinon'; -import * as i18nHook from '../../../../hooks/useI18nContext'; -import TransactionStatus from '../transaction-status.component'; -import Tooltip from '../../../ui/tooltip'; +import * as i18nHook from '../../../hooks/useI18nContext'; +import Tooltip from '../../ui/tooltip'; +import TransactionStatus from './transaction-status.component'; describe('TransactionStatus Component', function () { before(function () { diff --git a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.test.js similarity index 80% rename from ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js rename to ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.test.js index 7b57d9265..52e896ce6 100644 --- a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.test.js @@ -2,10 +2,10 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display.component'; -import CurrencyDisplay from '../../../ui/currency-display'; -import * as currencyHook from '../../../../hooks/useCurrencyDisplay'; -import * as currencyPrefHook from '../../../../hooks/useUserPreferencedCurrency'; +import CurrencyDisplay from '../../ui/currency-display'; +import * as currencyHook from '../../../hooks/useCurrencyDisplay'; +import * as currencyPrefHook from '../../../hooks/useUserPreferencedCurrency'; +import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display.component'; describe('UserPreferencedCurrencyDisplay Component', function () { describe('rendering', function () { diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js similarity index 87% rename from ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js rename to ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js index f0c704459..b52b931a7 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import UserPreferencedCurrencyInput from '../user-preferenced-currency-input.component'; -import CurrencyInput from '../../../ui/currency-input'; +import CurrencyInput from '../../ui/currency-input'; +import UserPreferencedCurrencyInput from './user-preferenced-currency-input.component'; describe('UserPreferencedCurrencyInput Component', function () { describe('rendering', function () { diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js similarity index 91% rename from ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js rename to ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js index 40234c9c5..b0f096550 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js @@ -3,7 +3,7 @@ import proxyquire from 'proxyquire'; let mapStateToProps; -proxyquire('../user-preferenced-currency-input.container.js', { +proxyquire('./user-preferenced-currency-input.container.js', { 'react-redux': { connect: (ms) => { mapStateToProps = ms; diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.test.js similarity index 88% rename from ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js rename to ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.test.js index 3fc20f657..98ca3760f 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js +++ b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import UserPreferencedTokenInput from '../user-preferenced-token-input.component'; -import TokenInput from '../../../ui/token-input'; +import TokenInput from '../../ui/token-input'; +import UserPreferencedTokenInput from './user-preferenced-token-input.component'; describe('UserPreferencedCurrencyInput Component', function () { describe('rendering', function () { diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.test.js similarity index 91% rename from ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js rename to ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.test.js index 9ff33f0f5..f91d2132b 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js +++ b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.test.js @@ -3,7 +3,7 @@ import proxyquire from 'proxyquire'; let mapStateToProps; -proxyquire('../user-preferenced-token-input.container.js', { +proxyquire('./user-preferenced-token-input.container.js', { 'react-redux': { connect: (ms) => { mapStateToProps = ms; diff --git a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js b/ui/app/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js similarity index 84% rename from ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js rename to ui/app/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js index febddd53b..7e3abbae2 100644 --- a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js +++ b/ui/app/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js @@ -3,9 +3,9 @@ import React from 'react'; import * as reactRedux from 'react-redux'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import InfoIcon from '../../icon/info-icon.component'; -import AccountMismatchWarning from '../account-mismatch-warning.component'; -import { getSelectedAccount } from '../../../../selectors'; +import InfoIcon from '../icon/info-icon.component'; +import { getSelectedAccount } from '../../../selectors'; +import AccountMismatchWarning from './account-mismatch-warning.component'; describe('AccountMismatchWarning', function () { before(function () { diff --git a/ui/app/components/ui/alert/tests/alert.test.js b/ui/app/components/ui/alert/index.test.js similarity index 97% rename from ui/app/components/ui/alert/tests/alert.test.js rename to ui/app/components/ui/alert/index.test.js index 64c519e0e..ead7edaea 100644 --- a/ui/app/components/ui/alert/tests/alert.test.js +++ b/ui/app/components/ui/alert/index.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import Alert from '..'; +import Alert from '.'; describe('Alert', function () { let wrapper; diff --git a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js b/ui/app/components/ui/breadcrumbs/breadcrumbs.component.test.js similarity index 93% rename from ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js rename to ui/app/components/ui/breadcrumbs/breadcrumbs.component.test.js index c2f7af83b..451d1af4b 100644 --- a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js +++ b/ui/app/components/ui/breadcrumbs/breadcrumbs.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import Breadcrumbs from '../breadcrumbs.component'; +import Breadcrumbs from './breadcrumbs.component'; describe('Breadcrumbs Component', function () { it('should render with the correct colors', function () { diff --git a/ui/app/components/ui/button-group/tests/button-group-component.test.js b/ui/app/components/ui/button-group/button-group-component.test.js similarity index 98% rename from ui/app/components/ui/button-group/tests/button-group-component.test.js rename to ui/app/components/ui/button-group/button-group-component.test.js index a7e82cc45..5cbae1292 100644 --- a/ui/app/components/ui/button-group/tests/button-group-component.test.js +++ b/ui/app/components/ui/button-group/button-group-component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import ButtonGroup from '../button-group.component'; +import ButtonGroup from './button-group.component'; describe('ButtonGroup Component', function () { let wrapper; diff --git a/ui/app/components/ui/card/tests/card.component.test.js b/ui/app/components/ui/card/card.component.test.js similarity index 94% rename from ui/app/components/ui/card/tests/card.component.test.js rename to ui/app/components/ui/card/card.component.test.js index 2f1d4b43c..98a1d102b 100644 --- a/ui/app/components/ui/card/tests/card.component.test.js +++ b/ui/app/components/ui/card/card.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import Card from '../card.component'; +import Card from './card.component'; describe('Card Component', function () { it('should render a card with a title and child element', function () { diff --git a/ui/app/components/ui/confusable/test/confusable.component.test.js b/ui/app/components/ui/confusable/confusable.component.test.js similarity index 94% rename from ui/app/components/ui/confusable/test/confusable.component.test.js rename to ui/app/components/ui/confusable/confusable.component.test.js index d3166ccd7..79f4074a6 100644 --- a/ui/app/components/ui/confusable/test/confusable.component.test.js +++ b/ui/app/components/ui/confusable/confusable.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import Confusable from '../confusable.component'; +import Confusable from './confusable.component'; describe('Confusable component', function () { it('should detect zero-width unicode', function () { diff --git a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js b/ui/app/components/ui/currency-display/currency-display.component.test.js similarity index 94% rename from ui/app/components/ui/currency-display/tests/currency-display.component.test.js rename to ui/app/components/ui/currency-display/currency-display.component.test.js index 295d4c463..ce81e58f1 100644 --- a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js +++ b/ui/app/components/ui/currency-display/currency-display.component.test.js @@ -3,7 +3,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import * as reactRedux from 'react-redux'; -import CurrencyDisplay from '../currency-display.component'; +import CurrencyDisplay from './currency-display.component'; describe('CurrencyDisplay Component', function () { beforeEach(function () { diff --git a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js b/ui/app/components/ui/currency-input/currency-input.component.test.js similarity index 98% rename from ui/app/components/ui/currency-input/tests/currency-input.component.test.js rename to ui/app/components/ui/currency-input/currency-input.component.test.js index f47154b5c..aa233dc17 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js +++ b/ui/app/components/ui/currency-input/currency-input.component.test.js @@ -5,9 +5,9 @@ import { shallow, mount } from 'enzyme'; import sinon from 'sinon'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; -import CurrencyInput from '../currency-input.component'; -import UnitInput from '../../unit-input'; -import CurrencyDisplay from '../../currency-display'; +import UnitInput from '../unit-input'; +import CurrencyDisplay from '../currency-display'; +import CurrencyInput from './currency-input.component'; describe('CurrencyInput Component', function () { describe('rendering', function () { diff --git a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js b/ui/app/components/ui/currency-input/currency-input.container.test.js similarity index 98% rename from ui/app/components/ui/currency-input/tests/currency-input.container.test.js rename to ui/app/components/ui/currency-input/currency-input.container.test.js index a0858288a..3748d103d 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js +++ b/ui/app/components/ui/currency-input/currency-input.container.test.js @@ -3,7 +3,7 @@ import proxyquire from 'proxyquire'; let mapStateToProps, mergeProps; -proxyquire('../currency-input.container.js', { +proxyquire('./currency-input.container.js', { 'react-redux': { connect: (ms, _, mp) => { mapStateToProps = ms; diff --git a/ui/app/components/ui/error-message/tests/error-message.component.test.js b/ui/app/components/ui/error-message/error-message.component.test.js similarity index 95% rename from ui/app/components/ui/error-message/tests/error-message.component.test.js rename to ui/app/components/ui/error-message/error-message.component.test.js index a6c2d4ac3..7fc75472a 100644 --- a/ui/app/components/ui/error-message/tests/error-message.component.test.js +++ b/ui/app/components/ui/error-message/error-message.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import ErrorMessage from '../error-message.component'; +import ErrorMessage from './error-message.component'; describe('ErrorMessage Component', function () { const t = (key) => `translate ${key}`; diff --git a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js b/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.test.js similarity index 92% rename from ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js rename to ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.test.js index 30bff9fce..c10cedeb8 100644 --- a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js +++ b/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import HexToDecimal from '../hex-to-decimal.component'; +import HexToDecimal from './hex-to-decimal.component'; describe('HexToDecimal Component', function () { it('should render a prefixed hex as a decimal with a className', function () { diff --git a/ui/app/components/ui/identicon/tests/identicon.component.test.js b/ui/app/components/ui/identicon/identicon.component.test.js similarity index 96% rename from ui/app/components/ui/identicon/tests/identicon.component.test.js rename to ui/app/components/ui/identicon/identicon.component.test.js index 3d33397ea..5eb3d920d 100644 --- a/ui/app/components/ui/identicon/tests/identicon.component.test.js +++ b/ui/app/components/ui/identicon/identicon.component.test.js @@ -3,7 +3,7 @@ import React from 'react'; import thunk from 'redux-thunk'; import configureMockStore from 'redux-mock-store'; import { mount } from 'enzyme'; -import Identicon from '../identicon.component'; +import Identicon from './identicon.component'; describe('Identicon', function () { const state = { diff --git a/ui/app/components/ui/list-item/tests/list-item.test.js b/ui/app/components/ui/list-item/list-item.component.test.js similarity index 93% rename from ui/app/components/ui/list-item/tests/list-item.test.js rename to ui/app/components/ui/list-item/list-item.component.test.js index 488ee9039..7936027bf 100644 --- a/ui/app/components/ui/list-item/tests/list-item.test.js +++ b/ui/app/components/ui/list-item/list-item.component.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import { shallow } from 'enzyme'; import React from 'react'; import Sinon from 'sinon'; -import ListItem from '../list-item.component'; -import Preloader from '../../icon/preloader/preloader-icon.component'; -import Send from '../../icon/send-icon.component'; +import Preloader from '../icon/preloader/preloader-icon.component'; +import Send from '../icon/send-icon.component'; +import ListItem from './list-item.component'; const TITLE = 'Hello World'; const SUBTITLE =

    I am a list item

    ; diff --git a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js b/ui/app/components/ui/metafox-logo/metafox-logo.component.test.js similarity index 96% rename from ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js rename to ui/app/components/ui/metafox-logo/metafox-logo.component.test.js index 3c0f725a4..eb929e4fc 100644 --- a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js +++ b/ui/app/components/ui/metafox-logo/metafox-logo.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { mount } from 'enzyme'; -import MetaFoxLogo from '..'; +import MetaFoxLogo from '.'; describe('MetaFoxLogo', function () { it('sets icon height and width to 42 by default', function () { diff --git a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js b/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.test.js similarity index 96% rename from ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js rename to ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.test.js index 56c798f65..8ca003142 100644 --- a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js +++ b/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import Button from '../../../button'; -import PageFooter from '../page-container-footer.component'; +import Button from '../../button'; +import PageFooter from './page-container-footer.component'; describe('Page Footer', function () { let wrapper; diff --git a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js b/ui/app/components/ui/page-container/page-container-header/page-container-header.component.test.js similarity index 97% rename from ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js rename to ui/app/components/ui/page-container/page-container-header/page-container-header.component.test.js index 1c96ee0e5..e465f28e8 100644 --- a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js +++ b/ui/app/components/ui/page-container/page-container-header/page-container-header.component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import PageContainerHeader from '../page-container-header.component'; +import PageContainerHeader from './page-container-header.component'; describe('Page Container Header', function () { let wrapper, style, onBackButtonClick, onClose; diff --git a/ui/app/components/ui/token-input/tests/token-input.component.test.js b/ui/app/components/ui/token-input/token-input.component.test.js similarity index 98% rename from ui/app/components/ui/token-input/tests/token-input.component.test.js rename to ui/app/components/ui/token-input/token-input.component.test.js index 479d63b0e..59f4af171 100644 --- a/ui/app/components/ui/token-input/tests/token-input.component.test.js +++ b/ui/app/components/ui/token-input/token-input.component.test.js @@ -5,9 +5,9 @@ import { shallow, mount } from 'enzyme'; import sinon from 'sinon'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; -import TokenInput from '../token-input.component'; -import UnitInput from '../../unit-input'; -import CurrencyDisplay from '../../currency-display'; +import UnitInput from '../unit-input'; +import CurrencyDisplay from '../currency-display'; +import TokenInput from './token-input.component'; describe('TokenInput Component', function () { const t = (key) => `translate ${key}`; diff --git a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js b/ui/app/components/ui/unit-input/unit-input.component.test.js similarity index 98% rename from ui/app/components/ui/unit-input/tests/unit-input.component.test.js rename to ui/app/components/ui/unit-input/unit-input.component.test.js index 032b9b76e..99b0ad4a7 100644 --- a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js +++ b/ui/app/components/ui/unit-input/unit-input.component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow, mount } from 'enzyme'; import sinon from 'sinon'; -import UnitInput from '../unit-input.component'; +import UnitInput from './unit-input.component'; describe('UnitInput Component', function () { describe('rendering', function () { diff --git a/test/unit/ui/app/reducers/app.test.js b/ui/app/ducks/app/app.test.js similarity index 98% rename from test/unit/ui/app/reducers/app.test.js rename to ui/app/ducks/app/app.test.js index f95060e32..8cc8d4204 100644 --- a/test/unit/ui/app/reducers/app.test.js +++ b/ui/app/ducks/app/app.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import reduceApp from '../../../../../ui/app/ducks/app/app'; -import * as actionConstants from '../../../../../ui/app/store/actionConstants'; +import * as actionConstants from '../../store/actionConstants'; +import reduceApp from './app'; const actions = actionConstants; diff --git a/test/unit/ui/app/reducers/metamask.test.js b/ui/app/ducks/metamask/metamask.test.js similarity index 98% rename from test/unit/ui/app/reducers/metamask.test.js rename to ui/app/ducks/metamask/metamask.test.js index faf765b86..de56aacc2 100644 --- a/test/unit/ui/app/reducers/metamask.test.js +++ b/ui/app/ducks/metamask/metamask.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import reduceMetamask from '../../../../../ui/app/ducks/metamask/metamask'; -import * as actionConstants from '../../../../../ui/app/store/actionConstants'; +import * as actionConstants from '../../store/actionConstants'; +import reduceMetamask from './metamask'; describe('MetaMask Reducers', function () { it('init state', function () { diff --git a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js b/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.test.js similarity index 96% rename from ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js rename to ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.test.js index 79339b4ad..f47269a2e 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import configureMockStore from 'redux-mock-store'; import { mount } from 'enzyme'; import React from 'react'; -import withModalProps from '../with-modal-props'; +import withModalProps from './with-modal-props'; const mockState = { appState: { diff --git a/ui/app/hooks/tests/useCancelTransaction.test.js b/ui/app/hooks/useCancelTransaction.test.js similarity index 92% rename from ui/app/hooks/tests/useCancelTransaction.test.js rename to ui/app/hooks/useCancelTransaction.test.js index f88b3cee8..96e14ea78 100644 --- a/ui/app/hooks/tests/useCancelTransaction.test.js +++ b/ui/app/hooks/useCancelTransaction.test.js @@ -2,12 +2,12 @@ import assert from 'assert'; import * as reactRedux from 'react-redux'; import { renderHook } from '@testing-library/react-hooks'; import sinon from 'sinon'; -import transactions from '../../../../test/data/transaction-data.json'; -import { getConversionRate, getSelectedAccount } from '../../selectors'; -import { useCancelTransaction } from '../useCancelTransaction'; -import { showModal } from '../../store/actions'; -import { increaseLastGasPrice } from '../../helpers/utils/confirm-tx.util'; -import * as actionConstants from '../../store/actionConstants'; +import transactions from '../../../test/data/transaction-data.json'; +import { getConversionRate, getSelectedAccount } from '../selectors'; +import { showModal } from '../store/actions'; +import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util'; +import * as actionConstants from '../store/actionConstants'; +import { useCancelTransaction } from './useCancelTransaction'; describe('useCancelTransaction', function () { let useSelector; diff --git a/ui/app/hooks/tests/useCurrencyDisplay.test.js b/ui/app/hooks/useCurrencyDisplay.test.js similarity index 97% rename from ui/app/hooks/tests/useCurrencyDisplay.test.js rename to ui/app/hooks/useCurrencyDisplay.test.js index 8b019ab87..32861bf50 100644 --- a/ui/app/hooks/tests/useCurrencyDisplay.test.js +++ b/ui/app/hooks/useCurrencyDisplay.test.js @@ -2,12 +2,12 @@ import assert from 'assert'; import { renderHook } from '@testing-library/react-hooks'; import * as reactRedux from 'react-redux'; import sinon from 'sinon'; -import { useCurrencyDisplay } from '../useCurrencyDisplay'; import { getCurrentCurrency, getNativeCurrency, getConversionRate, -} from '../../selectors'; +} from '../selectors'; +import { useCurrencyDisplay } from './useCurrencyDisplay'; const tests = [ { diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/useRetryTransaction.test.js similarity index 91% rename from ui/app/hooks/tests/useRetryTransaction.test.js rename to ui/app/hooks/useRetryTransaction.test.js index aba5d0009..a2a03cfc7 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/useRetryTransaction.test.js @@ -2,11 +2,11 @@ import assert from 'assert'; import * as reactRedux from 'react-redux'; import { renderHook } from '@testing-library/react-hooks'; import sinon from 'sinon'; -import transactions from '../../../../test/data/transaction-data.json'; -import * as methodDataHook from '../useMethodData'; -import * as metricEventHook from '../useMetricEvent'; -import { showSidebar } from '../../store/actions'; -import { useRetryTransaction } from '../useRetryTransaction'; +import transactions from '../../../test/data/transaction-data.json'; +import { showSidebar } from '../store/actions'; +import * as methodDataHook from './useMethodData'; +import * as metricEventHook from './useMetricEvent'; +import { useRetryTransaction } from './useRetryTransaction'; describe('useRetryTransaction', function () { describe('when transaction meets retry enabled criteria', function () { diff --git a/ui/app/hooks/tests/useTokenData.test.js b/ui/app/hooks/useTokenData.test.js similarity index 94% rename from ui/app/hooks/tests/useTokenData.test.js rename to ui/app/hooks/useTokenData.test.js index 24fbed5af..915aa98a1 100644 --- a/ui/app/hooks/tests/useTokenData.test.js +++ b/ui/app/hooks/useTokenData.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import { ethers } from 'ethers'; import { renderHook } from '@testing-library/react-hooks'; -import { useTokenData } from '../useTokenData'; -import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; +import { useTokenData } from './useTokenData'; const tests = [ { diff --git a/ui/app/hooks/tests/useTokenDisplayValue.test.js b/ui/app/hooks/useTokenDisplayValue.test.js similarity index 93% rename from ui/app/hooks/tests/useTokenDisplayValue.test.js rename to ui/app/hooks/useTokenDisplayValue.test.js index 6fc6f6105..825b7b2a4 100644 --- a/ui/app/hooks/tests/useTokenDisplayValue.test.js +++ b/ui/app/hooks/useTokenDisplayValue.test.js @@ -1,9 +1,9 @@ import assert from 'assert'; import { renderHook } from '@testing-library/react-hooks'; import sinon from 'sinon'; -import * as tokenUtil from '../../helpers/utils/token-util'; -import * as txUtil from '../../helpers/utils/transactions.util'; -import { useTokenDisplayValue } from '../useTokenDisplayValue'; +import * as tokenUtil from '../helpers/utils/token-util'; +import * as txUtil from '../helpers/utils/transactions.util'; +import { useTokenDisplayValue } from './useTokenDisplayValue'; const tests = [ { diff --git a/ui/app/hooks/tests/useTransactionDisplayData.test.js b/ui/app/hooks/useTransactionDisplayData.test.js similarity index 93% rename from ui/app/hooks/tests/useTransactionDisplayData.test.js rename to ui/app/hooks/useTransactionDisplayData.test.js index 13079628e..531b5a649 100644 --- a/ui/app/hooks/tests/useTransactionDisplayData.test.js +++ b/ui/app/hooks/useTransactionDisplayData.test.js @@ -4,25 +4,25 @@ import * as reactRedux from 'react-redux'; import { renderHook } from '@testing-library/react-hooks'; import sinon from 'sinon'; import { MemoryRouter } from 'react-router-dom'; -import transactions from '../../../../test/data/transaction-data.json'; -import { useTransactionDisplayData } from '../useTransactionDisplayData'; -import * as useTokenFiatAmountHooks from '../useTokenFiatAmount'; +import transactions from '../../../test/data/transaction-data.json'; import { getPreferences, getShouldShowFiat, getNativeCurrency, getCurrentCurrency, -} from '../../selectors'; -import { getTokens } from '../../ducks/metamask/metamask'; -import * as i18nhooks from '../useI18nContext'; -import { getMessage } from '../../helpers/utils/i18n-helper'; -import messages from '../../../../app/_locales/en/messages.json'; -import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes'; +} from '../selectors'; +import { getTokens } from '../ducks/metamask/metamask'; +import { getMessage } from '../helpers/utils/i18n-helper'; +import messages from '../../../app/_locales/en/messages.json'; +import { ASSET_ROUTE, DEFAULT_ROUTE } from '../helpers/constants/routes'; import { TRANSACTION_TYPES, TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction'; +} from '../../../shared/constants/transaction'; +import * as i18nhooks from './useI18nContext'; +import * as useTokenFiatAmountHooks from './useTokenFiatAmount'; +import { useTransactionDisplayData } from './useTransactionDisplayData'; const expectedResults = [ { diff --git a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js b/ui/app/hooks/useUserPreferencedCurrency.test.js similarity index 95% rename from ui/app/hooks/tests/useUserPreferencedCurrency.test.js rename to ui/app/hooks/useUserPreferencedCurrency.test.js index 75ee4cf66..6adca5d4d 100644 --- a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js +++ b/ui/app/hooks/useUserPreferencedCurrency.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import { renderHook } from '@testing-library/react-hooks'; import * as reactRedux from 'react-redux'; import sinon from 'sinon'; -import { useUserPreferencedCurrency } from '../useUserPreferencedCurrency'; -import { getPreferences, getShouldShowFiat } from '../../selectors'; +import { getPreferences, getShouldShowFiat } from '../selectors'; +import { useUserPreferencedCurrency } from './useUserPreferencedCurrency'; const tests = [ { diff --git a/ui/app/pages/add-token/tests/add-token.test.js b/ui/app/pages/add-token/add-token.test.js similarity index 96% rename from ui/app/pages/add-token/tests/add-token.test.js rename to ui/app/pages/add-token/add-token.test.js index bc130409c..9e4c14aca 100644 --- a/ui/app/pages/add-token/tests/add-token.test.js +++ b/ui/app/pages/add-token/add-token.test.js @@ -3,8 +3,8 @@ import React from 'react'; import { Provider } from 'react-redux'; import sinon from 'sinon'; import configureMockStore from 'redux-mock-store'; -import { mountWithRouter } from '../../../../../test/lib/render-helpers'; -import AddToken from '..'; +import { mountWithRouter } from '../../../../test/lib/render-helpers'; +import AddToken from './add-token.container'; describe('Add Token', function () { let wrapper; diff --git a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.test.js similarity index 88% rename from ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js rename to ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.test.js index a46d89f95..087834226 100644 --- a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import { getMethodName } from '../confirm-transaction-base.component'; +import { getMethodName } from './confirm-transaction-base.component'; describe('ConfirmTransactionBase Component', function () { describe('getMethodName', function () { diff --git a/ui/app/pages/create-account/tests/create-account.test.js b/ui/app/pages/create-account/create-account.test.js similarity index 92% rename from ui/app/pages/create-account/tests/create-account.test.js rename to ui/app/pages/create-account/create-account.test.js index 0c564a64b..579be2eaa 100644 --- a/ui/app/pages/create-account/tests/create-account.test.js +++ b/ui/app/pages/create-account/create-account.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import { mountWithRouter } from '../../../../../test/lib/render-helpers'; -import CreateAccountPage from '..'; +import { mountWithRouter } from '../../../../test/lib/render-helpers'; +import CreateAccountPage from '.'; describe('Create Account Page', function () { let wrapper; diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.test.js similarity index 97% rename from ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js rename to ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.test.js index 57e8ddcee..7d1cb07c2 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import ImportWithSeedPhrase from '../import-with-seed-phrase.component'; +import ImportWithSeedPhrase from './import-with-seed-phrase.component'; function shallowRender(props = {}, context = {}) { return shallow(, { diff --git a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.test.js similarity index 80% rename from ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js rename to ui/app/pages/first-time-flow/end-of-flow/end-of-flow.test.js index 2e25aa6b9..13d0fefc6 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js +++ b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.test.js @@ -1,9 +1,9 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes'; -import EndOfFlowScreen from '..'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; +import EndOfFlowScreen from './end-of-flow.container'; describe('End of Flow Screen', function () { let wrapper; diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.test.js similarity index 94% rename from ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js rename to ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.test.js index 16270b2bd..3bb8fe0e0 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.test.js @@ -1,14 +1,14 @@ import assert from 'assert'; import React from 'react'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; import { DEFAULT_ROUTE, LOCK_ROUTE, INITIALIZE_WELCOME_ROUTE, INITIALIZE_UNLOCK_ROUTE, INITIALIZE_END_OF_FLOW_ROUTE, -} from '../../../../helpers/constants/routes'; -import FirstTimeFlowSwitch from '..'; +} from '../../../helpers/constants/routes'; +import FirstTimeFlowSwitch from './first-time-flow-switch.container'; describe('FirstTimeFlowSwitch', function () { it('redirects to /welcome route with null props', function () { diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.test.js similarity index 86% rename from ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js rename to ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.test.js index 7aee30951..6322c3aea 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import configureMockStore from 'redux-mock-store'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import MetaMetricsOptIn from '..'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import MetaMetricsOptIn from './metametrics-opt-in.container'; describe('MetaMetricsOptIn', function () { it('opt out of MetaMetrics', function () { diff --git a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase-component.test.js similarity index 98% rename from ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js rename to ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase-component.test.js index 5add90bd9..8614901ac 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase-component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import ConfirmSeedPhrase from '../confirm-seed-phrase/confirm-seed-phrase.component'; +import ConfirmSeedPhrase from './confirm-seed-phrase/confirm-seed-phrase.component'; function shallowRender(props = {}, context = {}) { return shallow(, { diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.test.js similarity index 95% rename from ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js rename to ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.test.js index 29f1d6968..9fcd50cdd 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import RevealSeedPhrase from '..'; +import RevealSeedPhrase from './reveal-seed-phrase.container'; describe('Reveal Seed Phrase', function () { let wrapper; diff --git a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js b/ui/app/pages/first-time-flow/select-action/select-action.test.js similarity index 91% rename from ui/app/pages/first-time-flow/select-action/tests/select-action.test.js rename to ui/app/pages/first-time-flow/select-action/select-action.test.js index 9f5b66fc6..3a370b088 100644 --- a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js +++ b/ui/app/pages/first-time-flow/select-action/select-action.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import SelectAction from '..'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import SelectAction from './select-action.container'; describe('Selection Action', function () { let wrapper; diff --git a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js b/ui/app/pages/first-time-flow/welcome/welcome.test.js similarity index 92% rename from ui/app/pages/first-time-flow/welcome/tests/welcome.test.js rename to ui/app/pages/first-time-flow/welcome/welcome.test.js index cc8dbab08..5914cadf7 100644 --- a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js +++ b/ui/app/pages/first-time-flow/welcome/welcome.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import configureMockStore from 'redux-mock-store'; -import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; -import Welcome from '..'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import Welcome from './welcome.container'; describe('Welcome', function () { const mockStore = { diff --git a/ui/app/pages/keychains/tests/reveal-seed.test.js b/ui/app/pages/keychains/reveal-seed.test.js similarity index 92% rename from ui/app/pages/keychains/tests/reveal-seed.test.js rename to ui/app/pages/keychains/reveal-seed.test.js index 8eeda0ae0..d8ddd9d81 100644 --- a/ui/app/pages/keychains/tests/reveal-seed.test.js +++ b/ui/app/pages/keychains/reveal-seed.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import RevealSeedPage from '../reveal-seed'; +import RevealSeedPage from './reveal-seed'; describe('Reveal Seed Page', function () { it('form submit', function () { diff --git a/ui/app/pages/lock/tests/lock.test.js b/ui/app/pages/lock/lock.test.js similarity index 89% rename from ui/app/pages/lock/tests/lock.test.js rename to ui/app/pages/lock/lock.test.js index 529fe0176..f58e0b188 100644 --- a/ui/app/pages/lock/tests/lock.test.js +++ b/ui/app/pages/lock/lock.test.js @@ -1,8 +1,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; -import { mountWithRouter } from '../../../../../test/lib/render-helpers'; -import Lock from '..'; +import { mountWithRouter } from '../../../../test/lib/render-helpers'; +import Lock from './lock.container'; describe('Lock', function () { it('replaces history with default route when isUnlocked false', function () { diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.test.js similarity index 98% rename from ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js rename to ui/app/pages/send/send-content/add-recipient/add-recipient.component.test.js index 55f193590..f3aaaba4d 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import AddRecipient from '../add-recipient.component'; -import Dialog from '../../../../../components/ui/dialog'; +import Dialog from '../../../../components/ui/dialog'; +import AddRecipient from './add-recipient.component'; const propsMethodSpies = { closeToDropdown: sinon.spy(), diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.test.js similarity index 97% rename from ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js rename to ui/app/pages/send/send-content/add-recipient/add-recipient.container.test.js index a7b4abeb8..0bae6c85b 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.test.js @@ -9,7 +9,7 @@ const actionSpies = { updateSendTo: sinon.spy(), }; -proxyquire('../add-recipient.container.js', { +proxyquire('./add-recipient.container.js', { 'react-redux': { connect: (ms, md) => { mapStateToProps = ms; diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.utils.test.js similarity index 97% rename from ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js rename to ui/app/pages/send/send-content/add-recipient/add-recipient.utils.test.js index 3ffdc96af..9230f6752 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.utils.test.js @@ -8,7 +8,7 @@ import { KNOWN_RECIPIENT_ADDRESS_ERROR, CONFUSING_ENS_ERROR, CONTRACT_ADDRESS_ERROR, -} from '../../../send.constants'; +} from '../../send.constants'; const stubs = { isValidAddress: sinon @@ -16,7 +16,7 @@ const stubs = { .callsFake((to) => Boolean(to.match(/^[0xabcdef123456798]+$/u))), }; -const toRowUtils = proxyquire('../add-recipient.js', { +const toRowUtils = proxyquire('./add-recipient.js', { '../../../../helpers/utils/util': { isValidAddress: stubs.isValidAddress, }, diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.test.js similarity index 97% rename from ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js rename to ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.test.js index 42d7646a9..618308923 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import AmountMaxButton from '../amount-max-button.component'; +import AmountMaxButton from './amount-max-button.component'; describe('AmountMaxButton Component', function () { let wrapper; diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.test.js similarity index 98% rename from ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js rename to ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.test.js index c09e32985..3115dc004 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.test.js @@ -13,7 +13,7 @@ const duckActionSpies = { updateSendErrors: sinon.spy(), }; -proxyquire('../amount-max-button.container.js', { +proxyquire('./amount-max-button.container.js', { 'react-redux': { connect: (ms, md) => { mapStateToProps = ms; diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.test.js similarity index 92% rename from ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js rename to ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.test.js index e66395188..75fb24844 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import { calcMaxAmount } from '../amount-max-button.utils'; +import { calcMaxAmount } from './amount-max-button.utils'; describe('amount-max-button utils', function () { describe('calcMaxAmount()', function () { diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.test.js similarity index 94% rename from ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js rename to ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.test.js index fd7889004..f960168e4 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.test.js @@ -2,11 +2,11 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import SendAmountRow from '../send-amount-row.component'; +import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'; +import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input'; +import SendAmountRow from './send-amount-row.component'; -import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'; -import AmountMaxButton from '../amount-max-button/amount-max-button.container'; -import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input'; +import AmountMaxButton from './amount-max-button/amount-max-button.container'; describe('SendAmountRow Component', function () { describe('validateAmount', function () { diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.test.js similarity index 98% rename from ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js rename to ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.test.js index 5e29554ba..39cde16bc 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.test.js @@ -12,7 +12,7 @@ const duckActionSpies = { updateSendErrors: sinon.spy(), }; -proxyquire('../send-amount-row.container.js', { +proxyquire('./send-amount-row.container.js', { 'react-redux': { connect: (_, md) => { mapDispatchToProps = md; diff --git a/ui/app/pages/send/send-content/tests/send-content-component.test.js b/ui/app/pages/send/send-content/send-content.component.test.js similarity index 90% rename from ui/app/pages/send/send-content/tests/send-content-component.test.js rename to ui/app/pages/send/send-content/send-content.component.test.js index b652d369f..ddbb0c12b 100644 --- a/ui/app/pages/send/send-content/tests/send-content-component.test.js +++ b/ui/app/pages/send/send-content/send-content.component.test.js @@ -1,14 +1,14 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import SendContent from '../send-content.component'; +import PageContainerContent from '../../../components/ui/page-container/page-container-content.component'; +import Dialog from '../../../components/ui/dialog'; +import SendContent from './send-content.component'; -import PageContainerContent from '../../../../components/ui/page-container/page-container-content.component'; -import SendAmountRow from '../send-amount-row/send-amount-row.container'; -import SendGasRow from '../send-gas-row/send-gas-row.container'; -import SendHexDataRow from '../send-hex-data-row/send-hex-data-row.container'; -import SendAssetRow from '../send-asset-row/send-asset-row.container'; -import Dialog from '../../../../components/ui/dialog'; +import SendAmountRow from './send-amount-row/send-amount-row.container'; +import SendGasRow from './send-gas-row/send-gas-row.container'; +import SendHexDataRow from './send-hex-data-row/send-hex-data-row.container'; +import SendAssetRow from './send-asset-row/send-asset-row.container'; describe('SendContent Component', function () { let wrapper; diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.test.js similarity index 91% rename from ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js rename to ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.test.js index 15fb6b5a2..88f5761d7 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import GasFeeDisplay from '../gas-fee-display.component'; -import UserPreferencedCurrencyDisplay from '../../../../../../components/app/user-preferenced-currency-display'; +import UserPreferencedCurrencyDisplay from '../../../../../components/app/user-preferenced-currency-display'; +import GasFeeDisplay from './gas-fee-display.component'; const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.test.js similarity index 92% rename from ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js rename to ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.test.js index 12bb6d7bf..fc23078d1 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.test.js @@ -2,11 +2,11 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import SendGasRow from '../send-gas-row.component'; +import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'; +import GasPriceButtonGroup from '../../../../components/app/gas-customization/gas-price-button-group'; +import SendGasRow from './send-gas-row.component'; -import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'; -import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component'; -import GasPriceButtonGroup from '../../../../../components/app/gas-customization/gas-price-button-group'; +import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'; const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.test.js similarity index 99% rename from ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js rename to ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.test.js index 157082f76..2378d102f 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.test.js @@ -22,7 +22,7 @@ const gasDuckSpies = { setCustomGasLimit: sinon.spy(), }; -proxyquire('../send-gas-row.container.js', { +proxyquire('./send-gas-row.container.js', { 'react-redux': { connect: (_, md, mp) => { mapDispatchToProps = md; diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.test.js similarity index 93% rename from ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js rename to ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.test.js index c8c0f5c61..c02b9a057 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import SendRowErrorMessage from '../send-row-error-message.component'; +import SendRowErrorMessage from './send-row-error-message.component'; describe('SendRowErrorMessage Component', function () { let wrapper; diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.test.js similarity index 92% rename from ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js rename to ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.test.js index f231b7734..0162a7706 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.test.js @@ -3,7 +3,7 @@ import proxyquire from 'proxyquire'; let mapStateToProps; -proxyquire('../send-row-error-message.container.js', { +proxyquire('./send-row-error-message.container.js', { 'react-redux': { connect: (ms) => { mapStateToProps = ms; diff --git a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.test.js similarity index 95% rename from ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js rename to ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.test.js index 722168698..dd6555e54 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.test.js @@ -1,9 +1,9 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; -import SendRowWrapper from '../send-row-wrapper.component'; +import SendRowWrapper from './send-row-wrapper.component'; -import SendRowErrorMessage from '../send-row-error-message/send-row-error-message.container'; +import SendRowErrorMessage from './send-row-error-message/send-row-error-message.container'; describe('SendContent Component', function () { let wrapper; diff --git a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js b/ui/app/pages/send/send-footer/send-footer.component.test.js similarity index 97% rename from ui/app/pages/send/send-footer/tests/send-footer-component.test.js rename to ui/app/pages/send/send-footer/send-footer.component.test.js index a1f5a6ccd..02a6edc60 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js +++ b/ui/app/pages/send/send-footer/send-footer.component.test.js @@ -2,9 +2,9 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import { CONFIRM_TRANSACTION_ROUTE } from '../../../../helpers/constants/routes'; -import SendFooter from '../send-footer.component'; -import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'; +import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes'; +import PageContainerFooter from '../../../components/ui/page-container/page-container-footer'; +import SendFooter from './send-footer.component'; describe('SendFooter Component', function () { let wrapper; diff --git a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js b/ui/app/pages/send/send-footer/send-footer.container.test.js similarity index 99% rename from ui/app/pages/send/send-footer/tests/send-footer-container.test.js rename to ui/app/pages/send/send-footer/send-footer.container.test.js index 88523ee27..5e1bdcd58 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js +++ b/ui/app/pages/send/send-footer/send-footer.container.test.js @@ -19,7 +19,7 @@ const utilsStubs = { constructUpdatedTx: sinon.stub().returns('mockConstructedUpdatedTxParams'), }; -proxyquire('../send-footer.container.js', { +proxyquire('./send-footer.container.js', { 'react-redux': { connect: (_, md) => { mapDispatchToProps = md; diff --git a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js b/ui/app/pages/send/send-footer/send-footer.utils.test.js similarity index 97% rename from ui/app/pages/send/send-footer/tests/send-footer-utils.test.js rename to ui/app/pages/send/send-footer/send-footer.utils.test.js index 9d7507f57..24f2606a1 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js +++ b/ui/app/pages/send/send-footer/send-footer.utils.test.js @@ -1,7 +1,7 @@ import assert from 'assert'; import proxyquire from 'proxyquire'; import sinon from 'sinon'; -import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../../send.constants'; +import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../send.constants'; const stubs = { rawEncode: sinon.stub().callsFake((arr1, arr2) => { @@ -9,7 +9,7 @@ const stubs = { }), }; -const sendUtils = proxyquire('../send-footer.utils.js', { +const sendUtils = proxyquire('./send-footer.utils.js', { 'ethereumjs-abi': { rawEncode: stubs.rawEncode, }, diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/send-header.component.test.js similarity index 93% rename from ui/app/pages/send/send-header/tests/send-header-component.test.js rename to ui/app/pages/send/send-header/send-header.component.test.js index 14cde996a..ff711f0bb 100644 --- a/ui/app/pages/send/send-header/tests/send-header-component.test.js +++ b/ui/app/pages/send/send-header/send-header.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import SendHeader from '../send-header.component'; -import PageContainerHeader from '../../../../components/ui/page-container/page-container-header'; +import PageContainerHeader from '../../../components/ui/page-container/page-container-header'; +import SendHeader from './send-header.component'; describe('SendHeader Component', function () { let wrapper; diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/send.component.test.js similarity index 97% rename from ui/app/pages/send/tests/send-component.test.js rename to ui/app/pages/send/send.component.test.js index 3f502d6ce..29782c2c7 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/send.component.test.js @@ -3,16 +3,16 @@ import React from 'react'; import proxyquire from 'proxyquire'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import timeout from '../../../../lib/test-timeout'; +import timeout from '../../../lib/test-timeout'; -import AddRecipient from '../send-content/add-recipient/add-recipient.container'; -import SendHeader from '../send-header/send-header.container'; -import SendContent from '../send-content/send-content.container'; -import SendFooter from '../send-footer/send-footer.container'; import { RINKEBY_CHAIN_ID, ROPSTEN_CHAIN_ID, -} from '../../../../../shared/constants/network'; +} from '../../../../shared/constants/network'; +import AddRecipient from './send-content/add-recipient/add-recipient.container'; +import SendHeader from './send-header/send-header.container'; +import SendContent from './send-content/send-content.container'; +import SendFooter from './send-footer/send-footer.container'; describe('Send Component', function () { let wrapper; @@ -40,7 +40,7 @@ describe('Send Component', function () { .callsFake((obj) => obj.balance !== obj.prevBalance), }; - const SendTransactionScreen = proxyquire('../send.component.js', { + const SendTransactionScreen = proxyquire('./send.component.js', { './send.utils': utilsMethodStubs, }).default; diff --git a/ui/app/pages/send/tests/send-container.test.js b/ui/app/pages/send/send.container.test.js similarity index 98% rename from ui/app/pages/send/tests/send-container.test.js rename to ui/app/pages/send/send.container.test.js index 377118920..6940012a1 100644 --- a/ui/app/pages/send/tests/send-container.test.js +++ b/ui/app/pages/send/send.container.test.js @@ -14,7 +14,7 @@ const duckActionSpies = { resetSendState: sinon.spy(), }; -proxyquire('../send.container.js', { +proxyquire('./send.container.js', { 'react-redux': { connect: (_, md) => { mapDispatchToProps = md; diff --git a/ui/app/pages/send/tests/send-utils.test.js b/ui/app/pages/send/send.utils.test.js similarity index 99% rename from ui/app/pages/send/tests/send-utils.test.js rename to ui/app/pages/send/send.utils.test.js index 6f51b3fd1..a674cbcf5 100644 --- a/ui/app/pages/send/tests/send-utils.test.js +++ b/ui/app/pages/send/send.utils.test.js @@ -6,7 +6,7 @@ import { SIMPLE_GAS_COST, INSUFFICIENT_FUNDS_ERROR, INSUFFICIENT_TOKENS_ERROR, -} from '../send.constants'; +} from './send.constants'; const stubs = { addCurrencies: sinon.stub().callsFake((a, b) => { @@ -34,7 +34,7 @@ const stubs = { .callsFake((obj1, obj2) => obj1.value < obj2.value), }; -const sendUtils = proxyquire('../send.utils.js', { +const sendUtils = proxyquire('./send.utils.js', { '../../helpers/utils/conversion-util': { addCurrencies: stubs.addCurrencies, conversionUtil: stubs.conversionUtil, diff --git a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js b/ui/app/pages/settings/advanced-tab/advanced-tab.component.test.js similarity index 93% rename from ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js rename to ui/app/pages/settings/advanced-tab/advanced-tab.component.test.js index 76b9360f3..9db6793a4 100644 --- a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.component.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import AdvancedTab from '../advanced-tab.component'; -import TextField from '../../../../components/ui/text-field'; +import TextField from '../../../components/ui/text-field'; +import AdvancedTab from './advanced-tab.component'; describe('AdvancedTab Component', function () { it('should render correctly when threeBoxFeatureFlag', function () { diff --git a/ui/app/pages/settings/security-tab/tests/security-tab.test.js b/ui/app/pages/settings/security-tab/security-tab.container.test.js similarity index 97% rename from ui/app/pages/settings/security-tab/tests/security-tab.test.js rename to ui/app/pages/settings/security-tab/security-tab.container.test.js index 78b785c4f..2515a7660 100644 --- a/ui/app/pages/settings/security-tab/tests/security-tab.test.js +++ b/ui/app/pages/settings/security-tab/security-tab.container.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import SecurityTab from '..'; +import SecurityTab from './security-tab.container'; describe('Security Tab', function () { let wrapper; diff --git a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js b/ui/app/pages/settings/settings-tab/settings-tab.container.test.js similarity index 97% rename from ui/app/pages/settings/settings-tab/tests/settings-tab.test.js rename to ui/app/pages/settings/settings-tab/settings-tab.container.test.js index 969044da7..eb8a4eb68 100644 --- a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js +++ b/ui/app/pages/settings/settings-tab/settings-tab.container.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import SettingsTab from '..'; +import SettingsTab from './settings-tab.container'; describe('Settings Tab', function () { let wrapper; diff --git a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js b/ui/app/pages/swaps/view-quote/view-quote-price-difference.test.js similarity index 97% rename from ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js rename to ui/app/pages/swaps/view-quote/view-quote-price-difference.test.js index 437c67eea..019042bff 100644 --- a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js +++ b/ui/app/pages/swaps/view-quote/view-quote-price-difference.test.js @@ -3,8 +3,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; -import { NETWORK_TYPE_RPC } from '../../../../../../shared/constants/network'; -import ViewQuotePriceDifference from '../view-quote-price-difference'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; +import ViewQuotePriceDifference from './view-quote-price-difference'; describe('View Price Quote Difference', function () { const t = (key) => `translate ${key}`; diff --git a/ui/app/pages/unlock-page/tests/unlock-page.test.js b/ui/app/pages/unlock-page/unlock-page.container.test.js similarity index 97% rename from ui/app/pages/unlock-page/tests/unlock-page.test.js rename to ui/app/pages/unlock-page/unlock-page.container.test.js index 37bff5c34..c4145789d 100644 --- a/ui/app/pages/unlock-page/tests/unlock-page.test.js +++ b/ui/app/pages/unlock-page/unlock-page.container.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount } from 'enzyme'; -import UnlockPage from '..'; +import UnlockPage from './unlock-page.container'; describe('Unlock Page', function () { let wrapper; diff --git a/ui/app/selectors/tests/confirm-transaction.test.js b/ui/app/selectors/confirm-transaction.test.js similarity index 94% rename from ui/app/selectors/tests/confirm-transaction.test.js rename to ui/app/selectors/confirm-transaction.test.js index 647318a9d..d0c982ab5 100644 --- a/ui/app/selectors/tests/confirm-transaction.test.js +++ b/ui/app/selectors/confirm-transaction.test.js @@ -3,14 +3,14 @@ import { KOVAN_CHAIN_ID, KOVAN_NETWORK_ID, MAINNET_CHAIN_ID, -} from '../../../../shared/constants/network'; -import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; +} from '../../../shared/constants/network'; +import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; import { unconfirmedTransactionsCountSelector, sendTokenTokenAmountAndToAddressSelector, contractExchangeRateSelector, conversionRateSelector, -} from '../confirm-transaction'; +} from './confirm-transaction'; const getEthersArrayLikeFromObj = (obj) => { const arr = []; diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/custom-gas.test.js similarity index 99% rename from ui/app/selectors/tests/custom-gas.test.js rename to ui/app/selectors/custom-gas.test.js index ddfd6b136..b443897a7 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/custom-gas.test.js @@ -8,7 +8,7 @@ const { getRenderableEstimateDataForSmallButtonsFromGWEI, isCustomPriceSafe, isCustomPriceExcessive, -} = proxyquire('../custom-gas', {}); +} = proxyquire('./custom-gas', {}); describe('custom-gas selectors', function () { describe('getCustomGasPrice()', function () { diff --git a/ui/app/selectors/tests/permissions.test.js b/ui/app/selectors/permissions.test.js similarity index 99% rename from ui/app/selectors/tests/permissions.test.js rename to ui/app/selectors/permissions.test.js index d2f82893d..91b16ecd4 100644 --- a/ui/app/selectors/tests/permissions.test.js +++ b/ui/app/selectors/permissions.test.js @@ -1,10 +1,10 @@ import assert from 'assert'; -import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network'; +import { KOVAN_CHAIN_ID } from '../../../shared/constants/network'; import { getConnectedDomainsForSelectedAddress, getOrderedConnectedAccountsForActiveTab, getPermissionsForActiveTab, -} from '../permissions'; +} from './permissions'; describe('selectors', function () { describe('getConnectedDomainsForSelectedAddress', function () { diff --git a/ui/app/selectors/tests/selectors.test.js b/ui/app/selectors/selectors.test.js similarity index 96% rename from ui/app/selectors/tests/selectors.test.js rename to ui/app/selectors/selectors.test.js index 46058fe12..0de6dec40 100644 --- a/ui/app/selectors/tests/selectors.test.js +++ b/ui/app/selectors/selectors.test.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import * as selectors from '../selectors'; -import mockState from '../../../../test/data/mock-state.json'; +import mockState from '../../../test/data/mock-state.json'; +import * as selectors from './selectors'; describe('Selectors', function () { describe('#getSelectedAddress', function () { diff --git a/ui/app/selectors/tests/send-selectors-test-data.js b/ui/app/selectors/send-selectors-test-data.js similarity index 98% rename from ui/app/selectors/tests/send-selectors-test-data.js rename to ui/app/selectors/send-selectors-test-data.js index 19a91e9d3..93f7a217e 100644 --- a/ui/app/selectors/tests/send-selectors-test-data.js +++ b/ui/app/selectors/send-selectors-test-data.js @@ -1,4 +1,4 @@ -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; const state = { metamask: { diff --git a/ui/app/selectors/tests/send.test.js b/ui/app/selectors/send.test.js similarity index 99% rename from ui/app/selectors/tests/send.test.js rename to ui/app/selectors/send.test.js index 1cc2a60e0..f44a54b67 100644 --- a/ui/app/selectors/tests/send.test.js +++ b/ui/app/selectors/send.test.js @@ -1,10 +1,6 @@ import assert from 'assert'; import sinon from 'sinon'; -import { - accountsWithSendEtherInfoSelector, - getCurrentAccountWithSendEtherInfo, -} from '..'; -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; import { getBlockGasLimit, getConversionRate, @@ -33,8 +29,12 @@ import { getGasButtonGroupShown, getTitleKey, isSendFormInError, -} from '../send'; +} from './send'; import mockState from './send-selectors-test-data'; +import { + accountsWithSendEtherInfoSelector, + getCurrentAccountWithSendEtherInfo, +} from '.'; describe('send selectors', function () { const tempGlobalEth = { ...global.eth }; diff --git a/ui/app/selectors/tests/transactions.test.js b/ui/app/selectors/transactions.test.js similarity index 98% rename from ui/app/selectors/tests/transactions.test.js rename to ui/app/selectors/transactions.test.js index 6d2d59015..a02a23dca 100644 --- a/ui/app/selectors/tests/transactions.test.js +++ b/ui/app/selectors/transactions.test.js @@ -2,8 +2,8 @@ import { strict as assert } from 'assert'; import { KOVAN_CHAIN_ID, MAINNET_CHAIN_ID, -} from '../../../../shared/constants/network'; -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; +} from '../../../shared/constants/network'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; import { unapprovedMessagesSelector, transactionsSelector, @@ -11,7 +11,7 @@ import { nonceSortedPendingTransactionsSelector, nonceSortedCompletedTransactionsSelector, submittedPendingTransactionsSelector, -} from '../transactions'; +} from './transactions'; describe('Transaction Selectors', function () { describe('unapprovedMessagesSelector', function () { diff --git a/ui/app/store/actionConstants.test.js b/ui/app/store/actionConstants.test.js new file mode 100644 index 000000000..2875b2525 --- /dev/null +++ b/ui/app/store/actionConstants.test.js @@ -0,0 +1,82 @@ +import assert from 'assert'; +import freeze from 'deep-freeze-strict'; +import reducers from '../ducks'; +import { NETWORK_TYPE_RPC } from '../../../shared/constants/network'; +import * as actionConstants from './actionConstants'; + +describe('Redux actionConstants', function () { + describe('SET_RPC_TARGET', function () { + const initialState = { + metamask: { + rpcUrl: 'foo', + frequentRpcList: [], + }, + appState: { + currentView: { + name: 'accounts', + }, + }, + }; + freeze(initialState); + it('sets the state.metamask.rpcUrl property of the state to the action.value', function () { + const action = { + type: actionConstants.SET_RPC_TARGET, + value: 'foo', + }; + + const result = reducers(initialState, action); + assert.equal(result.metamask.provider.type, NETWORK_TYPE_RPC); + assert.equal(result.metamask.provider.rpcUrl, 'foo'); + }); + }); + + describe('SET_ACCOUNT_LABEL', function () { + it('updates the state.metamask.identities[:i].name property of the state to the action.value.label', function () { + const initialState = { + metamask: { + identities: { + foo: { + name: 'bar', + }, + }, + }, + }; + freeze(initialState); + + const action = { + type: actionConstants.SET_ACCOUNT_LABEL, + value: { + account: 'foo', + label: 'baz', + }, + }; + freeze(action); + + const resultingState = reducers(initialState, action); + assert.equal( + resultingState.metamask.identities.foo.name, + action.value.label, + ); + }); + }); + + describe('SHOW_ACCOUNT_DETAIL', function () { + it('updates metamask state', function () { + const initialState = { + metamask: { + selectedAddress: 'foo', + }, + }; + freeze(initialState); + + const action = { + type: actionConstants.SHOW_ACCOUNT_DETAIL, + value: 'bar', + }; + freeze(action); + + const resultingState = reducers(initialState, action); + assert.equal(resultingState.metamask.selectedAddress, action.value); + }); + }); +}); diff --git a/test/unit/ui/app/actions.test.js b/ui/app/store/actions.test.js similarity index 96% rename from test/unit/ui/app/actions.test.js rename to ui/app/store/actions.test.js index 705783dbd..52d7c6417 100644 --- a/test/unit/ui/app/actions.test.js +++ b/ui/app/store/actions.test.js @@ -4,11 +4,11 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import EthQuery from 'eth-query'; import Eth from 'ethjs'; -import { createTestProviderTools } from '../../../stub/provider'; -import enLocale from '../../../../app/_locales/en/messages.json'; -import * as actions from '../../../../ui/app/store/actions'; -import MetaMaskController from '../../../../app/scripts/metamask-controller'; -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; +import { createTestProviderTools } from '../../../test/stub/provider'; +import enLocale from '../../../app/_locales/en/messages.json'; +import MetaMaskController from '../../../app/scripts/metamask-controller'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import * as actions from './actions'; const { provider } = createTestProviderTools({ scaffold: {} }); const middleware = [thunk]; @@ -1793,4 +1793,52 @@ describe('Actions', function () { assert(background.unMarkPasswordForgotten.calledOnce); }); }); + + describe('#displayWarning', function () { + it('sets appState.warning to provided value', async function () { + const store = mockStore(); + + const warningText = 'This is a sample warning message'; + + await store.dispatch(actions.displayWarning(warningText)); + + const resultantActions = store.getActions(); + + assert.deepStrictEqual(resultantActions[0], { + type: 'DISPLAY_WARNING', + value: warningText, + }); + }); + }); + + describe('#cancelTx', function () { + it('creates COMPLETED_TX with the cancelled transaction ID', async function () { + const store = mockStore(); + + background.getApi.returns({ + cancelTransaction: sinon.stub().callsFake((_, cb) => { + cb(); + }), + getState: sinon.stub().callsFake((cb) => + cb(null, { + currentLocale: 'test', + selectedAddress: '0xFirstAddress', + }), + ), + }); + + actions._setBackgroundConnection(background.getApi()); + + const txId = 1457634084250832; + + await store.dispatch(actions.cancelTx({ id: txId })); + const resultantActions = store.getActions(); + const expectedAction = resultantActions.find( + (action) => action.type === 'COMPLETED_TX', + ); + assert.ok(expectedAction, 'expected action not found'); + + assert.strictEqual(expectedAction.value.id, txId); + }); + }); }); diff --git a/test/unit/lib/account-link.test.js b/ui/lib/account-link.test.js similarity index 93% rename from test/unit/lib/account-link.test.js rename to ui/lib/account-link.test.js index 784133f75..8a2053b92 100644 --- a/test/unit/lib/account-link.test.js +++ b/ui/lib/account-link.test.js @@ -2,8 +2,8 @@ import assert from 'assert'; import { MAINNET_CHAIN_ID, ROPSTEN_CHAIN_ID, -} from '../../../shared/constants/network'; -import getAccountLink from '../../../ui/lib/account-link'; +} from '../../shared/constants/network'; +import getAccountLink from './account-link'; describe('Account link', function () { describe('getAccountLink', function () { diff --git a/test/unit/app/controllers/transactions/tx-helper.test.js b/ui/lib/tx-helper.test.js similarity index 85% rename from test/unit/app/controllers/transactions/tx-helper.test.js rename to ui/lib/tx-helper.test.js index 246f9a46c..128bc888a 100644 --- a/test/unit/app/controllers/transactions/tx-helper.test.js +++ b/ui/lib/tx-helper.test.js @@ -2,8 +2,8 @@ import { strict as assert } from 'assert'; import { MAINNET_CHAIN_ID, MAINNET_NETWORK_ID, -} from '../../../../../shared/constants/network'; -import txHelper from '../../../../../ui/lib/tx-helper'; +} from '../../shared/constants/network'; +import txHelper from './tx-helper'; describe('txHelper', function () { it('always shows the oldest tx first', function () { From 88ad38372227250488527c41122d5e5cc1f14d25 Mon Sep 17 00:00:00 2001 From: ryanml Date: Tue, 16 Mar 2021 21:21:46 -0700 Subject: [PATCH 18/82] Fixing migration script generation paths (#10664) --- development/generate-migration.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/generate-migration.sh b/development/generate-migration.sh index 5fb85feb5..0e08b9421 100755 --- a/development/generate-migration.sh +++ b/development/generate-migration.sh @@ -8,8 +8,8 @@ g-migration() { touch app/scripts/migrations/"$vnum".js cp app/scripts/migrations/template.js app/scripts/migrations/"$vnum".js - touch test/unit/migrations/"$vnum".js - cp test/unit/migrations/template-test.js test/unit/migrations/"$vnum"-test.js + touch app/scripts/migrations/"$vnum".test.js + cp app/scripts/migrations/template.test.js app/scripts/migrations/"$vnum".test.js } g-migration "$1" From 1c573ef852e20789d3e2ff1233348a18c854fa4c Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 17 Mar 2021 10:50:59 -0230 Subject: [PATCH 19/82] Improve specificity of `test:unit:lax` npm script (#10661) The unit test npm script `test:unit:lax` is now more specific about which tests files to exclude. An `--ignore` CLI option is used to specify the files to ignore, rather than using the braces glob syntax to ignore them from the target glob itself. This makes the option easier to update going forward as we move more tests into the "strict" group, because the options are exactly the same between the two scripts. It also ensures we don't accidentally exclude other subdirectories that happen to also be named `permissions`. In trying to implement this, I stumbled at first because mocha expects the ignore pattern to be a relative path if the target is a relative path (i.e. they need to both start with `./` or neither). The script `test:unit:strict` has been updated to use a relative target pattern for consistency. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3fa468bce..0a84353a0 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive './{ui,app,shared}/**/*.test.js'", "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js", - "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive './{ui,app,shared}/{,**/!(permissions)}/*.test.js'", - "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive 'app/scripts/controllers/permissions/*.test.js'", + "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --ignore './app/scripts/controllers/permissions/*.test.js' --recursive './{ui,app,shared}/**/*.test.js'", + "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive './app/scripts/controllers/permissions/*.test.js'", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", "test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js", From 480512d14fe4891a508cddbcb7e027d9181ae728 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 18 Mar 2021 07:50:06 -0230 Subject: [PATCH 20/82] Swaps support for local testnet (#10658) * Swaps support for local testnet * Create util method for comparison of token addresses/symbols to default swaps token * Get chainId from txMeta in _trackSwapsMetrics of transaction controller * Add comment to document purpose of getTransactionGroupRecipientAddressFilter * Use isSwapsDefaultTokenSymbol in place of repeated defaultTokenSymbol comparisons in build-quote.js --- app/scripts/controllers/swaps.js | 71 ++++++---- app/scripts/controllers/swaps.test.js | 13 +- app/scripts/controllers/transactions/index.js | 1 + app/scripts/metamask-controller.js | 3 + shared/constants/swaps.js | 52 +++++-- shared/modules/swaps.utils.js | 33 +++++ .../transaction-list.component.js | 37 ++++- .../app/wallet-overview/eth-overview.js | 14 +- .../app/wallet-overview/token-overview.js | 11 +- ui/app/ducks/swaps/swaps.js | 28 ++-- ui/app/hooks/useCurrentAsset.js | 17 ++- ui/app/hooks/useSwappedTokenValue.js | 26 +++- ui/app/hooks/useTokensToSearch.js | 31 ++-- .../hooks/useTransactionDisplayData.test.js | 4 + .../swaps/awaiting-swap/awaiting-swap.js | 29 ++-- ui/app/pages/swaps/build-quote/build-quote.js | 53 ++++--- ui/app/pages/swaps/index.js | 18 +-- ui/app/pages/swaps/intro-popup/intro-popup.js | 12 +- ui/app/pages/swaps/swaps.util.js | 132 ++++++++++-------- ui/app/pages/swaps/swaps.util.test.js | 40 +++--- ui/app/pages/swaps/view-quote/view-quote.js | 42 +++--- ui/app/selectors/selectors.js | 26 +++- 22 files changed, 466 insertions(+), 227 deletions(-) create mode 100644 shared/modules/swaps.utils.js diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 0011984b3..fcb2fce00 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -8,12 +8,13 @@ import { calcTokenAmount } from '../../../ui/app/helpers/utils/token-util'; import { calcGasTotal } from '../../../ui/app/pages/send/send.utils'; import { conversionUtil } from '../../../ui/app/helpers/utils/conversion-util'; import { - ETH_SWAPS_TOKEN_OBJECT, DEFAULT_ERC20_APPROVE_GAS, QUOTES_EXPIRED_ERROR, QUOTES_NOT_AVAILABLE_ERROR, SWAPS_FETCH_ORDER_CONFLICT, } from '../../../shared/constants/swaps'; +import { isSwapsDefaultTokenAddress } from '../../../shared/modules/swaps.utils'; + import { fetchTradesInfo as defaultFetchTradesInfo, fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness, @@ -85,6 +86,7 @@ export default class SwapsController { fetchTradesInfo = defaultFetchTradesInfo, fetchSwapsFeatureLiveness = defaultFetchSwapsFeatureLiveness, fetchSwapsQuoteRefreshTime = defaultFetchSwapsQuoteRefreshTime, + getCurrentChainId, }) { this.store = new ObservableStore({ swapsState: { ...initialState.swapsState }, @@ -93,6 +95,7 @@ export default class SwapsController { this._fetchTradesInfo = fetchTradesInfo; this._fetchSwapsFeatureLiveness = fetchSwapsFeatureLiveness; this._fetchSwapsQuoteRefreshTime = fetchSwapsQuoteRefreshTime; + this._getCurrentChainId = getCurrentChainId; this.getBufferedGasLimit = getBufferedGasLimit; this.tokenRatesStore = tokenRatesStore; @@ -116,10 +119,11 @@ export default class SwapsController { // Sets the refresh rate for quote updates from the MetaSwap API async _setSwapsQuoteRefreshTime() { + const chainId = this._getCurrentChainId(); // Default to fallback time unless API returns valid response let swapsQuoteRefreshTime = FALLBACK_QUOTE_REFRESH_TIME; try { - swapsQuoteRefreshTime = await this._fetchSwapsQuoteRefreshTime(); + swapsQuoteRefreshTime = await this._fetchSwapsQuoteRefreshTime(chainId); } catch (e) { console.error('Request for swaps quote refresh time failed: ', e); } @@ -158,6 +162,8 @@ export default class SwapsController { fetchParamsMetaData = {}, isPolledRequest, ) { + const { chainId } = fetchParamsMetaData; + if (!fetchParams) { return null; } @@ -177,7 +183,7 @@ export default class SwapsController { this.indexOfNewestCallInFlight = indexOfCurrentCall; let [newQuotes] = await Promise.all([ - this._fetchTradesInfo(fetchParams), + this._fetchTradesInfo(fetchParams, fetchParamsMetaData), this._setSwapsQuoteRefreshTime(), ]); @@ -191,7 +197,7 @@ export default class SwapsController { let approvalRequired = false; if ( - fetchParams.sourceToken !== ETH_SWAPS_TOKEN_OBJECT.address && + !isSwapsDefaultTokenAddress(fetchParams.sourceToken, chainId) && Object.values(newQuotes).length ) { const allowance = await this._getERC20Allowance( @@ -490,6 +496,7 @@ export default class SwapsController { const { swapsState: { customGasPrice }, } = this.store.getState(); + const chainId = this._getCurrentChainId(); const numQuotes = Object.keys(quotes).length; if (!numQuotes) { @@ -533,8 +540,8 @@ export default class SwapsController { // trade.value is a sum of different values depending on the transaction. // It always includes any external fees charged by the quote source. In - // addition, if the source asset is ETH, trade.value includes the amount - // of swapped ETH. + // addition, if the source asset is the selected chain's default token, trade.value + // includes the amount of that token. const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16).plus( trade.value, 16, @@ -549,21 +556,21 @@ export default class SwapsController { }); // The total fee is aggregator/exchange fees plus gas fees. - // If the swap is from ETH, subtract the sourceAmount from the total cost. - // Otherwise, the total fee is simply trade.value plus gas fees. - const ethFee = - sourceToken === ETH_SWAPS_TOKEN_OBJECT.address - ? conversionUtil( - totalWeiCost.minus(sourceAmount, 10), // sourceAmount is in wei - { - fromCurrency: 'ETH', - fromDenomination: 'WEI', - toDenomination: 'ETH', - fromNumericBase: 'BN', - numberOfDecimals: 6, - }, - ) - : totalEthCost; + // If the swap is from the selected chain's default token, subtract + // the sourceAmount from the total cost. Otherwise, the total fee + // is simply trade.value plus gas fees. + const ethFee = isSwapsDefaultTokenAddress(sourceToken, chainId) + ? conversionUtil( + totalWeiCost.minus(sourceAmount, 10), // sourceAmount is in wei + { + fromCurrency: 'ETH', + fromDenomination: 'WEI', + toDenomination: 'ETH', + fromNumericBase: 'BN', + numberOfDecimals: 6, + }, + ) + : totalEthCost; const decimalAdjustedDestinationAmount = calcTokenAmount( destinationAmount, @@ -588,10 +595,12 @@ export default class SwapsController { 10, ); - const conversionRateForCalculations = - destinationToken === ETH_SWAPS_TOKEN_OBJECT.address - ? 1 - : tokenConversionRate; + const conversionRateForCalculations = isSwapsDefaultTokenAddress( + destinationToken, + chainId, + ) + ? 1 + : tokenConversionRate; const overallValueOfQuoteForSorting = conversionRateForCalculations === undefined @@ -618,8 +627,10 @@ export default class SwapsController { }); const isBest = - newQuotes[topAggId].destinationToken === ETH_SWAPS_TOKEN_OBJECT.address || - Boolean(tokenConversionRates[newQuotes[topAggId]?.destinationToken]); + isSwapsDefaultTokenAddress( + newQuotes[topAggId].destinationToken, + chainId, + ) || Boolean(tokenConversionRates[newQuotes[topAggId]?.destinationToken]); let savings = null; @@ -726,13 +737,17 @@ export default class SwapsController { async _fetchAndSetSwapsLiveness() { const { swapsState } = this.store.getState(); const { swapsFeatureIsLive: oldSwapsFeatureIsLive } = swapsState; + const chainId = this._getCurrentChainId(); + let swapsFeatureIsLive = false; let successfullyFetched = false; let numAttempts = 0; const fetchAndIncrementNumAttempts = async () => { try { - swapsFeatureIsLive = Boolean(await this._fetchSwapsFeatureLiveness()); + swapsFeatureIsLive = Boolean( + await this._fetchSwapsFeatureLiveness(chainId), + ); successfullyFetched = true; } catch (err) { log.error(err); diff --git a/app/scripts/controllers/swaps.test.js b/app/scripts/controllers/swaps.test.js index 8fd07a18b..12169c83c 100644 --- a/app/scripts/controllers/swaps.test.js +++ b/app/scripts/controllers/swaps.test.js @@ -8,6 +8,7 @@ import { ObservableStore } from '@metamask/obs-store'; import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID, + MAINNET_CHAIN_ID, } from '../../../shared/constants/network'; import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; import { createTestProviderTools } from '../../../test/stub/provider'; @@ -75,6 +76,7 @@ const MOCK_FETCH_METADATA = { symbol: 'FOO', decimals: 18, }, + chainId: MAINNET_CHAIN_ID, }; const MOCK_TOKEN_RATES_STORE = new ObservableStore({ @@ -131,6 +133,8 @@ const sandbox = sinon.createSandbox(); const fetchTradesInfoStub = sandbox.stub(); const fetchSwapsFeatureLivenessStub = sandbox.stub(); const fetchSwapsQuoteRefreshTimeStub = sandbox.stub(); +const getCurrentChainIdStub = sandbox.stub(); +getCurrentChainIdStub.returns(MAINNET_CHAIN_ID); describe('SwapsController', function () { let provider; @@ -145,6 +149,7 @@ describe('SwapsController', function () { fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, fetchSwapsQuoteRefreshTime: fetchSwapsQuoteRefreshTimeStub, + getCurrentChainId: getCurrentChainIdStub, }); }; @@ -194,6 +199,7 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; const onNetworkDidChange = networkController.on.getCall(0).args[1]; @@ -218,6 +224,7 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; const onNetworkDidChange = networkController.on.getCall(0).args[1]; @@ -242,6 +249,7 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; const onNetworkDidChange = networkController.on.getCall(0).args[1]; @@ -686,7 +694,10 @@ describe('SwapsController', function () { }); assert.strictEqual( - fetchTradesInfoStub.calledOnceWithExactly(MOCK_FETCH_PARAMS), + fetchTradesInfoStub.calledOnceWithExactly( + MOCK_FETCH_PARAMS, + MOCK_FETCH_METADATA, + ), true, ); }); diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index fe88b897e..e61d747bd 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -958,6 +958,7 @@ export default class TransactionController extends EventEmitter { txMeta.txParams.from, txMeta.destinationTokenDecimals, approvalTxMeta, + txMeta.chainId, ); const quoteVsExecutionRatio = `${new BigNumber(tokensReceived, 10) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 9eaaf17f7..d34c5c86f 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -383,6 +383,9 @@ export default class MetamaskController extends EventEmitter { this.networkController, ), tokenRatesStore: this.tokenRatesController.store, + getCurrentChainId: this.networkController.getCurrentChainId.bind( + this.networkController, + ), }); // ensure accountTracker updates balances after network change diff --git a/shared/constants/swaps.js b/shared/constants/swaps.js index 7ae20c5ae..17898d256 100644 --- a/shared/constants/swaps.js +++ b/shared/constants/swaps.js @@ -1,3 +1,12 @@ +import { MAINNET_CHAIN_ID } from './network'; + +export const QUOTES_EXPIRED_ERROR = 'quotes-expired'; +export const SWAP_FAILED_ERROR = 'swap-failed-error'; +export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes'; +export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable'; +export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance'; +export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict'; + // An address that the metaswap-api recognizes as ETH, in place of the token address that ERC-20 tokens have const ETH_SWAPS_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000'; @@ -9,17 +18,42 @@ export const ETH_SWAPS_TOKEN_OBJECT = { iconUrl: 'images/black-eth-logo.svg', }; -export const QUOTES_EXPIRED_ERROR = 'quotes-expired'; -export const SWAP_FAILED_ERROR = 'swap-failed-error'; -export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes'; -export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable'; -export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance'; -export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict'; +const TEST_ETH_SWAPS_TOKEN_OBJECT = { + symbol: 'TESTETH', + name: 'Test Ether', + address: ETH_SWAPS_TOKEN_ADDRESS, + decimals: 18, + iconUrl: 'images/black-eth-logo.svg', +}; // A gas value for ERC20 approve calls that should be sufficient for all ERC20 approve implementations export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0'; -export const SWAPS_CONTRACT_ADDRESS = - '0x881d40237659c251811cec9c364ef91dc08d300c'; +const MAINNET_CONTRACT_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; + +const TESTNET_CONTRACT_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; + +const METASWAP_ETH_API_HOST = 'https://api.metaswap.codefi.network'; + +const SWAPS_TESTNET_CHAIN_ID = '0x539'; +const SWAPS_TESTNET_HOST = 'https://metaswap-api.airswap-dev.codefi.network'; -export const METASWAP_API_HOST = 'https://api.metaswap.codefi.network'; +export const ALLOWED_SWAPS_CHAIN_IDS = { + [MAINNET_CHAIN_ID]: true, + [SWAPS_TESTNET_CHAIN_ID]: true, +}; + +export const METASWAP_CHAINID_API_HOST_MAP = { + [MAINNET_CHAIN_ID]: METASWAP_ETH_API_HOST, + [SWAPS_TESTNET_CHAIN_ID]: SWAPS_TESTNET_HOST, +}; + +export const SWAPS_CHAINID_CONTRACT_ADDRESS_MAP = { + [MAINNET_CHAIN_ID]: MAINNET_CONTRACT_ADDRESS, + [SWAPS_TESTNET_CHAIN_ID]: TESTNET_CONTRACT_ADDRESS, +}; + +export const SWAPS_CHAINID_DEFAULT_TOKEN_MAP = { + [MAINNET_CHAIN_ID]: ETH_SWAPS_TOKEN_OBJECT, + [SWAPS_TESTNET_CHAIN_ID]: TEST_ETH_SWAPS_TOKEN_OBJECT, +}; diff --git a/shared/modules/swaps.utils.js b/shared/modules/swaps.utils.js new file mode 100644 index 000000000..799f17d1d --- /dev/null +++ b/shared/modules/swaps.utils.js @@ -0,0 +1,33 @@ +import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../constants/swaps'; + +/** + * Checks whether the provided address is strictly equal to the address for + * the default swaps token of the provided chain. + * + * @param {string} address - The string to compare to the default token address + * @param {string} chainId - The hex encoded chain ID of the default swaps token to check + * @returns {boolean} Whether the address is the provided chain's default token address + */ +export function isSwapsDefaultTokenAddress(address, chainId) { + if (!address || !chainId) { + return false; + } + + return address === SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId]?.address; +} + +/** + * Checks whether the provided symbol is strictly equal to the symbol for + * the default swaps token of the provided chain. + * + * @param {string} symbol - The string to compare to the default token symbol + * @param {string} chainId - The hex encoded chain ID of the default swaps token to check + * @returns {boolean} Whether the symbl is the provided chain's default token symbol + */ +export function isSwapsDefaultTokenSymbol(symbol, chainId) { + if (!symbol || !chainId) { + return false; + } + + return symbol === SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId]?.symbol; +} diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js index 305fbed98..389a76025 100644 --- a/ui/app/components/app/transaction-list/transaction-list.component.js +++ b/ui/app/components/app/transaction-list/transaction-list.component.js @@ -5,20 +5,31 @@ import { nonceSortedCompletedTransactionsSelector, nonceSortedPendingTransactionsSelector, } from '../../../selectors/transactions'; +import { getCurrentChainId } from '../../../selectors'; import { useI18nContext } from '../../../hooks/useI18nContext'; import TransactionListItem from '../transaction-list-item'; import Button from '../../ui/button'; import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions'; -import { SWAPS_CONTRACT_ADDRESS } from '../../../../../shared/constants/swaps'; +import { SWAPS_CHAINID_CONTRACT_ADDRESS_MAP } from '../../../../../shared/constants/swaps'; import { TRANSACTION_TYPES } from '../../../../../shared/constants/transaction'; const PAGE_INCREMENT = 10; -const getTransactionGroupRecipientAddressFilter = (recipientAddress) => { +// When we are on a token page, we only want to show transactions that involve that token. +// In the case of token transfers or approvals, these will be transactions sent to the +// token contract. In the case of swaps, these will be transactions sent to the swaps contract +// and which have the token address in the transaction data. +// +// getTransactionGroupRecipientAddressFilter is used to determine whether a transaction matches +// either of those criteria +const getTransactionGroupRecipientAddressFilter = ( + recipientAddress, + chainId, +) => { return ({ initialTransaction: { txParams } }) => { return ( txParams?.to === recipientAddress || - (txParams?.to === SWAPS_CONTRACT_ADDRESS && + (txParams?.to === SWAPS_CHAINID_CONTRACT_ADDRESS_MAP[chainId] && txParams.data.match(recipientAddress.slice(2))) ); }; @@ -39,12 +50,13 @@ const getFilteredTransactionGroups = ( transactionGroups, hideTokenTransactions, tokenAddress, + chainId, ) => { if (hideTokenTransactions) { return transactionGroups.filter(tokenTransactionFilter); } else if (tokenAddress) { return transactionGroups.filter( - getTransactionGroupRecipientAddressFilter(tokenAddress), + getTransactionGroupRecipientAddressFilter(tokenAddress, chainId), ); } return transactionGroups; @@ -63,6 +75,7 @@ export default function TransactionList({ const unfilteredCompletedTransactions = useSelector( nonceSortedCompletedTransactionsSelector, ); + const chainId = useSelector(getCurrentChainId); const pendingTransactions = useMemo( () => @@ -70,8 +83,14 @@ export default function TransactionList({ unfilteredPendingTransactions, hideTokenTransactions, tokenAddress, + chainId, ), - [hideTokenTransactions, tokenAddress, unfilteredPendingTransactions], + [ + hideTokenTransactions, + tokenAddress, + unfilteredPendingTransactions, + chainId, + ], ); const completedTransactions = useMemo( () => @@ -79,8 +98,14 @@ export default function TransactionList({ unfilteredCompletedTransactions, hideTokenTransactions, tokenAddress, + chainId, ), - [hideTokenTransactions, tokenAddress, unfilteredCompletedTransactions], + [ + hideTokenTransactions, + tokenAddress, + unfilteredCompletedTransactions, + chainId, + ], ); const viewMore = useCallback( diff --git a/ui/app/components/app/wallet-overview/eth-overview.js b/ui/app/components/app/wallet-overview/eth-overview.js index 38ada5c24..c4ef76115 100644 --- a/ui/app/components/app/wallet-overview/eth-overview.js +++ b/ui/app/components/app/wallet-overview/eth-overview.js @@ -25,7 +25,8 @@ import { getIsMainnet, getIsTestnet, getCurrentKeyring, - getSwapsEthToken, + getSwapsDefaultToken, + getIsSwapsChain, } from '../../../selectors/selectors'; import SwapIcon from '../../ui/icon/swap-icon.component'; import BuyIcon from '../../ui/icon/overview-buy-icon.component'; @@ -63,13 +64,14 @@ const EthOverview = ({ className }) => { const { balance } = selectedAccount; const isMainnetChain = useSelector(getIsMainnet); const isTestnetChain = useSelector(getIsTestnet); + const isSwapsChain = useSelector(getIsSwapsChain); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', properties: { source: 'Main View', active_currency: 'ETH' }, category: 'swaps', }); const swapsEnabled = useSelector(getSwapsFeatureLiveness); - const swapsEthToken = useSelector(getSwapsEthToken); + const defaultSwapsToken = useSelector(getSwapsDefaultToken); return ( { {swapsEnabled ? ( { - if (isMainnetChain) { + if (isSwapsChain) { enteredSwapsEvent(); - dispatch(setSwapsFromToken(swapsEthToken)); + dispatch(setSwapsFromToken(defaultSwapsToken)); if (usingHardwareWallet) { global.platform.openExtensionInBrowser(BUILD_QUOTE_ROUTE); } else { @@ -154,7 +156,7 @@ const EthOverview = ({ className }) => { {contents} diff --git a/ui/app/components/app/wallet-overview/token-overview.js b/ui/app/components/app/wallet-overview/token-overview.js index e705461d9..953de1fd8 100644 --- a/ui/app/components/app/wallet-overview/token-overview.js +++ b/ui/app/components/app/wallet-overview/token-overview.js @@ -25,9 +25,8 @@ import { import { getAssetImages, getCurrentKeyring, - getCurrentChainId, + getIsSwapsChain, } from '../../../selectors/selectors'; -import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network'; import SwapIcon from '../../ui/icon/swap-icon.component'; import SendIcon from '../../ui/icon/overview-send-icon.component'; @@ -58,7 +57,7 @@ const TokenOverview = ({ className, token }) => { balanceToRender, token.symbol, ); - const chainId = useSelector(getCurrentChainId); + const isSwapsChain = useSelector(getIsSwapsChain); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', properties: { source: 'Token View', active_currency: token.symbol }, @@ -100,10 +99,10 @@ const TokenOverview = ({ className, token }) => { {swapsEnabled ? ( { - if (chainId === MAINNET_CHAIN_ID) { + if (isSwapsChain) { enteredSwapsEvent(); dispatch( setSwapsFromToken({ @@ -125,7 +124,7 @@ const TokenOverview = ({ className, token }) => { {contents} diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 40e97428f..ae3198629 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -49,7 +49,8 @@ import { getSelectedAccount, getTokenExchangeRates, getUSDConversionRate, - getSwapsEthToken, + getSwapsDefaultToken, + getCurrentChainId, } from '../../selectors'; import { ERROR_FETCHING_QUOTES, @@ -376,9 +377,11 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent, ) => { return async (dispatch, getState) => { + const state = getState(); + const chainId = getCurrentChainId(state); let swapsFeatureIsLive = false; try { - swapsFeatureIsLive = await fetchSwapsFeatureLiveness(); + swapsFeatureIsLive = await fetchSwapsFeatureLiveness(chainId); } catch (error) { log.error('Failed to fetch Swaps liveness, defaulting to false.', error); } @@ -389,13 +392,14 @@ export const fetchQuotesAndSetQuoteState = ( return; } - const state = getState(); const fetchParams = getFetchParams(state); const selectedAccount = getSelectedAccount(state); const balanceError = getBalanceError(state); + const swapsDefaultToken = getSwapsDefaultToken(state); const fetchParamsFromToken = - fetchParams?.metaData?.sourceTokenInfo?.symbol === 'ETH' - ? getSwapsEthToken(state) + fetchParams?.metaData?.sourceTokenInfo?.symbol === + swapsDefaultToken.symbol + ? swapsDefaultToken : fetchParams?.metaData?.sourceTokenInfo; const selectedFromToken = getFromToken(state) || fetchParamsFromToken || {}; const selectedToToken = @@ -420,7 +424,10 @@ export const fetchQuotesAndSetQuoteState = ( const contractExchangeRates = getTokenExchangeRates(state); let destinationTokenAddedForSwap = false; - if (toTokenSymbol !== 'ETH' && !contractExchangeRates[toTokenAddress]) { + if ( + toTokenSymbol !== swapsDefaultToken.symbol && + !contractExchangeRates[toTokenAddress] + ) { destinationTokenAddedForSwap = true; await dispatch( addToken( @@ -433,7 +440,7 @@ export const fetchQuotesAndSetQuoteState = ( ); } if ( - fromTokenSymbol !== 'ETH' && + fromTokenSymbol !== swapsDefaultToken.symbol && !contractExchangeRates[fromTokenAddress] && fromTokenBalance && new BigNumber(fromTokenBalance, 16).gt(0) @@ -494,6 +501,7 @@ export const fetchQuotesAndSetQuoteState = ( sourceTokenInfo, destinationTokenInfo, accountBalance: selectedAccount.balance, + chainId, }, ), ); @@ -563,9 +571,12 @@ export const fetchQuotesAndSetQuoteState = ( export const signAndSendTransactions = (history, metaMetricsEvent) => { return async (dispatch, getState) => { + const state = getState(); + const chainId = getCurrentChainId(state); + let swapsFeatureIsLive = false; try { - swapsFeatureIsLive = await fetchSwapsFeatureLiveness(); + swapsFeatureIsLive = await fetchSwapsFeatureLiveness(chainId); } catch (error) { log.error('Failed to fetch Swaps liveness, defaulting to false.', error); } @@ -576,7 +587,6 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { return; } - const state = getState(); const customSwapsGas = getCustomSwapsGas(state); const fetchParams = getFetchParams(state); const { metaData, value: swapTokenValue, slippage } = fetchParams; diff --git a/ui/app/hooks/useCurrentAsset.js b/ui/app/hooks/useCurrentAsset.js index 382250e5f..832576a0c 100644 --- a/ui/app/hooks/useCurrentAsset.js +++ b/ui/app/hooks/useCurrentAsset.js @@ -1,13 +1,18 @@ import { useSelector } from 'react-redux'; import { useRouteMatch } from 'react-router-dom'; import { getTokens } from '../ducks/metamask/metamask'; +import { getCurrentChainId } from '../selectors'; import { ASSET_ROUTE } from '../helpers/constants/routes'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; +import { + SWAPS_CHAINID_DEFAULT_TOKEN_MAP, + ETH_SWAPS_TOKEN_OBJECT, +} from '../../../shared/constants/swaps'; /** * Returns a token object for the asset that is currently being viewed. - * Will return the ETH_SWAPS_TOKEN_OBJECT when the user is viewing either - * the primary, unfiltered, activity list or the ETH asset page. + * Will return the default token object for the current chain when the + * user is viewing either the primary, unfiltered, activity list or the + * default token asset page. * @returns {import('./useTokenDisplayValue').Token} */ export function useCurrentAsset() { @@ -22,6 +27,10 @@ export function useCurrentAsset() { const knownTokens = useSelector(getTokens); const token = tokenAddress && knownTokens.find(({ address }) => address === tokenAddress); + const chainId = useSelector(getCurrentChainId); - return token ?? ETH_SWAPS_TOKEN_OBJECT; + return ( + token ?? + (SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId] || ETH_SWAPS_TOKEN_OBJECT) + ); } diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index 788104bbb..6eff3726f 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -1,6 +1,11 @@ +import { useSelector } from 'react-redux'; import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; +import { + isSwapsDefaultTokenAddress, + isSwapsDefaultTokenSymbol, +} from '../../../shared/modules/swaps.utils'; import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util'; +import { getCurrentChainId } from '../selectors'; import { useTokenFiatAmount } from './useTokenFiatAmount'; /** @@ -14,10 +19,11 @@ import { useTokenFiatAmount } from './useTokenFiatAmount'; /** * A Swap transaction group's primaryTransaction contains details of the swap, * including the source (from) and destination (to) token type (ETH, DAI, etc..) - * When viewing a non ETH asset page, we need to determine if that asset is the - * token that was received (destination) from the swap. In that circumstance we - * would want to show the primaryCurrency in the activity list that is most relevant - * for that token (- 1000 DAI, for example, when swapping DAI for ETH). + * When viewing an asset page that is not for the current chain's default token, we + * need to determine if that asset is the token that was received (destination) from + * the swap. In that circumstance we would want to show the primaryCurrency in the + * activity list that is most relevant for that token (- 1000 DAI, for example, when + * swapping DAI for ETH). * @param {import('../selectors').transactionGroup} transactionGroup - Group of transactions by nonce * @param {import('./useTokenDisplayValue').Token} currentAsset - The current asset the user is looking at * @returns {SwappedTokenValue} @@ -27,11 +33,15 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { const { primaryTransaction, initialTransaction } = transactionGroup; const { type } = initialTransaction; const { from: senderAddress } = initialTransaction.txParams || {}; + const chainId = useSelector(getCurrentChainId); const isViewingReceivedTokenFromSwap = currentAsset?.symbol === primaryTransaction.destinationTokenSymbol || - (currentAsset.address === ETH_SWAPS_TOKEN_OBJECT.address && - primaryTransaction.destinationTokenSymbol === 'ETH'); + (isSwapsDefaultTokenAddress(currentAsset.address, chainId) && + isSwapsDefaultTokenSymbol( + primaryTransaction.destinationTokenSymbol, + chainId, + )); const swapTokenValue = type === TRANSACTION_TYPES.SWAP && isViewingReceivedTokenFromSwap @@ -41,6 +51,8 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { address, senderAddress, decimals, + null, + chainId, ) : type === TRANSACTION_TYPES.SWAP && primaryTransaction.swapTokenValue; diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index b1af93cdf..4542882f0 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -9,9 +9,11 @@ import { getTokenExchangeRates, getConversionRate, getCurrentCurrency, - getSwapsEthToken, + getSwapsDefaultToken, + getCurrentChainId, } from '../selectors'; import { getSwapsTokens } from '../ducks/swaps/swaps'; +import { isSwapsDefaultTokenSymbol } from '../../../shared/modules/swaps.utils'; import { useEqualityCheck } from './useEqualityCheck'; const tokenList = shuffle( @@ -28,12 +30,15 @@ export function getRenderableTokenData( contractExchangeRates, conversionRate, currentCurrency, + chainId, ) { const { symbol, name, address, iconUrl, string, balance, decimals } = token; const formattedFiat = getTokenFiatAmount( - symbol === 'ETH' ? 1 : contractExchangeRates[address], + isSwapsDefaultTokenSymbol(symbol, chainId) + ? 1 + : contractExchangeRates[address], conversionRate, currentCurrency, string, @@ -42,7 +47,9 @@ export function getRenderableTokenData( ) || ''; const rawFiat = getTokenFiatAmount( - symbol === 'ETH' ? 1 : contractExchangeRates[address], + isSwapsDefaultTokenSymbol(symbol, chainId) + ? 1 + : contractExchangeRates[address], conversionRate, currentCurrency, string, @@ -70,30 +77,32 @@ export function getRenderableTokenData( } export function useTokensToSearch({ usersTokens = [], topTokens = {} }) { + const chainId = useSelector(getCurrentChainId); const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); const conversionRate = useSelector(getConversionRate); const currentCurrency = useSelector(getCurrentCurrency); - const swapsEthToken = useSelector(getSwapsEthToken); + const defaultSwapsToken = useSelector(getSwapsDefaultToken); const memoizedTopTokens = useEqualityCheck(topTokens); const memoizedUsersToken = useEqualityCheck(usersTokens); - const ethToken = getRenderableTokenData( - swapsEthToken, + const defaultToken = getRenderableTokenData( + defaultSwapsToken, tokenConversionRates, conversionRate, currentCurrency, + chainId, ); - const memoizedEthToken = useEqualityCheck(ethToken); + const memoizedDefaultToken = useEqualityCheck(defaultToken); const swapsTokens = useSelector(getSwapsTokens) || []; const tokensToSearch = swapsTokens.length ? swapsTokens : [ - memoizedEthToken, + memoizedDefaultToken, ...tokenList.filter( - (token) => token.symbol !== memoizedEthToken.symbol, + (token) => token.symbol !== memoizedDefaultToken.symbol, ), ]; @@ -116,9 +125,10 @@ export function useTokensToSearch({ usersTokens = [], topTokens = {} }) { tokenConversionRates, conversionRate, currentCurrency, + chainId, ); if ( - renderableDataToken.symbol === 'ETH' || + isSwapsDefaultTokenSymbol(renderableDataToken.symbol, chainId) || (usersTokensAddressMap[token.address] && Number(renderableDataToken.balance ?? 0) !== 0) ) { @@ -150,5 +160,6 @@ export function useTokensToSearch({ usersTokens = [], topTokens = {} }) { conversionRate, currentCurrency, memoizedTopTokens, + chainId, ]); } diff --git a/ui/app/hooks/useTransactionDisplayData.test.js b/ui/app/hooks/useTransactionDisplayData.test.js index 531b5a649..76dca1bcd 100644 --- a/ui/app/hooks/useTransactionDisplayData.test.js +++ b/ui/app/hooks/useTransactionDisplayData.test.js @@ -10,11 +10,13 @@ import { getShouldShowFiat, getNativeCurrency, getCurrentCurrency, + getCurrentChainId, } from '../selectors'; import { getTokens } from '../ducks/metamask/metamask'; import { getMessage } from '../helpers/utils/i18n-helper'; import messages from '../../../app/_locales/en/messages.json'; import { ASSET_ROUTE, DEFAULT_ROUTE } from '../helpers/constants/routes'; +import { MAINNET_CHAIN_ID } from '../../../shared/constants/network'; import { TRANSACTION_TYPES, TRANSACTION_GROUP_CATEGORIES, @@ -164,6 +166,8 @@ describe('useTransactionDisplayData', function () { return 'ETH'; } else if (selector === getCurrentCurrency) { return 'ETH'; + } else if (selector === getCurrentChainId) { + return MAINNET_CHAIN_ID; } return null; }); diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index e218cbb9a..7f39c12e8 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -6,12 +6,14 @@ import { useHistory } from 'react-router-dom'; import { I18nContext } from '../../../contexts/i18n'; import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; + import { getCurrentChainId, getCurrentCurrency, getRpcPrefsForCurrentProvider, getUSDConversionRate, } from '../../../selectors'; + import { getUsedQuote, getFetchParams, @@ -23,7 +25,6 @@ import { prepareToLeaveSwaps, } from '../../../ducks/swaps/swaps'; import Mascot from '../../../components/ui/mascot'; -import PulseLoader from '../../../components/ui/pulse-loader'; import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, @@ -31,6 +32,9 @@ import { QUOTES_NOT_AVAILABLE_ERROR, OFFLINE_FOR_MAINTENANCE, } from '../../../../../shared/constants/swaps'; +import { isSwapsDefaultTokenSymbol } from '../../../../../shared/modules/swaps.utils'; +import PulseLoader from '../../../components/ui/pulse-loader'; + import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { getRenderableNetworkFeesForQuote } from '../swaps.util'; @@ -73,16 +77,17 @@ export default function AwaitingSwap({ let feeinUnformattedFiat; if (usedQuote && swapsGasPrice) { - const renderableNetworkFees = getRenderableNetworkFeesForQuote( - usedQuote.gasEstimateWithRefund || usedQuote.averageGas, - approveTxParams?.gas || '0x0', - swapsGasPrice, + const renderableNetworkFees = getRenderableNetworkFeesForQuote({ + tradeGas: usedQuote.gasEstimateWithRefund || usedQuote.averageGas, + approveGas: approveTxParams?.gas || '0x0', + gasPrice: swapsGasPrice, currentCurrency, - usdConversionRate, - usedQuote?.trade?.value, - sourceTokenInfo?.symbol, - usedQuote.sourceAmount, - ); + conversionRate: usdConversionRate, + tradeValue: usedQuote?.trade?.value, + sourceSymbol: sourceTokenInfo?.symbol, + sourceAmount: usedQuote.sourceAmount, + chainId, + }); feeinUnformattedFiat = renderableNetworkFees.rawNetworkFees; } @@ -228,7 +233,9 @@ export default function AwaitingSwap({ ); } else if (errorKey) { await dispatch(navigateBackToBuildQuote(history)); - } else if (destinationTokenInfo?.symbol === 'ETH') { + } else if ( + isSwapsDefaultTokenSymbol(destinationTokenInfo?.symbol, chainId) + ) { history.push(DEFAULT_ROUTE); } else { history.push(`${ASSET_ROUTE}/${destinationTokenInfo?.address}`); diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index 7648efe47..d106fa18d 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -29,10 +29,11 @@ import { getFetchParams, } from '../../../ducks/swaps/swaps'; import { - getSwapsEthToken, + getSwapsDefaultToken, getTokenExchangeRates, getConversionRate, getCurrentCurrency, + getCurrentChainId, } from '../../../selectors'; import { getValueFromWeiHex, @@ -44,7 +45,10 @@ import { useTokenTracker } from '../../../hooks/useTokenTracker'; import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../../shared/constants/swaps'; +import { + isSwapsDefaultTokenAddress, + isSwapsDefaultTokenSymbol, +} from '../../../../../shared/modules/swaps.utils'; import { resetSwapsPostFetchState, removeToken } from '../../../store/actions'; import { fetchTokenPrice, fetchTokenBalance } from '../swaps.util'; @@ -84,21 +88,29 @@ export default function BuildQuote({ const topAssets = useSelector(getTopAssets); const fromToken = useSelector(getFromToken); const toToken = useSelector(getToToken) || destinationTokenInfo; - const swapsEthToken = useSelector(getSwapsEthToken); - const fetchParamsFromToken = - sourceTokenInfo?.symbol === 'ETH' ? swapsEthToken : sourceTokenInfo; + const defaultSwapsToken = useSelector(getSwapsDefaultToken); + const chainId = useSelector(getCurrentChainId); const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); const conversionRate = useSelector(getConversionRate); const currentCurrency = useSelector(getCurrentCurrency); + const fetchParamsFromToken = isSwapsDefaultTokenSymbol( + sourceTokenInfo?.symbol, + chainId, + ) + ? defaultSwapsToken + : sourceTokenInfo; + const { loading, tokensWithBalances } = useTokenTracker(tokens); // If the fromToken was set in a call to `onFromSelect` (see below), and that from token has a balance // but is not in tokensWithBalances or tokens, then we want to add it to the usersTokens array so that // the balance of the token can appear in the from token selection dropdown const fromTokenArray = - fromToken?.symbol !== 'ETH' && fromToken?.balance ? [fromToken] : []; + !isSwapsDefaultTokenSymbol(fromToken?.symbol, chainId) && fromToken?.balance + ? [fromToken] + : []; const usersTokens = uniqBy( [...tokensWithBalances, ...tokens, ...fromTokenArray], 'address', @@ -110,6 +122,7 @@ export default function BuildQuote({ tokenConversionRates, conversionRate, currentCurrency, + chainId, ); const tokensToSearch = useTokensToSearch({ @@ -119,9 +132,9 @@ export default function BuildQuote({ const selectedToToken = tokensToSearch.find(({ address }) => address === toToken?.address) || toToken; - const toTokenIsNotEth = + const toTokenIsNotDefault = selectedToToken?.address && - selectedToToken?.address !== ETH_SWAPS_TOKEN_OBJECT.address; + !isSwapsDefaultTokenAddress(selectedToToken?.address, chainId); const occurances = Number(selectedToToken?.occurances || 0); const { address: fromTokenAddress, @@ -151,8 +164,9 @@ export default function BuildQuote({ { showFiat: true }, true, ); - const swapFromFiatValue = - fromTokenSymbol === 'ETH' ? swapFromEthFiatValue : swapFromTokenFiatValue; + const swapFromFiatValue = isSwapsDefaultTokenSymbol(fromTokenSymbol, chainId) + ? swapFromEthFiatValue + : swapFromTokenFiatValue; const onFromSelect = (token) => { if ( @@ -227,15 +241,17 @@ export default function BuildQuote({ ); useEffect(() => { - const notEth = - tokensWithBalancesFromToken?.address !== ETH_SWAPS_TOKEN_OBJECT.address; + const notDefault = !isSwapsDefaultTokenAddress( + tokensWithBalancesFromToken?.address, + chainId, + ); const addressesAreTheSame = tokensWithBalancesFromToken?.address === previousTokensWithBalancesFromToken?.address; const balanceHasChanged = tokensWithBalancesFromToken?.balance !== previousTokensWithBalancesFromToken?.balance; - if (notEth && addressesAreTheSame && balanceHasChanged) { + if (notDefault && addressesAreTheSame && balanceHasChanged) { dispatch( setSwapsFromToken({ ...fromToken, @@ -249,12 +265,13 @@ export default function BuildQuote({ tokensWithBalancesFromToken, previousTokensWithBalancesFromToken, fromToken, + chainId, ]); // If the eth balance changes while on build quote, we update the selected from token useEffect(() => { if ( - fromToken?.address === ETH_SWAPS_TOKEN_OBJECT.address && + isSwapsDefaultTokenAddress(fromToken?.address, chainId) && fromToken?.balance !== hexToDecimal(ethBalance) ) { dispatch( @@ -269,7 +286,7 @@ export default function BuildQuote({ }), ); } - }, [dispatch, fromToken, ethBalance]); + }, [dispatch, fromToken, ethBalance, chainId]); useEffect(() => { if (prevFromTokenBalance !== fromTokenBalance) { @@ -286,7 +303,7 @@ export default function BuildQuote({
    {t('swapSwapFrom')}
    - {fromTokenSymbol !== 'ETH' && ( + {!isSwapsDefaultTokenSymbol(fromTokenSymbol, chainId) && (
    @@ -384,7 +401,7 @@ export default function BuildQuote({ defaultToAll />
    - {toTokenIsNotEth && + {toTokenIsNotDefault && (occurances < 2 ? ( MAX_ALLOWED_SLIPPAGE || - (toTokenIsNotEth && occurances < 2 && !verificationClicked) + (toTokenIsNotDefault && occurances < 2 && !verificationClicked) } hideCancel showTermsOfService diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index 75752d24c..04f4505b3 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -12,6 +12,7 @@ import { I18nContext } from '../../contexts/i18n'; import { getSelectedAccount, getCurrentChainId, + getIsSwapsChain, } from '../../selectors/selectors'; import { getQuotes, @@ -45,7 +46,6 @@ import { SWAP_FAILED_ERROR, OFFLINE_FOR_MAINTENANCE, } from '../../../../shared/constants/swaps'; -import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { resetBackgroundSwapsState, @@ -96,6 +96,8 @@ export default function Swap() { const fetchingQuotes = useSelector(getFetchingQuotes); let swapsErrorKey = useSelector(getSwapsErrorKey); const swapsEnabled = useSelector(getSwapsFeatureLiveness); + const chainId = useSelector(getCurrentChainId); + const isSwapsChain = useSelector(getIsSwapsChain); const { balance: ethBalance, @@ -116,6 +118,7 @@ export default function Swap() { selectedAccountAddress, destinationTokenInfo?.decimals, approveTxData, + chainId, ); const tradeConfirmed = tradeTxData?.status === TRANSACTION_STATUSES.CONFIRMED; const approveError = @@ -155,26 +158,26 @@ export default function Swap() { }, []); useEffect(() => { - fetchTokens() + fetchTokens(chainId) .then((tokens) => { dispatch(setSwapsTokens(tokens)); }) .catch((error) => console.error(error)); - fetchTopAssets().then((topAssets) => { + fetchTopAssets(chainId).then((topAssets) => { dispatch(setTopAssets(topAssets)); }); - fetchAggregatorMetadata().then((newAggregatorMetadata) => { + fetchAggregatorMetadata(chainId).then((newAggregatorMetadata) => { dispatch(setAggregatorMetadata(newAggregatorMetadata)); }); - dispatch(fetchAndSetSwapsGasPriceInfo()); + dispatch(fetchAndSetSwapsGasPriceInfo(chainId)); return () => { dispatch(prepareToLeaveSwaps()); }; - }, [dispatch]); + }, [dispatch, chainId]); const exitedSwapsEvent = useNewMetricEvent({ event: 'Exited Swaps', @@ -224,8 +227,7 @@ export default function Swap() { return () => window.removeEventListener('beforeunload', fn); }, [dispatch, isLoadingQuotesRoute]); - const chainId = useSelector(getCurrentChainId); - if (chainId !== MAINNET_CHAIN_ID) { + if (!isSwapsChain) { return ; } diff --git a/ui/app/pages/swaps/intro-popup/intro-popup.js b/ui/app/pages/swaps/intro-popup/intro-popup.js index 359cd0d34..658c84bb9 100644 --- a/ui/app/pages/swaps/intro-popup/intro-popup.js +++ b/ui/app/pages/swaps/intro-popup/intro-popup.js @@ -6,7 +6,7 @@ import { setSwapsFromToken } from '../../../ducks/swaps/swaps'; import { I18nContext } from '../../../contexts/i18n'; import { BUILD_QUOTE_ROUTE } from '../../../helpers/constants/routes'; import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; -import { getSwapsEthToken } from '../../../selectors'; +import { getSwapsDefaultToken } from '../../../selectors'; import Button from '../../../components/ui/button'; import Popover from '../../../components/ui/popover'; @@ -14,9 +14,14 @@ export default function IntroPopup({ onClose }) { const dispatch = useDispatch(useDispatch); const history = useHistory(); const t = useContext(I18nContext); + + const swapsDefaultToken = useSelector(getSwapsDefaultToken); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', - properties: { source: 'Intro popup', active_currency: 'ETH' }, + properties: { + source: 'Intro popup', + active_currency: swapsDefaultToken.symbol, + }, category: 'swaps', }); const blogPostVisitedEvent = useNewMetricEvent({ @@ -31,7 +36,6 @@ export default function IntroPopup({ onClose }) { event: 'Product Overview Dismissed', category: 'swaps', }); - const swapsEthToken = useSelector(getSwapsEthToken); return (
    @@ -51,7 +55,7 @@ export default function IntroPopup({ onClose }) { onClick={() => { onClose(); enteredSwapsEvent(); - dispatch(setSwapsFromToken(swapsEthToken)); + dispatch(setSwapsFromToken(swapsDefaultToken)); history.push(BUILD_QUOTE_ROUTE); }} > diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index 85c8a5cdf..8e2c89bac 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -3,9 +3,15 @@ import BigNumber from 'bignumber.js'; import abi from 'human-standard-token-abi'; import { isValidAddress } from 'ethereumjs-util'; import { - ETH_SWAPS_TOKEN_OBJECT, - METASWAP_API_HOST, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP, + METASWAP_CHAINID_API_HOST_MAP, } from '../../../../shared/constants/swaps'; +import { + isSwapsDefaultTokenAddress, + isSwapsDefaultTokenSymbol, +} from '../../../../shared/modules/swaps.utils'; + +import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { calcTokenValue, calcTokenAmount, @@ -30,22 +36,22 @@ const TOKEN_TRANSFER_LOG_TOPIC_HASH = const CACHE_REFRESH_ONE_HOUR = 3600000; -const getBaseApi = function (type) { +const getBaseApi = function (type, chainId = MAINNET_CHAIN_ID) { switch (type) { case 'trade': - return `${METASWAP_API_HOST}/trades?`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/trades?`; case 'tokens': - return `${METASWAP_API_HOST}/tokens`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/tokens`; case 'topAssets': - return `${METASWAP_API_HOST}/topAssets`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/topAssets`; case 'featureFlag': - return `${METASWAP_API_HOST}/featureFlag`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/featureFlag`; case 'aggregatorMetadata': - return `${METASWAP_API_HOST}/aggregatorMetadata`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/aggregatorMetadata`; case 'gasPrices': - return `${METASWAP_API_HOST}/gasPrices`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/gasPrices`; case 'refreshTime': - return `${METASWAP_API_HOST}/quoteRefreshRate`; + return `${METASWAP_CHAINID_API_HOST_MAP[chainId]}/quoteRefreshRate`; default: throw new Error('getBaseApi requires an api call type'); } @@ -205,15 +211,18 @@ function validateData(validators, object, urlUsed) { }); } -export async function fetchTradesInfo({ - slippage, - sourceToken, - sourceDecimals, - destinationToken, - value, - fromAddress, - exchangeList, -}) { +export async function fetchTradesInfo( + { + slippage, + sourceToken, + sourceDecimals, + destinationToken, + value, + fromAddress, + exchangeList, + }, + { chainId }, +) { const urlParams = { destinationToken, sourceToken, @@ -228,7 +237,7 @@ export async function fetchTradesInfo({ } const queryString = new URLSearchParams(urlParams).toString(); - const tradeURL = `${getBaseApi('trade')}${queryString}`; + const tradeURL = `${getBaseApi('trade', chainId)}${queryString}`; const tradesResponse = await fetchWithCache( tradeURL, { method: 'GET' }, @@ -272,21 +281,21 @@ export async function fetchTradesInfo({ return newQuotes; } -export async function fetchTokens() { - const tokenUrl = getBaseApi('tokens'); +export async function fetchTokens(chainId) { + const tokenUrl = getBaseApi('tokens', chainId); const tokens = await fetchWithCache( tokenUrl, { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }, ); const filteredTokens = [ - ETH_SWAPS_TOKEN_OBJECT, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId], ...tokens.filter((token) => { return ( validateData(TOKEN_VALIDATORS, token, tokenUrl) && !( - token.symbol === ETH_SWAPS_TOKEN_OBJECT.symbol || - token.address === ETH_SWAPS_TOKEN_OBJECT.address + isSwapsDefaultTokenSymbol(token.symbol, chainId) || + isSwapsDefaultTokenAddress(token.address, chainId) ) ); }), @@ -294,8 +303,8 @@ export async function fetchTokens() { return filteredTokens; } -export async function fetchAggregatorMetadata() { - const aggregatorMetadataUrl = getBaseApi('aggregatorMetadata'); +export async function fetchAggregatorMetadata(chainId) { + const aggregatorMetadataUrl = getBaseApi('aggregatorMetadata', chainId); const aggregators = await fetchWithCache( aggregatorMetadataUrl, { method: 'GET' }, @@ -316,8 +325,8 @@ export async function fetchAggregatorMetadata() { return filteredAggregators; } -export async function fetchTopAssets() { - const topAssetsUrl = getBaseApi('topAssets'); +export async function fetchTopAssets(chainId) { + const topAssetsUrl = getBaseApi('topAssets', chainId); const response = await fetchWithCache( topAssetsUrl, { method: 'GET' }, @@ -332,18 +341,18 @@ export async function fetchTopAssets() { return topAssetsMap; } -export async function fetchSwapsFeatureLiveness() { +export async function fetchSwapsFeatureLiveness(chainId) { const status = await fetchWithCache( - getBaseApi('featureFlag'), + getBaseApi('featureFlag', chainId), { method: 'GET' }, { cacheRefreshTime: 600000 }, ); return status?.active; } -export async function fetchSwapsQuoteRefreshTime() { +export async function fetchSwapsQuoteRefreshTime(chainId) { const response = await fetchWithCache( - getBaseApi('refreshTime'), + getBaseApi('refreshTime', chainId), { method: 'GET' }, { cacheRefreshTime: 600000 }, ); @@ -378,8 +387,8 @@ export async function fetchTokenBalance(address, userAddress) { return usersToken; } -export async function fetchSwapsGasPrices() { - const gasPricesUrl = getBaseApi('gasPrices'); +export async function fetchSwapsGasPrices(chainId) { + const gasPricesUrl = getBaseApi('gasPrices', chainId); const response = await fetchWithCache( gasPricesUrl, { method: 'GET' }, @@ -408,7 +417,7 @@ export async function fetchSwapsGasPrices() { }; } -export function getRenderableNetworkFeesForQuote( +export function getRenderableNetworkFeesForQuote({ tradeGas, approveGas, gasPrice, @@ -417,14 +426,18 @@ export function getRenderableNetworkFeesForQuote( tradeValue, sourceSymbol, sourceAmount, -) { + chainId, +}) { const totalGasLimitForCalculation = new BigNumber(tradeGas || '0x0', 16) .plus(approveGas || '0x0', 16) .toString(16); const gasTotalInWeiHex = calcGasTotal(totalGasLimitForCalculation, gasPrice); const nonGasFee = new BigNumber(tradeValue, 16) - .minus(sourceSymbol === 'ETH' ? sourceAmount : 0, 10) + .minus( + isSwapsDefaultTokenSymbol(sourceSymbol, chainId) ? sourceAmount : 0, + 10, + ) .toString(16); const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16) @@ -447,7 +460,7 @@ export function getRenderableNetworkFeesForQuote( rawNetworkFees, rawEthFee: ethFee, feeInFiat: formattedNetworkFee, - feeInEth: `${ethFee} ETH`, + feeInEth: `${ethFee} ${SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId].symbol}`, nonGasFee, }; } @@ -459,6 +472,7 @@ export function quotesToRenderableData( currentCurrency, approveGas, tokenConversionRates, + chainId, ) { return Object.values(quotes).map((quote) => { const { @@ -488,16 +502,17 @@ export function quotesToRenderableData( rawNetworkFees, rawEthFee, feeInEth, - } = getRenderableNetworkFeesForQuote( - gasEstimateWithRefund || decimalToHex(averageGas || 800000), + } = getRenderableNetworkFeesForQuote({ + tradeGas: gasEstimateWithRefund || decimalToHex(averageGas || 800000), approveGas, gasPrice, currentCurrency, conversionRate, - trade.value, - sourceTokenInfo.symbol, + tradeValue: trade.value, + sourceSymbol: sourceTokenInfo.symbol, sourceAmount, - ); + chainId, + }); const slippageMultiplier = new BigNumber(100 - slippage).div(100); const minimumAmountReceived = new BigNumber(destinationValue) @@ -506,18 +521,20 @@ export function quotesToRenderableData( const tokenConversionRate = tokenConversionRates[destinationTokenInfo.address]; - const ethValueOfTrade = - destinationTokenInfo.symbol === 'ETH' - ? calcTokenAmount( - destinationAmount, - destinationTokenInfo.decimals, - ).minus(rawEthFee, 10) - : new BigNumber(tokenConversionRate || 0, 10) - .times( - calcTokenAmount(destinationAmount, destinationTokenInfo.decimals), - 10, - ) - .minus(rawEthFee, 10); + const ethValueOfTrade = isSwapsDefaultTokenSymbol( + destinationTokenInfo.symbol, + chainId, + ) + ? calcTokenAmount(destinationAmount, destinationTokenInfo.decimals).minus( + rawEthFee, + 10, + ) + : new BigNumber(tokenConversionRate || 0, 10) + .times( + calcTokenAmount(destinationAmount, destinationTokenInfo.decimals), + 10, + ) + .minus(rawEthFee, 10); let liquiditySourceKey; let renderedSlippage = slippage; @@ -566,9 +583,10 @@ export function getSwapsTokensReceivedFromTxMeta( accountAddress, tokenDecimals, approvalTxMeta, + chainId, ) { const txReceipt = txMeta?.txReceipt; - if (tokenSymbol === 'ETH') { + if (isSwapsDefaultTokenSymbol(tokenSymbol, chainId)) { if ( !txReceipt || !txMeta || diff --git a/ui/app/pages/swaps/swaps.util.test.js b/ui/app/pages/swaps/swaps.util.test.js index c68cff29b..df305e675 100644 --- a/ui/app/pages/swaps/swaps.util.test.js +++ b/ui/app/pages/swaps/swaps.util.test.js @@ -1,5 +1,6 @@ import { strict as assert } from 'assert'; import proxyquire from 'proxyquire'; +import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { TRADES_BASE_PROD_URL, TOKENS_BASE_PROD_URL, @@ -89,42 +90,45 @@ describe('Swaps Util', function () { }, }; it('should fetch trade info on prod', async function () { - const result = await fetchTradesInfo({ - TOKENS, - slippage: '3', - sourceToken: TOKENS[0].address, - destinationToken: TOKENS[1].address, - value: '2000000000000000000', - fromAddress: '0xmockAddress', - sourceSymbol: TOKENS[0].symbol, - sourceDecimals: TOKENS[0].decimals, - sourceTokenInfo: { ...TOKENS[0] }, - destinationTokenInfo: { ...TOKENS[1] }, - }); + const result = await fetchTradesInfo( + { + TOKENS, + slippage: '3', + sourceToken: TOKENS[0].address, + destinationToken: TOKENS[1].address, + value: '2000000000000000000', + fromAddress: '0xmockAddress', + sourceSymbol: TOKENS[0].symbol, + sourceDecimals: TOKENS[0].decimals, + sourceTokenInfo: { ...TOKENS[0] }, + destinationTokenInfo: { ...TOKENS[1] }, + }, + { chainId: MAINNET_CHAIN_ID }, + ); assert.deepStrictEqual(result, expectedResult2); }); }); describe('fetchTokens', function () { it('should fetch tokens', async function () { - const result = await fetchTokens(true); + const result = await fetchTokens(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT); }); it('should fetch tokens on prod', async function () { - const result = await fetchTokens(false); + const result = await fetchTokens(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT); }); }); describe('fetchAggregatorMetadata', function () { it('should fetch aggregator metadata', async function () { - const result = await fetchAggregatorMetadata(true); + const result = await fetchAggregatorMetadata(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, AGGREGATOR_METADATA); }); it('should fetch aggregator metadata on prod', async function () { - const result = await fetchAggregatorMetadata(false); + const result = await fetchAggregatorMetadata(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, AGGREGATOR_METADATA); }); }); @@ -148,12 +152,12 @@ describe('Swaps Util', function () { }, }; it('should fetch top assets', async function () { - const result = await fetchTopAssets(true); + const result = await fetchTopAssets(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, expectedResult); }); it('should fetch top assets on prod', async function () { - const result = await fetchTopAssets(false); + const result = await fetchTopAssets(MAINNET_CHAIN_ID); assert.deepStrictEqual(result, expectedResult); }); }); diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index f16af36a0..02cf4b464 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -36,7 +36,8 @@ import { getSelectedAccount, getCurrentCurrency, getTokenExchangeRates, - getSwapsEthToken, + getSwapsDefaultToken, + getCurrentChainId, } from '../../../selectors'; import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util'; import { getTokens } from '../../../ducks/metamask/metamask'; @@ -125,7 +126,8 @@ export default function ViewQuote() { const usedQuote = selectedQuote || topQuote; const tradeValue = usedQuote?.trade?.value ?? '0x0'; const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime); - const swapsEthToken = useSelector(getSwapsEthToken); + const defaultSwapsToken = useSelector(getSwapsDefaultToken); + const chainId = useSelector(getCurrentChainId); const { isBestQuote } = usedQuote; @@ -151,8 +153,8 @@ export default function ViewQuote() { const { tokensWithBalances } = useTokenTracker(swapsTokens, true); const balanceToken = - fetchParamsSourceToken === swapsEthToken.address - ? swapsEthToken + fetchParamsSourceToken === defaultSwapsToken.address + ? defaultSwapsToken : tokensWithBalances.find( ({ address }) => address === fetchParamsSourceToken, ); @@ -183,6 +185,7 @@ export default function ViewQuote() { currentCurrency, approveGas, memoizedTokenConversionRates, + chainId, ); }, [ quotes, @@ -191,6 +194,7 @@ export default function ViewQuote() { currentCurrency, approveGas, memoizedTokenConversionRates, + chainId, ]); const renderableDataForUsedQuote = renderablePopoverData.find( @@ -209,31 +213,33 @@ export default function ViewQuote() { sourceTokenIconUrl, } = renderableDataForUsedQuote; - const { feeInFiat, feeInEth } = getRenderableNetworkFeesForQuote( - usedGasLimit, + const { feeInFiat, feeInEth } = getRenderableNetworkFeesForQuote({ + tradeGas: usedGasLimit, approveGas, gasPrice, currentCurrency, conversionRate, tradeValue, - sourceTokenSymbol, - usedQuote.sourceAmount, - ); + sourceSymbol: sourceTokenSymbol, + sourceAmount: usedQuote.sourceAmount, + chainId, + }); const { feeInFiat: maxFeeInFiat, feeInEth: maxFeeInEth, nonGasFee, - } = getRenderableNetworkFeesForQuote( - maxGasLimit, + } = getRenderableNetworkFeesForQuote({ + tradeGas: maxGasLimit, approveGas, gasPrice, currentCurrency, conversionRate, tradeValue, - sourceTokenSymbol, - usedQuote.sourceAmount, - ); + sourceSymbol: sourceTokenSymbol, + sourceAmount: usedQuote.sourceAmount, + chainId, + }); const tokenCost = new BigNumber(usedQuote.sourceAmount); const ethCost = new BigNumber(usedQuote.trade.value || 0, 10).plus( @@ -481,9 +487,9 @@ export default function ViewQuote() { {tokenBalanceNeeded || ethBalanceNeeded} , - tokenBalanceNeeded && !(sourceTokenSymbol === 'ETH') + tokenBalanceNeeded && !(sourceTokenSymbol === defaultSwapsToken.symbol) ? sourceTokenSymbol - : 'ETH', + : defaultSwapsToken.symbol, ]); // Price difference warning @@ -643,7 +649,7 @@ export default function ViewQuote() { setSelectQuotePopoverShown(true); }} tokenConversionRate={ - destinationTokenSymbol === 'ETH' + destinationTokenSymbol === defaultSwapsToken.symbol ? 1 : memoizedTokenConversionRates[destinationToken.address] } @@ -655,7 +661,7 @@ export default function ViewQuote() { setSubmitClicked(true); if (!balanceError) { dispatch(signAndSendTransactions(history, metaMetricsEvent)); - } else if (destinationToken.symbol === 'ETH') { + } else if (destinationToken.symbol === defaultSwapsToken.symbol) { history.push(DEFAULT_ROUTE); } else { history.push(`${ASSET_ROUTE}/${destinationToken.address}`); diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index f0146194f..550c45983 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -15,7 +15,10 @@ import { getValueFromWeiHex, hexToDecimal, } from '../helpers/utils/conversions.util'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps'; +import { + SWAPS_CHAINID_DEFAULT_TOKEN_MAP, + ALLOWED_SWAPS_CHAIN_IDS, +} from '../../../shared/constants/swaps'; /** * One of the only remaining valid uses of selecting the network subkey of the @@ -431,22 +434,26 @@ export function getWeb3ShimUsageStateForOrigin(state, origin) { * minimal token units (according to its decimals). * `string` is the token balance in a readable format, ready for rendering. * - * Swaps treats ETH as a token, and we use the ETH_SWAPS_TOKEN_OBJECT constant - * to set the standard properties for the token. The getSwapsEthToken selector - * extends that object with `balance` and `balance` values of the same type as - * in regular ERC-20 token objects, per the above description. + * Swaps treats the selected chain's currency as a token, and we use the token constants + * in the SWAPS_CHAINID_DEFAULT_TOKEN_MAP to set the standard properties for + * the token. The getSwapsDefaultToken selector extends that object with + * `balance` and `string` values of the same type as in regular ERC-20 token + * objects, per the above description. * * @param {object} state - the redux state object * @returns {SwapsEthToken} The token object representation of the currently * selected account's ETH balance, as expected by the Swaps API. */ -export function getSwapsEthToken(state) { +export function getSwapsDefaultToken(state) { const selectedAccount = getSelectedAccount(state); const { balance } = selectedAccount; + const chainId = getCurrentChainId(state); + + const defaultTokenObject = SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId]; return { - ...ETH_SWAPS_TOKEN_OBJECT, + ...defaultTokenObject, balance: hexToDecimal(balance), string: getValueFromWeiHex({ value: balance, @@ -455,3 +462,8 @@ export function getSwapsEthToken(state) { }), }; } + +export function getIsSwapsChain(state) { + const chainId = getCurrentChainId(state); + return ALLOWED_SWAPS_CHAIN_IDS[chainId]; +} From b50fe3184ac82344af256db901e5c0bc08ebc956 Mon Sep 17 00:00:00 2001 From: Shane Date: Thu, 18 Mar 2021 11:23:46 -0700 Subject: [PATCH 21/82] fix: replace dnode background with JSON-RPC (#10627) fixes #10090 --- .../controllers/incoming-transactions.js | 2 +- .../controllers/incoming-transactions.test.js | 2 +- .../transactions/tx-state-manager.js | 2 +- app/scripts/lib/createMetaRPCHandler.js | 33 +++++++ app/scripts/lib/createMetaRPCHandler.test.js | 61 +++++++++++++ app/scripts/lib/decrypt-message-manager.js | 2 +- .../lib/encryption-public-key-manager.js | 2 +- app/scripts/lib/message-manager.js | 2 +- app/scripts/lib/metaRPCClientFactory.js | 81 +++++++++++++++++ app/scripts/lib/metaRPCClientFactory.test.js | 88 +++++++++++++++++++ app/scripts/lib/personal-message-manager.js | 2 +- app/scripts/lib/typed-message-manager.js | 2 +- app/scripts/metamask-controller.js | 38 ++++---- app/scripts/metamask-controller.test.js | 2 +- app/scripts/phishing-detect.js | 46 +++------- app/scripts/ui.js | 21 +---- package.json | 1 - .../lib => shared/modules}/random-id.js | 0 ui/app/store/actions.js | 30 +++++-- ui/index.js | 12 ++- yarn.lock | 33 +------ 21 files changed, 339 insertions(+), 123 deletions(-) create mode 100644 app/scripts/lib/createMetaRPCHandler.js create mode 100644 app/scripts/lib/createMetaRPCHandler.test.js create mode 100644 app/scripts/lib/metaRPCClientFactory.js create mode 100644 app/scripts/lib/metaRPCClientFactory.test.js rename {app/scripts/lib => shared/modules}/random-id.js (100%) diff --git a/app/scripts/controllers/incoming-transactions.js b/app/scripts/controllers/incoming-transactions.js index 632bd96a4..61958fc88 100644 --- a/app/scripts/controllers/incoming-transactions.js +++ b/app/scripts/controllers/incoming-transactions.js @@ -1,7 +1,7 @@ import { ObservableStore } from '@metamask/obs-store'; import log from 'loglevel'; import BN from 'bn.js'; -import createId from '../lib/random-id'; +import createId from '../../../shared/modules/random-id'; import { bnToHex } from '../lib/util'; import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; diff --git a/app/scripts/controllers/incoming-transactions.test.js b/app/scripts/controllers/incoming-transactions.test.js index b7e52b19f..a50c1df64 100644 --- a/app/scripts/controllers/incoming-transactions.test.js +++ b/app/scripts/controllers/incoming-transactions.test.js @@ -22,7 +22,7 @@ import { import { NETWORK_EVENTS } from './network'; const IncomingTransactionsController = proxyquire('./incoming-transactions', { - '../lib/random-id': { default: () => 54321 }, + '../../../shared/modules/random-id': { default: () => 54321 }, }).default; const FAKE_CHAIN_ID = '0x1338'; diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js index c62a97d1e..32d10509b 100644 --- a/app/scripts/controllers/transactions/tx-state-manager.js +++ b/app/scripts/controllers/transactions/tx-state-manager.js @@ -1,7 +1,7 @@ import EventEmitter from 'safe-event-emitter'; import { ObservableStore } from '@metamask/obs-store'; import log from 'loglevel'; -import createId from '../../lib/random-id'; +import createId from '../../../../shared/modules/random-id'; import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; import { transactionMatchesNetwork } from '../../../../shared/modules/transaction.utils'; diff --git a/app/scripts/lib/createMetaRPCHandler.js b/app/scripts/lib/createMetaRPCHandler.js new file mode 100644 index 000000000..24ac0ff6a --- /dev/null +++ b/app/scripts/lib/createMetaRPCHandler.js @@ -0,0 +1,33 @@ +import { ethErrors, serializeError } from 'eth-rpc-errors'; + +const createMetaRPCHandler = (api, outStream) => { + return (data) => { + if (!api[data.method]) { + outStream.write({ + jsonrpc: '2.0', + error: ethErrors.rpc.methodNotFound({ + message: `${data.method} not found`, + }), + id: data.id, + }); + return; + } + api[data.method](...data.params, (err, result) => { + if (err) { + outStream.write({ + jsonrpc: '2.0', + error: serializeError(err, { shouldIncludeStack: true }), + id: data.id, + }); + } else { + outStream.write({ + jsonrpc: '2.0', + result, + id: data.id, + }); + } + }); + }; +}; + +export default createMetaRPCHandler; diff --git a/app/scripts/lib/createMetaRPCHandler.test.js b/app/scripts/lib/createMetaRPCHandler.test.js new file mode 100644 index 000000000..e37985105 --- /dev/null +++ b/app/scripts/lib/createMetaRPCHandler.test.js @@ -0,0 +1,61 @@ +import assert from 'assert'; +import { obj as createThoughStream } from 'through2'; +import createMetaRPCHandler from './createMetaRPCHandler'; + +describe('createMetaRPCHandler', function () { + it('can call the api when handler receives a JSON-RPC request', function (done) { + const api = { + foo: (param1) => { + assert.strictEqual(param1, 'bar'); + done(); + }, + }; + const streamTest = createThoughStream(); + const handler = createMetaRPCHandler(api, streamTest); + handler({ + id: 1, + method: 'foo', + params: ['bar'], + }); + }); + it('can write the response to the outstream when api callback is called', function (done) { + const api = { + foo: (param1, cb) => { + assert.strictEqual(param1, 'bar'); + cb(null, 'foobarbaz'); + }, + }; + const streamTest = createThoughStream(); + const handler = createMetaRPCHandler(api, streamTest); + handler({ + id: 1, + method: 'foo', + params: ['bar'], + }); + streamTest.on('data', (data) => { + assert.strictEqual(data.result, 'foobarbaz'); + streamTest.end(); + done(); + }); + }); + it('can write the error to the outstream when api callback is called with an error', function (done) { + const api = { + foo: (param1, cb) => { + assert.strictEqual(param1, 'bar'); + cb(new Error('foo-error')); + }, + }; + const streamTest = createThoughStream(); + const handler = createMetaRPCHandler(api, streamTest); + handler({ + id: 1, + method: 'foo', + params: ['bar'], + }); + streamTest.on('data', (data) => { + assert.strictEqual(data.error.message, 'foo-error'); + streamTest.end(); + done(); + }); + }); +}); diff --git a/app/scripts/lib/decrypt-message-manager.js b/app/scripts/lib/decrypt-message-manager.js index 32ae13626..674c73572 100644 --- a/app/scripts/lib/decrypt-message-manager.js +++ b/app/scripts/lib/decrypt-message-manager.js @@ -5,8 +5,8 @@ import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; +import createId from '../../../shared/modules/random-id'; import { addHexPrefix } from './util'; -import createId from './random-id'; const hexRe = /^[0-9A-Fa-f]+$/gu; diff --git a/app/scripts/lib/encryption-public-key-manager.js b/app/scripts/lib/encryption-public-key-manager.js index e29723b5b..2a4b2296e 100644 --- a/app/scripts/lib/encryption-public-key-manager.js +++ b/app/scripts/lib/encryption-public-key-manager.js @@ -4,7 +4,7 @@ import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; -import createId from './random-id'; +import createId from '../../../shared/modules/random-id'; /** * Represents, and contains data about, an 'eth_getEncryptionPublicKey' type request. These are created when diff --git a/app/scripts/lib/message-manager.js b/app/scripts/lib/message-manager.js index 7f4218f8b..ce48327f3 100644 --- a/app/scripts/lib/message-manager.js +++ b/app/scripts/lib/message-manager.js @@ -4,7 +4,7 @@ import ethUtil from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; -import createId from './random-id'; +import createId from '../../../shared/modules/random-id'; /** * Represents, and contains data about, an 'eth_sign' type signature request. These are created when a signature for diff --git a/app/scripts/lib/metaRPCClientFactory.js b/app/scripts/lib/metaRPCClientFactory.js new file mode 100644 index 000000000..108da0e4c --- /dev/null +++ b/app/scripts/lib/metaRPCClientFactory.js @@ -0,0 +1,81 @@ +import { EthereumRpcError } from 'eth-rpc-errors'; +import SafeEventEmitter from 'safe-event-emitter'; +import createRandomId from '../../../shared/modules/random-id'; + +class MetaRPCClient { + constructor(connectionStream) { + this.connectionStream = connectionStream; + this.notificationChannel = new SafeEventEmitter(); + this.requests = new Map(); + this.connectionStream.on('data', this.handleResponse.bind(this)); + this.connectionStream.on('end', this.close.bind(this)); + } + + onNotification(handler) { + this.notificationChannel.addListener('notification', (data) => { + handler(data); + }); + } + + close() { + this.notificationChannel.removeAllListeners(); + } + + handleResponse(data) { + const { id, result, error, method, params } = data; + const cb = this.requests.get(id); + + if (method && params && id) { + // dont handle server-side to client-side requests + return; + } + if (method && params && !id) { + // handle servier-side to client-side notification + this.notificationChannel.emit('notification', data); + return; + } + if (!cb) { + // not found in request list + return; + } + + if (error) { + const e = new EthereumRpcError(error.code, error.message, error.data); + // preserve the stack from serializeError + e.stack = error.stack; + this.requests.delete(id); + cb(e); + return; + } + + this.requests.delete(id); + + cb(null, result); + } +} + +const metaRPCClientFactory = (connectionStream) => { + const metaRPCClient = new MetaRPCClient(connectionStream); + return new Proxy(metaRPCClient, { + get: (object, property) => { + if (object[property]) { + return object[property]; + } + return (...p) => { + const cb = p[p.length - 1]; + const params = p.slice(0, -1); + const id = createRandomId(); + + object.requests.set(id, cb); + object.connectionStream.write({ + jsonrpc: '2.0', + method: property, + params, + id, + }); + }; + }, + }); +}; + +export default metaRPCClientFactory; diff --git a/app/scripts/lib/metaRPCClientFactory.test.js b/app/scripts/lib/metaRPCClientFactory.test.js new file mode 100644 index 000000000..d270a4e1a --- /dev/null +++ b/app/scripts/lib/metaRPCClientFactory.test.js @@ -0,0 +1,88 @@ +import assert from 'assert'; +import { obj as createThoughStream } from 'through2'; +import metaRPCClientFactory from './metaRPCClientFactory'; + +describe('metaRPCClientFactory', function () { + it('should be able to make an rpc request with the method', function (done) { + const streamTest = createThoughStream((chunk) => { + assert.strictEqual(chunk.method, 'foo'); + done(); + }); + const metaRPCClient = metaRPCClientFactory(streamTest); + metaRPCClient.foo(); + }); + it('should be able to make an rpc request/response with the method and params and node-style callback', function (done) { + const streamTest = createThoughStream(); + const metaRPCClient = metaRPCClientFactory(streamTest); + + // make a "foo" method call + metaRPCClient.foo('bar', (_, result) => { + assert.strictEqual(result, 'foobarbaz'); + done(); + }); + + // fake a response + metaRPCClient.requests.forEach((_, key) => { + streamTest.write({ + jsonrpc: '2.0', + id: key, + result: 'foobarbaz', + }); + }); + }); + it('should be able to make an rpc request/error with the method and params and node-style callback', function (done) { + const streamTest = createThoughStream(); + const metaRPCClient = metaRPCClientFactory(streamTest); + + // make a "foo" method call + metaRPCClient.foo('bar', (err) => { + assert.strictEqual(err.message, 'foo-message'); + assert.strictEqual(err.code, 1); + done(); + }); + + metaRPCClient.requests.forEach((_, key) => { + streamTest.write({ + jsonrpc: '2.0', + id: key, + error: { + code: 1, + message: 'foo-message', + }, + }); + }); + }); + + it('should be able to make an rpc request/response with the method and params and node-style callback with multiple instances of metaRPCClientFactory and the same connectionStream', function (done) { + const streamTest = createThoughStream(); + const metaRPCClient = metaRPCClientFactory(streamTest); + const metaRPCClient2 = metaRPCClientFactory(streamTest); + + // make a "foo" method call, followed by "baz" call on metaRPCClient2 + metaRPCClient.foo('bar', (_, result) => { + assert.strictEqual(result, 'foobarbaz'); + metaRPCClient2.baz('bar', (err) => { + assert.strictEqual(err, null); + done(); + }); + }); + + // fake a response + metaRPCClient.requests.forEach((_, key) => { + streamTest.write({ + jsonrpc: '2.0', + id: key, + result: 'foobarbaz', + }); + }); + + // fake client2's response + metaRPCClient2.requests.forEach((_, key) => { + streamTest.write({ + jsonrpc: '2.0', + id: key, + result: 'foobarbaz', + }); + }); + }); +}); diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index 1fb59144b..0149e4802 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -5,8 +5,8 @@ import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; +import createId from '../../../shared/modules/random-id'; import { addHexPrefix } from './util'; -import createId from './random-id'; const hexRe = /^[0-9A-Fa-f]+$/gu; diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index d1ea6491b..28e7a2534 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -8,7 +8,7 @@ import log from 'loglevel'; import jsonschema from 'jsonschema'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; -import createId from './random-id'; +import createId from '../../../shared/modules/random-id'; /** * Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d34c5c86f..14c96098c 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1,6 +1,5 @@ import EventEmitter from 'events'; import pump from 'pump'; -import Dnode from 'dnode'; import { ObservableStore } from '@metamask/obs-store'; import { storeAsStream } from '@metamask/obs-store/dist/asStream'; import { JsonRpcEngine } from 'json-rpc-engine'; @@ -60,6 +59,7 @@ import accountImporter from './account-import-strategies'; import seedPhraseVerifier from './lib/seed-phrase-verifier'; import MetaMetricsController from './controllers/metametrics'; import { segment, segmentLegacy } from './lib/segment'; +import createMetaRPCHandler from './lib/createMetaRPCHandler'; export const METAMASK_CONTROLLER_EVENTS = { // Fired after state changes that impact the extension badge (unapproved msg count) @@ -598,7 +598,7 @@ export default class MetamaskController extends EventEmitter { /** * Returns an Object containing API Callback Functions. * These functions are the interface for the UI. - * The API object can be transmitted over a stream with dnode. + * The API object can be transmitted over a stream via JSON-RPC. * * @returns {Object} Object containing API functions. */ @@ -1996,36 +1996,34 @@ export default class MetamaskController extends EventEmitter { } /** - * A method for providing our API over a stream using Dnode. + * A method for providing our API over a stream using JSON-RPC. * @param {*} outStream - The stream to provide our API over. */ setupControllerConnection(outStream) { const api = this.getApi(); - // the "weak: false" option is for nodejs only (eg unit tests) - // it is a workaround for node v12 support - const dnode = Dnode(api, { weak: false }); + // report new active controller connection this.activeControllerConnections += 1; this.emit('controllerConnectionChanged', this.activeControllerConnections); - // connect dnode api to remote connection - pump(outStream, dnode, outStream, (err) => { - // report new active controller connection + + // set up postStream transport + outStream.on('data', createMetaRPCHandler(api, outStream)); + const handleUpdate = (update) => { + // send notification to client-side + outStream.write({ + jsonrpc: '2.0', + method: 'sendUpdate', + params: [update], + }); + }; + this.on('update', handleUpdate); + outStream.on('end', () => { this.activeControllerConnections -= 1; this.emit( 'controllerConnectionChanged', this.activeControllerConnections, ); - // report any error - if (err) { - log.error(err); - } - }); - dnode.on('remote', (remote) => { - // push updates to popup - const sendUpdate = (update) => remote.sendUpdate(update); - this.on('update', sendUpdate); - // remove update listener once the connection ends - dnode.on('end', () => this.removeListener('update', sendUpdate)); + this.removeListener('update', handleUpdate); }); } diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 146eb0889..f8b74006e 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -1116,7 +1116,7 @@ describe('MetaMaskController', function () { }); describe('#setupTrustedCommunication', function () { - it('sets up controller dnode api for trusted communication', async function () { + it('sets up controller JSON-RPC api for trusted communication', async function () { const messageSender = { url: 'http://mycrypto.com', tab: {}, diff --git a/app/scripts/phishing-detect.js b/app/scripts/phishing-detect.js index 9ade869f0..f036461c3 100644 --- a/app/scripts/phishing-detect.js +++ b/app/scripts/phishing-detect.js @@ -1,8 +1,7 @@ import querystring from 'querystring'; -import { EventEmitter } from 'events'; -import dnode from 'dnode'; import PortStream from 'extension-port-stream'; import extension from 'extensionizer'; +import createRandomId from '../../shared/modules/random-id'; import { setupMultiplex } from './lib/stream-utils'; import { getEnvironmentType } from './lib/util'; import ExtensionPlatform from './platforms/extension'; @@ -22,36 +21,15 @@ function start() { }); const connectionStream = new PortStream(extensionPort); const mx = setupMultiplex(connectionStream); - setupControllerConnection( - mx.createStream('controller'), - (err, metaMaskController) => { - if (err) { - return; - } - - const continueLink = document.getElementById('unsafe-continue'); - continueLink.addEventListener('click', () => { - metaMaskController.safelistPhishingDomain(suspect.hostname); - window.location.href = suspect.href; - }); - }, - ); -} - -function setupControllerConnection(connectionStream, cb) { - const eventEmitter = new EventEmitter(); - // the "weak: false" option is for nodejs only (eg unit tests) - // it is a workaround for node v12 support - const metaMaskControllerDnode = dnode( - { - sendUpdate(state) { - eventEmitter.emit('update', state); - }, - }, - { weak: false }, - ); - connectionStream.pipe(metaMaskControllerDnode).pipe(connectionStream); - metaMaskControllerDnode.once('remote', (backgroundConnection) => - cb(null, backgroundConnection), - ); + const backgroundConnection = mx.createStream('controller'); + const continueLink = document.getElementById('unsafe-continue'); + continueLink.addEventListener('click', () => { + backgroundConnection.write({ + jsonrpc: '2.0', + method: 'safelistPhishingDomain', + params: [suspect.hostname], + id: createRandomId(), + }); + window.location.href = suspect.href; + }); } diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 0d048191c..b00c3d6da 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -2,11 +2,9 @@ import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'; import '@formatjs/intl-relativetimeformat/polyfill'; -import { EventEmitter } from 'events'; import PortStream from 'extension-port-stream'; import extension from 'extensionizer'; -import Dnode from 'dnode'; import Eth from 'ethjs'; import EthQuery from 'eth-query'; import StreamProvider from 'web3-stream-provider'; @@ -19,6 +17,7 @@ import { import ExtensionPlatform from './platforms/extension'; import { setupMultiplex } from './lib/stream-utils'; import { getEnvironmentType } from './lib/util'; +import metaRPCClientFactory from './lib/metaRPCClientFactory'; start().catch(log.error); @@ -138,20 +137,6 @@ function setupWeb3Connection(connectionStream) { * @param {Function} cb - Called when the remote account manager connection is established */ function setupControllerConnection(connectionStream, cb) { - const eventEmitter = new EventEmitter(); - // the "weak: false" option is for nodejs only (eg unit tests) - // it is a workaround for node v12 support - const backgroundDnode = Dnode( - { - sendUpdate(state) { - eventEmitter.emit('update', state); - }, - }, - { weak: false }, - ); - connectionStream.pipe(backgroundDnode).pipe(connectionStream); - backgroundDnode.once('remote', function (backgroundConnection) { - backgroundConnection.on = eventEmitter.on.bind(eventEmitter); - cb(null, backgroundConnection); - }); + const backgroundRPC = metaRPCClientFactory(connectionStream); + cb(null, backgroundRPC); } diff --git a/package.json b/package.json index 0a84353a0..d7b242642 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,6 @@ "currency-formatter": "^1.4.2", "debounce-stream": "^2.0.0", "deep-freeze-strict": "1.1.1", - "dnode": "^1.2.2", "end-of-stream": "^1.4.4", "eth-block-tracker": "^4.4.2", "eth-ens-namehash": "^2.0.8", diff --git a/app/scripts/lib/random-id.js b/shared/modules/random-id.js similarity index 100% rename from app/scripts/lib/random-id.js rename to shared/modules/random-id.js diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index 8b613f0a5..907f6fa10 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -2427,8 +2427,12 @@ export function requestAccountsPermissionWithId(origin) { * @param {string[]} accounts - The accounts to expose, if any. */ export function approvePermissionsRequest(request, accounts) { - return () => { - background.approvePermissionsRequest(request, accounts); + return (dispatch) => { + background.approvePermissionsRequest(request, accounts, (err) => { + if (err) { + dispatch(displayWarning(err.message)); + } + }); }; } @@ -2455,8 +2459,12 @@ export function rejectPermissionsRequest(requestId) { * Clears the given permissions for the given origin. */ export function removePermissionsFor(domains) { - return () => { - background.removePermissionsFor(domains); + return (dispatch) => { + background.removePermissionsFor(domains, (err) => { + if (err) { + dispatch(displayWarning(err.message)); + } + }); }; } @@ -2464,8 +2472,12 @@ export function removePermissionsFor(domains) { * Clears all permissions for all domains. */ export function clearPermissions() { - return () => { - background.clearPermissions(); + return (dispatch) => { + background.clearPermissions((err) => { + if (err) { + dispatch(displayWarning(err.message)); + } + }); }; } @@ -2610,7 +2622,11 @@ export function getContractMethodData(data = '') { return getMethodDataAsync(fourBytePrefix).then(({ name, params }) => { dispatch(loadingMethodDataFinished()); - background.addKnownMethodData(fourBytePrefix, { name, params }); + background.addKnownMethodData(fourBytePrefix, { name, params }, (err) => { + if (err) { + dispatch(displayWarning(err.message)); + } + }); return { name, params }; }); }; diff --git a/ui/index.js b/ui/index.js index 3ccc25b6c..16a8f5c7d 100644 --- a/ui/index.js +++ b/ui/index.js @@ -128,8 +128,16 @@ async function startApp(metamaskState, backgroundConnection, opts) { ); } - backgroundConnection.on('update', function (state) { - store.dispatch(actions.updateMetamaskState(state)); + backgroundConnection.onNotification((data) => { + if (data.method === 'sendUpdate') { + store.dispatch(actions.updateMetamaskState(data.params[0])); + } else { + throw new Error( + `Internal JSON-RPC Notification Not Handled:\n\n ${JSON.stringify( + data, + )}`, + ); + } }); // global metamask api - used by tooling diff --git a/yarn.lock b/yarn.lock index df49ca023..738b2c749 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8565,24 +8565,6 @@ dnd-core@^7.4.4: invariant "^2.2.4" redux "^4.0.1" -dnode-protocol@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dnode-protocol/-/dnode-protocol-0.2.2.tgz#51151d16fc3b5f84815ee0b9497a1061d0d1949d" - integrity sha1-URUdFvw7X4SBXuC5SXoQYdDRlJ0= - dependencies: - jsonify "~0.0.0" - traverse "~0.6.3" - -dnode@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/dnode/-/dnode-1.2.2.tgz#4ac3cfe26e292b3b39b8258ae7d94edc58132efa" - integrity sha1-SsPP4m4pKzs5uCWK59lO3FgTLvo= - dependencies: - dnode-protocol "~0.2.2" - jsonify "~0.0.0" - optionalDependencies: - weak "^1.0.0" - dns-packet@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-4.2.0.tgz#3fd6f5ff5a4ec3194ed0b15312693ffe8776b343" @@ -17608,7 +17590,7 @@ nan@2.13.2: resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== -nan@^2.0.5, nan@^2.11.1, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.2.1: +nan@^2.11.1, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.2.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -24362,11 +24344,6 @@ tr46@^1.0.0, tr46@^1.0.1: dependencies: punycode "^2.1.0" -traverse@~0.6.3: - version "0.6.6" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" - integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= - tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -25417,14 +25394,6 @@ wcwidth@^1.0.0: dependencies: defaults "^1.0.3" -weak@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/weak/-/weak-1.0.1.tgz#ab99aab30706959aa0200cb8cf545bb9cb33b99e" - integrity sha1-q5mqswcGlZqgIAy4z1RbucszuZ4= - dependencies: - bindings "^1.2.1" - nan "^2.0.5" - web3-bzz@1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" From 6cfdac529f1378e7c45d556e18352198361e2b72 Mon Sep 17 00:00:00 2001 From: ryanml Date: Fri, 19 Mar 2021 08:48:41 -0700 Subject: [PATCH 22/82] Don't render faucet row in deposit modal for custom chains (#10674) Fixes MetaMask/metamask-extension#10038 --- .../deposit-ether-modal.component.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js index 147a80e86..553f25973 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js +++ b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js @@ -155,14 +155,15 @@ export default class DepositEtherModal extends Component { buttonLabel: this.context.t('viewAccount'), onButtonClick: () => this.goToAccountDetailsModal(), })} - {this.renderRow({ - logo: , - title: this.context.t('testFaucet'), - text: this.context.t('getEtherFromFaucet', [networkName]), - buttonLabel: this.context.t('getEther'), - onButtonClick: () => toFaucet(chainId), - hide: !isTestnet, - })} + {networkName && + this.renderRow({ + logo: , + title: this.context.t('testFaucet'), + text: this.context.t('getEtherFromFaucet', [networkName]), + buttonLabel: this.context.t('getEther'), + onButtonClick: () => toFaucet(chainId), + hide: !isTestnet, + })}
    From fc999f948b5bf1d5d05b40483064792e18342b7c Mon Sep 17 00:00:00 2001 From: gitpurva <47534619+gitpurva@users.noreply.github.com> Date: Fri, 19 Mar 2021 22:42:11 +0530 Subject: [PATCH 23/82] Change 'Send ETH' title to 'Send' (#10651) --- app/_locales/am/messages.json | 3 --- app/_locales/ar/messages.json | 3 --- app/_locales/bg/messages.json | 3 --- app/_locales/bn/messages.json | 3 --- app/_locales/ca/messages.json | 3 --- app/_locales/cs/messages.json | 3 --- app/_locales/da/messages.json | 3 --- app/_locales/de/messages.json | 3 --- app/_locales/el/messages.json | 3 --- app/_locales/en/messages.json | 3 --- app/_locales/es/messages.json | 3 --- app/_locales/es_419/messages.json | 3 --- app/_locales/et/messages.json | 3 --- app/_locales/fa/messages.json | 3 --- app/_locales/fi/messages.json | 3 --- app/_locales/fil/messages.json | 3 --- app/_locales/fr/messages.json | 3 --- app/_locales/he/messages.json | 3 --- app/_locales/hi/messages.json | 3 --- app/_locales/hn/messages.json | 3 --- app/_locales/hr/messages.json | 3 --- app/_locales/ht/messages.json | 3 --- app/_locales/hu/messages.json | 3 --- app/_locales/id/messages.json | 3 --- app/_locales/it/messages.json | 3 --- app/_locales/ja/messages.json | 3 --- app/_locales/kn/messages.json | 3 --- app/_locales/ko/messages.json | 3 --- app/_locales/lt/messages.json | 3 --- app/_locales/lv/messages.json | 3 --- app/_locales/ms/messages.json | 3 --- app/_locales/nl/messages.json | 3 --- app/_locales/pl/messages.json | 3 --- app/_locales/pt/messages.json | 3 --- app/_locales/pt_BR/messages.json | 3 --- app/_locales/ro/messages.json | 3 --- app/_locales/ru/messages.json | 3 --- app/_locales/sk/messages.json | 3 --- app/_locales/sl/messages.json | 3 --- app/_locales/sr/messages.json | 3 --- app/_locales/sv/messages.json | 3 --- app/_locales/sw/messages.json | 3 --- app/_locales/ta/messages.json | 3 --- app/_locales/th/messages.json | 3 --- app/_locales/tl/messages.json | 3 --- app/_locales/tr/messages.json | 3 --- app/_locales/uk/messages.json | 3 --- app/_locales/vi/messages.json | 3 --- app/_locales/zh_CN/messages.json | 3 --- app/_locales/zh_TW/messages.json | 3 --- ui/app/hooks/useTransactionDisplayData.js | 2 +- ui/app/hooks/useTransactionDisplayData.test.js | 6 +++--- ui/app/selectors/send.js | 2 +- ui/app/selectors/send.test.js | 2 +- 54 files changed, 6 insertions(+), 156 deletions(-) diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index a52aee23f..cc697e452 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -934,9 +934,6 @@ "sendAmount": { "message": "መጠኑን ላክ" }, - "sendETH": { - "message": "ETH ላክ" - }, "sendTokens": { "message": "ተለዋጭ ስሞችን ላክ" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 9a04e15d8..54095520a 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -930,9 +930,6 @@ "sendAmount": { "message": "إرسال المبلغ" }, - "sendETH": { - "message": "إرسال عملة إيثيريوم" - }, "sendTokens": { "message": "إرسال عملات رمزية" }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 26abfe956..a443e38d1 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -933,9 +933,6 @@ "sendAmount": { "message": "Изпратете сумата" }, - "sendETH": { - "message": "Изпрати ETH" - }, "sendTokens": { "message": "Изпращане на жетони" }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index 2ef360f19..f87c0d6dd 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -937,9 +937,6 @@ "sendAmount": { "message": "পাঠানো অর্থরাশি" }, - "sendETH": { - "message": "ETH পাঠান" - }, "sendTokens": { "message": "টোকেনগুলি পাঠান" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index fda999248..cff905794 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -915,9 +915,6 @@ "sendAmount": { "message": "Enviar Quantitat" }, - "sendETH": { - "message": "Envia ETH" - }, "sendTokens": { "message": "Enviar Fitxes" }, diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json index 3ccfc0089..f24aaf824 100644 --- a/app/_locales/cs/messages.json +++ b/app/_locales/cs/messages.json @@ -356,9 +356,6 @@ "send": { "message": "Odeslat" }, - "sendETH": { - "message": "Odeslat ETH" - }, "sendTokens": { "message": "Odeslat tokeny" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index 9378cbbbd..e558751ba 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -915,9 +915,6 @@ "sendAmount": { "message": "Send Beløb" }, - "sendETH": { - "message": "Vælg ETH" - }, "sendTokens": { "message": "Send tokens" }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index f90cd388e..6db35e4d3 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -906,9 +906,6 @@ "sendAmount": { "message": "Betrag senden" }, - "sendETH": { - "message": "ETH senden" - }, "sendTokens": { "message": "Token senden" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 95df989d9..25fd175e5 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -934,9 +934,6 @@ "sendAmount": { "message": "Αποστολή Ποσού" }, - "sendETH": { - "message": "Στείλτε ETH" - }, "sendTokens": { "message": "Στείλτε Tokens" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index b79c5b9b0..53b47fcda 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1511,9 +1511,6 @@ "sendAmount": { "message": "Send Amount" }, - "sendETH": { - "message": "Send ETH" - }, "sendSpecifiedTokens": { "message": "Send $1", "description": "Symbol of the specified token" diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index f7cb42082..5d2501941 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -1413,9 +1413,6 @@ "sendAmount": { "message": "Enviar cantidad" }, - "sendETH": { - "message": "Enviar ETH" - }, "sendSpecifiedTokens": { "message": "Enviar $1", "description": "Symbol of the specified token" diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 9428674bd..237e063ff 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -1413,9 +1413,6 @@ "sendAmount": { "message": "Enviar monto" }, - "sendETH": { - "message": "Enviar ETH" - }, "sendSpecifiedTokens": { "message": "Enviar $1", "description": "Symbol of the specified token" diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index e2cfe7aa3..4908192e1 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -927,9 +927,6 @@ "sendAmount": { "message": "Saatke kogus" }, - "sendETH": { - "message": "Saada ETH" - }, "sendTokens": { "message": "Saada lube" }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index b8bffe956..e9eee1ddf 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -937,9 +937,6 @@ "sendAmount": { "message": "ارسال مبلغ" }, - "sendETH": { - "message": "ارسال ETH" - }, "sendTokens": { "message": "رمزیاب ها را ارسال کنید" }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index fa5bd1125..e8c5ec0d0 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -934,9 +934,6 @@ "sendAmount": { "message": "Lähetä summa" }, - "sendETH": { - "message": "Lähetä ETH:iä" - }, "sendTokens": { "message": "Lähetä tietueita" }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 473331a30..16a07e99b 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -849,9 +849,6 @@ "sendAmount": { "message": "Magpadala ng Halaga" }, - "sendETH": { - "message": "Magpadala ng ETH" - }, "sendTokens": { "message": "Magpadala ng Mga Token" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 39d44fb72..ca0791341 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -919,9 +919,6 @@ "sendAmount": { "message": "Envoyer le montant" }, - "sendETH": { - "message": "Envoyer des ETH" - }, "sendTokens": { "message": "Envoyer des jetons" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index 9b426ea16..5f0fa2ba3 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -931,9 +931,6 @@ "sendAmount": { "message": "שלח סכום" }, - "sendETH": { - "message": "שלח/י ETH" - }, "sendTokens": { "message": "שלח טוקנים" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 8feb56e55..74b404bdb 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1404,9 +1404,6 @@ "sendAmount": { "message": "राशि भेजें" }, - "sendETH": { - "message": "ETH भेजें" - }, "sendSpecifiedTokens": { "message": "$1 भेजें", "description": "Symbol of the specified token" diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json index 0dac2b285..a2cef557d 100644 --- a/app/_locales/hn/messages.json +++ b/app/_locales/hn/messages.json @@ -336,9 +336,6 @@ "send": { "message": "भेजें" }, - "sendETH": { - "message": "भेजें ETH" - }, "sendTokens": { "message": "भेजें टोकन" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index 17c35b6b7..959d7dc77 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -930,9 +930,6 @@ "sendAmount": { "message": "Odaberi iznos" }, - "sendETH": { - "message": "Pošalji ETH" - }, "sendTokens": { "message": "Pošalji tokene" }, diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json index 40d8d73bb..2b6e4b063 100644 --- a/app/_locales/ht/messages.json +++ b/app/_locales/ht/messages.json @@ -585,9 +585,6 @@ "send": { "message": "Voye" }, - "sendETH": { - "message": "Voye ETH" - }, "sendTokens": { "message": "Voye Tokens" }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index ce8df8e5d..1089ce3c6 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -930,9 +930,6 @@ "sendAmount": { "message": "Összeg küldése" }, - "sendETH": { - "message": "ETH küldése" - }, "sendTokens": { "message": "Token küldése" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 67f7d4470..768543c3e 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -1404,9 +1404,6 @@ "sendAmount": { "message": "Kirim Jumlah" }, - "sendETH": { - "message": "Kirim ETH" - }, "sendSpecifiedTokens": { "message": "Kirim $1", "description": "Symbol of the specified token" diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index c497ee342..c924cc30d 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -1419,9 +1419,6 @@ "sendAmount": { "message": "Invia Importo" }, - "sendETH": { - "message": "Invia ETH" - }, "sendSpecifiedTokens": { "message": "Invia $1", "description": "Symbol of the specified token" diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 69b2f208e..020d6b7b1 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1413,9 +1413,6 @@ "sendAmount": { "message": "送金額" }, - "sendETH": { - "message": "ETHの送金" - }, "sendSpecifiedTokens": { "message": "$1 を送る", "description": "Symbol of the specified token" diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index e07994172..32d24c6d7 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -937,9 +937,6 @@ "sendAmount": { "message": "ಮೊತ್ತವನ್ನು ಕಳುಹಿಸಿ" }, - "sendETH": { - "message": "ETH ಕಳುಹಿಸಿ" - }, "sendTokens": { "message": "ಟೋಕನ್‌ಗಳನ್ನು ಕಳುಹಿಸಿ" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 3f1df0f86..9a1bb146f 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -1401,9 +1401,6 @@ "sendAmount": { "message": "금액 보내기" }, - "sendETH": { - "message": "ETH 보내기" - }, "sendSpecifiedTokens": { "message": "$1 보내기", "description": "Symbol of the specified token" diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index ec9137030..4e20c2812 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -937,9 +937,6 @@ "sendAmount": { "message": "Siųsti sumą" }, - "sendETH": { - "message": "Siųsti ETH" - }, "sendTokens": { "message": "Siųsti žetonus" }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index fd1b79205..72d09faff 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -933,9 +933,6 @@ "sendAmount": { "message": "Nosūtītā summa" }, - "sendETH": { - "message": "Sūtīt ETH" - }, "sendTokens": { "message": "Nosūtīt marķierus" }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index 355a2ca28..dd3c3cfd7 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -914,9 +914,6 @@ "sendAmount": { "message": "Hantar Amaun" }, - "sendETH": { - "message": "Hantar ETH" - }, "sendTokens": { "message": "Hantar Token" }, diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json index 1c20ec2f5..6db2439eb 100644 --- a/app/_locales/nl/messages.json +++ b/app/_locales/nl/messages.json @@ -323,9 +323,6 @@ "send": { "message": "Sturen" }, - "sendETH": { - "message": "Verzend ETH" - }, "sendTokens": { "message": "Stuur tokens" }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 4a4c717a8..484e53c91 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -931,9 +931,6 @@ "sendAmount": { "message": "Wyślij kwotę" }, - "sendETH": { - "message": "Wyślij ETH" - }, "sendTokens": { "message": "Wyślij tokeny" }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index ca1cca50f..0a3367d59 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -333,9 +333,6 @@ "send": { "message": "Enviar" }, - "sendETH": { - "message": "Enviar ETH" - }, "sendTokens": { "message": "Enviar Tokens" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 5aac3e78b..6c2eb760a 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -925,9 +925,6 @@ "sendAmount": { "message": "Enviar Quantia" }, - "sendETH": { - "message": "Enviar ETH" - }, "sendTokens": { "message": "Enviar Tokens" }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index d29f98239..e697a4227 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -924,9 +924,6 @@ "sendAmount": { "message": "Suma trimisă" }, - "sendETH": { - "message": "Trimitere ETH" - }, "sendTokens": { "message": "Trimiteți indicative" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 697abea15..42f94bae9 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -1404,9 +1404,6 @@ "sendAmount": { "message": "Отправить сумму" }, - "sendETH": { - "message": "Отправить ETH" - }, "sendSpecifiedTokens": { "message": "Отправить $1", "description": "Symbol of the specified token" diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 3124751fb..5d2cb5be7 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -900,9 +900,6 @@ "sendAmount": { "message": "Poslať sumu" }, - "sendETH": { - "message": "Odeslat ETH" - }, "sendTokens": { "message": "Odeslat tokeny" }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index f2fc5b566..6cb1434df 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -919,9 +919,6 @@ "sendAmount": { "message": "Pošlji znesek" }, - "sendETH": { - "message": "Pošlji ETH" - }, "sendTokens": { "message": "Pošlji žetone" }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index fcf6cf06e..1409dc795 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -928,9 +928,6 @@ "sendAmount": { "message": "Pošaljite iznos" }, - "sendETH": { - "message": "Pošalji ETH" - }, "sendTokens": { "message": "Pošalji tokene" }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index f961555dc..c9552fa0b 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -921,9 +921,6 @@ "sendAmount": { "message": "Skicka belopp" }, - "sendETH": { - "message": "Skicka ETH" - }, "sendTokens": { "message": "Skicka tokens" }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 3176cc28d..6bd385ad9 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -915,9 +915,6 @@ "sendAmount": { "message": "Tuma Kiasi" }, - "sendETH": { - "message": "Tuma ETH" - }, "sendTokens": { "message": "Tuma Vianzio" }, diff --git a/app/_locales/ta/messages.json b/app/_locales/ta/messages.json index 09b0b87bb..58f48caab 100644 --- a/app/_locales/ta/messages.json +++ b/app/_locales/ta/messages.json @@ -438,9 +438,6 @@ "send": { "message": "அனுப்பு" }, - "sendETH": { - "message": "ETH ஐ அனுப்பு" - }, "sendTokens": { "message": "டோக்கன்களை அனுப்பவும்" }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index b0df95826..02b3ff61f 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -441,9 +441,6 @@ "sendAmount": { "message": "ส่งจำนวนเงินนี้" }, - "sendETH": { - "message": "ส่งอีเธอร์" - }, "sendTokens": { "message": "ส่งโทเค็น" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index f35d6ae6a..8b9ecb5fc 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -1401,9 +1401,6 @@ "sendAmount": { "message": "Halaga ng Ipapadala" }, - "sendETH": { - "message": "Magpadala ng ETH" - }, "sendSpecifiedTokens": { "message": "Magpadala ng $1", "description": "Symbol of the specified token" diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 4b71110d0..b6ebceed0 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -378,9 +378,6 @@ "send": { "message": "Gönder" }, - "sendETH": { - "message": "ETH Gönder" - }, "sendTokens": { "message": "Jeton Gönder" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index 8f499bc2f..ef54267bb 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -937,9 +937,6 @@ "sendAmount": { "message": "Надіслати суму" }, - "sendETH": { - "message": "Надіслати ETH" - }, "sendTokens": { "message": "Надіслати токени" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index da2e8d5b5..dc0592c75 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -1404,9 +1404,6 @@ "sendAmount": { "message": "Gửi khoản tiền" }, - "sendETH": { - "message": "Gửi ETH" - }, "sendSpecifiedTokens": { "message": "Gửi $1", "description": "Symbol of the specified token" diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 09c370050..26724aa42 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -1413,9 +1413,6 @@ "sendAmount": { "message": "发送数额" }, - "sendETH": { - "message": "发送 ETH" - }, "sendSpecifiedTokens": { "message": "发送 $1", "description": "Symbol of the specified token" diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index d724a8647..a88f2fe65 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -925,9 +925,6 @@ "sendAmount": { "message": "發送數量" }, - "sendETH": { - "message": "發送以太幣" - }, "sendTokens": { "message": "發送代幣" }, diff --git a/ui/app/hooks/useTransactionDisplayData.js b/ui/app/hooks/useTransactionDisplayData.js index 370516170..ffdda4660 100644 --- a/ui/app/hooks/useTransactionDisplayData.js +++ b/ui/app/hooks/useTransactionDisplayData.js @@ -208,7 +208,7 @@ export function useTransactionDisplayData(transactionGroup) { subtitle = t('toAddress', [shortenAddress(recipientAddress)]); } else if (type === TRANSACTION_TYPES.SENT_ETHER) { category = TRANSACTION_GROUP_CATEGORIES.SEND; - title = t('sendETH'); + title = t('send'); subtitle = t('toAddress', [shortenAddress(recipientAddress)]); } diff --git a/ui/app/hooks/useTransactionDisplayData.test.js b/ui/app/hooks/useTransactionDisplayData.test.js index 76dca1bcd..572c8e99b 100644 --- a/ui/app/hooks/useTransactionDisplayData.test.js +++ b/ui/app/hooks/useTransactionDisplayData.test.js @@ -28,7 +28,7 @@ import { useTransactionDisplayData } from './useTransactionDisplayData'; const expectedResults = [ { - title: 'Send ETH', + title: 'Send', category: TRANSACTION_GROUP_CATEGORIES.SEND, subtitle: 'To: 0xffe5...1a97', subtitleContainsOrigin: false, @@ -42,7 +42,7 @@ const expectedResults = [ isSubmitted: false, }, { - title: 'Send ETH', + title: 'Send', category: TRANSACTION_GROUP_CATEGORIES.SEND, subtitle: 'To: 0x0ccc...8848', subtitleContainsOrigin: false, @@ -55,7 +55,7 @@ const expectedResults = [ displayedStatusKey: TRANSACTION_STATUSES.CONFIRMED, }, { - title: 'Send ETH', + title: 'Send', category: TRANSACTION_GROUP_CATEGORIES.SEND, subtitle: 'To: 0xffe5...1a97', subtitleContainsOrigin: false, diff --git a/ui/app/selectors/send.js b/ui/app/selectors/send.js index fad9b7275..d6f291c9f 100644 --- a/ui/app/selectors/send.js +++ b/ui/app/selectors/send.js @@ -154,7 +154,7 @@ export function getTitleKey(state) { } else if (isToken) { return 'sendTokens'; } - return 'sendETH'; + return 'send'; } export function isSendFormInError(state) { diff --git a/ui/app/selectors/send.test.js b/ui/app/selectors/send.test.js index f44a54b67..dccedfc2b 100644 --- a/ui/app/selectors/send.test.js +++ b/ui/app/selectors/send.test.js @@ -491,7 +491,7 @@ describe('send selectors', function () { token: null, }), ), - 'sendETH', + 'send', ); }); }); From 530e8c132fbac85d96709e83bbce60a7a2d4d738 Mon Sep 17 00:00:00 2001 From: ryanml Date: Fri, 19 Mar 2021 10:17:39 -0700 Subject: [PATCH 24/82] Fixing incorrectly typed token decimal attribute (#10666) --- app/scripts/controllers/preferences.js | 2 +- app/scripts/migrations/054.js | 75 +++ app/scripts/migrations/054.test.js | 687 +++++++++++++++++++++++++ app/scripts/migrations/index.js | 1 + 4 files changed, 764 insertions(+), 1 deletion(-) create mode 100644 app/scripts/migrations/054.js create mode 100644 app/scripts/migrations/054.test.js diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 240aaaa18..fba7a400a 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -378,7 +378,7 @@ export default class PreferencesController { */ async addToken(rawAddress, symbol, decimals, image) { const address = normalizeAddress(rawAddress); - const newEntry = { address, symbol, decimals }; + const newEntry = { address, symbol, decimals: Number(decimals) }; const { tokens, hiddenTokens } = this.store.getState(); const assetImages = this.getAssetImages(); const updatedHiddenTokens = hiddenTokens.filter( diff --git a/app/scripts/migrations/054.js b/app/scripts/migrations/054.js new file mode 100644 index 000000000..105a46750 --- /dev/null +++ b/app/scripts/migrations/054.js @@ -0,0 +1,75 @@ +import { cloneDeep } from 'lodash'; + +const version = 54; + +function isValidDecimals(decimals) { + return ( + typeof decimals === 'number' || + (typeof decimals === 'string' && decimals.match(/^(0x)?\d+$/u)) + ); +} + +/** + * Migrates preference tokens with decimals typed as string to number. + * It also removes any tokens with corrupted or inconvertible decimal values. + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; + }, +}; + +function transformState(state) { + const newState = state; + + if (!newState.PreferencesController) { + return newState; + } + + const tokens = newState.PreferencesController.tokens || []; + // Filter out any tokens with corrupted decimal values + const validTokens = tokens.filter(({ decimals }) => + isValidDecimals(decimals), + ); + for (const token of validTokens) { + // In the case of a decimal value type string, convert to a number. + if (typeof token.decimals === 'string') { + // eslint-disable-next-line radix + token.decimals = parseInt(token.decimals); + } + } + newState.PreferencesController.tokens = validTokens; + + const { accountTokens } = newState.PreferencesController; + if (accountTokens && typeof accountTokens === 'object') { + for (const address of Object.keys(accountTokens)) { + const networkTokens = accountTokens[address]; + if (networkTokens && typeof networkTokens === 'object') { + for (const network of Object.keys(networkTokens)) { + const tokensOnNetwork = networkTokens[network] || []; + // Filter out any tokens with corrupted decimal values + const validTokensOnNetwork = tokensOnNetwork.filter(({ decimals }) => + isValidDecimals(decimals), + ); + // In the case of a decimal value type string, convert to a number. + for (const token of validTokensOnNetwork) { + if (typeof token.decimals === 'string') { + // eslint-disable-next-line radix + token.decimals = parseInt(token.decimals); + } + } + networkTokens[network] = validTokensOnNetwork; + } + } + } + } + newState.PreferencesController.accountTokens = accountTokens; + + return newState; +} diff --git a/app/scripts/migrations/054.test.js b/app/scripts/migrations/054.test.js new file mode 100644 index 000000000..b0d78bcfd --- /dev/null +++ b/app/scripts/migrations/054.test.js @@ -0,0 +1,687 @@ +import { strict as assert } from 'assert'; +import { + MAINNET_CHAIN_ID, + ROPSTEN_CHAIN_ID, +} from '../../../shared/constants/network'; +import migration54 from './054'; + +describe('migration #54', function () { + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 53, + }, + data: {}, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.meta, { + version: 54, + }); + }); + + it('should retype instance of 0 decimal values to numbers [tokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + accountTokens: [], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + accountTokens: [], + }, + }); + }); + + it('should do nothing if all decimal value typings are correct [tokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + accountTokens: [], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + accountTokens: [], + }, + }); + }); + + it('should retype instance of 0 decimal values to numbers [accountTokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + }, + tokens: [], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + }, + tokens: [], + }, + }); + }); + + it('should do nothing if all decimal value typings are correct [accountTokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + }, + tokens: [], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + }, + tokens: [], + }, + }); + }); + + it('should retype instance of 0 decimal values to numbers [accountTokens and tokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + }, + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + }, + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + }); + }); + + it('should retype instance of 0 decimal values to numbers, and remove tokens with corrupted decimal values [accountTokens and tokens]', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '0', + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 'corrupted_decimal?', + symbol: 'SOR', + }, + ], + }, + }, + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: '0', + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: '18xx', + symbol: 'SOR', + }, + ], + }, + }, + }; + + const newStorage = await migration54.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + PreferencesController: { + accountTokens: { + '0x1111': { + [MAINNET_CHAIN_ID]: [ + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + { + address: '0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205', + decimals: 0, + symbol: 'SOR', + }, + ], + }, + '0x1112': { + [ROPSTEN_CHAIN_ID]: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + ], + }, + }, + tokens: [ + { + address: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + decimals: 0, + symbol: 'CK', + }, + { + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + decimals: 18, + symbol: 'BAT', + }, + { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + decimals: 18, + symbol: 'LINK', + }, + ], + }, + }); + }); +}); diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index b30410202..00565e4d8 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -58,6 +58,7 @@ const migrations = [ require('./051').default, require('./052').default, require('./053').default, + require('./054').default, ]; export default migrations; From a81629e104675f46b4b3cbd87201cd98db315b15 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Fri, 19 Mar 2021 16:54:30 -0500 Subject: [PATCH 25/82] refactor incoming tx controller (#10639) --- app/scripts/background.js | 16 +- .../controllers/incoming-transactions.js | 287 +++--- .../controllers/incoming-transactions.test.js | 875 +++++++----------- app/scripts/lib/setupSentry.js | 2 +- app/scripts/metamask-controller.js | 8 +- app/scripts/migrations/055.js | 32 + app/scripts/migrations/055.test.js | 96 ++ app/scripts/migrations/index.js | 1 + shared/constants/transaction.js | 54 ++ 9 files changed, 674 insertions(+), 697 deletions(-) create mode 100644 app/scripts/migrations/055.js create mode 100644 app/scripts/migrations/055.test.js diff --git a/app/scripts/background.js b/app/scripts/background.js index 44bcab288..963f71daf 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -70,21 +70,7 @@ if (inTest || process.env.METAMASK_DEBUG) { initialize().catch(log.error); /** - * An object representing a transaction, in whatever state it is in. - * @typedef TransactionMeta - * - * @property {number} id - An internally unique tx identifier. - * @property {number} time - Time the tx was first suggested, in unix epoch time (ms). - * @property {string} status - The current transaction status (unapproved, signed, submitted, dropped, failed, rejected), as defined in `tx-state-manager.js`. - * @property {string} metamaskNetworkId - The transaction's network ID, used for EIP-155 compliance. - * @property {boolean} loadingDefaults - TODO: Document - * @property {Object} txParams - The tx params as passed to the network provider. - * @property {Object[]} history - A history of mutations to this TransactionMeta object. - * @property {string} origin - A string representing the interface that suggested the transaction. - * @property {Object} nonceDetails - A metadata object containing information used to derive the suggested nonce, useful for debugging nonce issues. - * @property {string} rawTx - A hex string of the final signed transaction, ready to submit to the network. - * @property {string} hash - A hex string of the transaction hash, used to identify the transaction on the network. - * @property {number} submittedTime - The time the transaction was submitted to the network, in Unix epoch time (ms). + * @typedef {import('../../shared/constants/transaction').TransactionMeta} TransactionMeta */ /** diff --git a/app/scripts/controllers/incoming-transactions.js b/app/scripts/controllers/incoming-transactions.js index 61958fc88..7aa621898 100644 --- a/app/scripts/controllers/incoming-transactions.js +++ b/app/scripts/controllers/incoming-transactions.js @@ -12,21 +12,37 @@ import { import { CHAIN_ID_TO_NETWORK_ID_MAP, CHAIN_ID_TO_TYPE_MAP, - GOERLI, GOERLI_CHAIN_ID, - KOVAN, KOVAN_CHAIN_ID, - MAINNET, MAINNET_CHAIN_ID, - RINKEBY, RINKEBY_CHAIN_ID, - ROPSTEN, ROPSTEN_CHAIN_ID, } from '../../../shared/constants/network'; -import { NETWORK_EVENTS } from './network'; const fetchWithTimeout = getFetchWithTimeout(30000); +/** + * @typedef {import('../../../shared/constants/transaction').TransactionMeta} TransactionMeta + */ + +/** + * A transaction object in the format returned by the Etherscan API. + * + * Note that this is not an exhaustive type definiton; only the properties we use are defined + * + * @typedef {Object} EtherscanTransaction + * @property {string} blockNumber - The number of the block this transaction was found in, in decimal + * @property {string} from - The hex-prefixed address of the sender + * @property {string} gas - The gas limit, in decimal WEI + * @property {string} gasPrice - The gas price, in decimal WEI + * @property {string} hash - The hex-prefixed transaction hash + * @property {string} isError - Whether the transaction was confirmed or failed (0 for confirmed, 1 for failed) + * @property {string} nonce - The transaction nonce, in decimal + * @property {string} timeStamp - The timestamp for the transaction, in seconds + * @property {string} to - The hex-prefixed address of the recipient + * @property {string} value - The amount of ETH sent in this transaction, in decimal WEI + */ + /** * This controller is responsible for retrieving incoming transactions. Etherscan is polled once every block to check * for new incoming transactions for the current selected account on the current network @@ -44,35 +60,37 @@ const etherscanSupportedNetworks = [ export default class IncomingTransactionsController { constructor(opts = {}) { - const { blockTracker, networkController, preferencesController } = opts; + const { + blockTracker, + onNetworkDidChange, + getCurrentChainId, + preferencesController, + } = opts; this.blockTracker = blockTracker; - this.networkController = networkController; + this.getCurrentChainId = getCurrentChainId; this.preferencesController = preferencesController; this._onLatestBlock = async (newBlockNumberHex) => { const selectedAddress = this.preferencesController.getSelectedAddress(); const newBlockNumberDec = parseInt(newBlockNumberHex, 16); - await this._update({ - address: selectedAddress, - newBlockNumberDec, - }); + await this._update(selectedAddress, newBlockNumberDec); }; const initState = { incomingTransactions: {}, - incomingTxLastFetchedBlocksByNetwork: { - [GOERLI]: null, - [KOVAN]: null, - [MAINNET]: null, - [RINKEBY]: null, - [ROPSTEN]: null, + incomingTxLastFetchedBlockByChainId: { + [GOERLI_CHAIN_ID]: null, + [KOVAN_CHAIN_ID]: null, + [MAINNET_CHAIN_ID]: null, + [RINKEBY_CHAIN_ID]: null, + [ROPSTEN_CHAIN_ID]: null, }, ...opts.initState, }; this.store = new ObservableStore(initState); this.preferencesController.store.subscribe( - pairwise((prevState, currState) => { + previousValueComparator((prevState, currState) => { const { featureFlags: { showIncomingTransactions: prevShowIncomingTransactions, @@ -94,29 +112,24 @@ export default class IncomingTransactionsController { } this.start(); - }), + }, this.preferencesController.store.getState()), ); this.preferencesController.store.subscribe( - pairwise(async (prevState, currState) => { + previousValueComparator(async (prevState, currState) => { const { selectedAddress: prevSelectedAddress } = prevState; const { selectedAddress: currSelectedAddress } = currState; if (currSelectedAddress === prevSelectedAddress) { return; } - - await this._update({ - address: currSelectedAddress, - }); - }), + await this._update(currSelectedAddress); + }, this.preferencesController.store.getState()), ); - this.networkController.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, async () => { + onNetworkDidChange(async () => { const address = this.preferencesController.getSelectedAddress(); - await this._update({ - address, - }); + await this._update(address); }); } @@ -136,85 +149,79 @@ export default class IncomingTransactionsController { this.blockTracker.removeListener('latest', this._onLatestBlock); } - async _update({ address, newBlockNumberDec } = {}) { - const chainId = this.networkController.getCurrentChainId(); - if (!etherscanSupportedNetworks.includes(chainId)) { + /** + * Determines the correct block number to begin looking for new transactions + * from, fetches the transactions and then saves them and the next block + * number to begin fetching from in state. Block numbers and transactions are + * stored per chainId. + * @private + * @param {string} address - address to lookup transactions for + * @param {number} [newBlockNumberDec] - block number to begin fetching from + * @returns {void} + */ + async _update(address, newBlockNumberDec) { + const chainId = this.getCurrentChainId(); + if (!etherscanSupportedNetworks.includes(chainId) || !address) { return; } try { - const dataForUpdate = await this._getDataForUpdate({ + const currentState = this.store.getState(); + const currentBlock = parseInt(this.blockTracker.getCurrentBlock(), 16); + + const mostRecentlyFetchedBlock = + currentState.incomingTxLastFetchedBlockByChainId[chainId]; + const blockToFetchFrom = + mostRecentlyFetchedBlock ?? newBlockNumberDec ?? currentBlock; + + const newIncomingTxs = await this._getNewIncomingTransactions( address, + blockToFetchFrom, chainId, - newBlockNumberDec, + ); + + let newMostRecentlyFetchedBlock = blockToFetchFrom; + + newIncomingTxs.forEach((tx) => { + if ( + tx.blockNumber && + parseInt(newMostRecentlyFetchedBlock, 10) < + parseInt(tx.blockNumber, 10) + ) { + newMostRecentlyFetchedBlock = parseInt(tx.blockNumber, 10); + } + }); + + this.store.updateState({ + incomingTxLastFetchedBlockByChainId: { + ...currentState.incomingTxLastFetchedBlockByChainId, + [chainId]: newMostRecentlyFetchedBlock + 1, + }, + incomingTransactions: newIncomingTxs.reduce( + (transactions, tx) => { + transactions[tx.hash] = tx; + return transactions; + }, + { + ...currentState.incomingTransactions, + }, + ), }); - this._updateStateWithNewTxData(dataForUpdate); } catch (err) { log.error(err); } } - async _getDataForUpdate({ address, chainId, newBlockNumberDec } = {}) { - const { - incomingTransactions: currentIncomingTxs, - incomingTxLastFetchedBlocksByNetwork: currentBlocksByNetwork, - } = this.store.getState(); - - const lastFetchBlockByCurrentNetwork = - currentBlocksByNetwork[CHAIN_ID_TO_TYPE_MAP[chainId]]; - let blockToFetchFrom = lastFetchBlockByCurrentNetwork || newBlockNumberDec; - if (blockToFetchFrom === undefined) { - blockToFetchFrom = parseInt(this.blockTracker.getCurrentBlock(), 16); - } - - const { latestIncomingTxBlockNumber, txs: newTxs } = await this._fetchAll( - address, - blockToFetchFrom, - chainId, - ); - - return { - latestIncomingTxBlockNumber, - newTxs, - currentIncomingTxs, - currentBlocksByNetwork, - fetchedBlockNumber: blockToFetchFrom, - chainId, - }; - } - - _updateStateWithNewTxData({ - latestIncomingTxBlockNumber, - newTxs, - currentIncomingTxs, - currentBlocksByNetwork, - fetchedBlockNumber, - chainId, - }) { - const newLatestBlockHashByNetwork = latestIncomingTxBlockNumber - ? parseInt(latestIncomingTxBlockNumber, 10) + 1 - : fetchedBlockNumber + 1; - const newIncomingTransactions = { - ...currentIncomingTxs, - }; - newTxs.forEach((tx) => { - newIncomingTransactions[tx.hash] = tx; - }); - - this.store.updateState({ - incomingTxLastFetchedBlocksByNetwork: { - ...currentBlocksByNetwork, - [CHAIN_ID_TO_TYPE_MAP[chainId]]: newLatestBlockHashByNetwork, - }, - incomingTransactions: newIncomingTransactions, - }); - } - - async _fetchAll(address, fromBlock, chainId) { - const fetchedTxResponse = await this._fetchTxs(address, fromBlock, chainId); - return this._processTxFetchResponse(fetchedTxResponse); - } - - async _fetchTxs(address, fromBlock, chainId) { + /** + * fetches transactions for the given address and chain, via etherscan, then + * processes the data into the necessary shape for usage in this controller. + * + * @private + * @param {string} [address] - Address to fetch transactions for + * @param {number} [fromBlock] - Block to look for transactions at + * @param {string} [chainId] - The chainId for the current network + * @returns {TransactionMeta[]} + */ + async _getNewIncomingTransactions(address, fromBlock, chainId) { const etherscanSubdomain = chainId === MAINNET_CHAIN_ID ? 'api' @@ -227,16 +234,8 @@ export default class IncomingTransactionsController { url += `&startBlock=${parseInt(fromBlock, 10)}`; } const response = await fetchWithTimeout(url); - const parsedResponse = await response.json(); - - return { - ...parsedResponse, - address, - chainId, - }; - } - - _processTxFetchResponse({ status, result = [], address, chainId }) { + const { status, result } = await response.json(); + let newIncomingTxs = []; if (status === '1' && Array.isArray(result) && result.length > 0) { const remoteTxList = {}; const remoteTxs = []; @@ -247,70 +246,70 @@ export default class IncomingTransactionsController { } }); - const incomingTxs = remoteTxs.filter( + newIncomingTxs = remoteTxs.filter( (tx) => tx.txParams?.to?.toLowerCase() === address.toLowerCase(), ); - incomingTxs.sort((a, b) => (a.time < b.time ? -1 : 1)); - - let latestIncomingTxBlockNumber = null; - incomingTxs.forEach((tx) => { - if ( - tx.blockNumber && - (!latestIncomingTxBlockNumber || - parseInt(latestIncomingTxBlockNumber, 10) < - parseInt(tx.blockNumber, 10)) - ) { - latestIncomingTxBlockNumber = tx.blockNumber; - } - }); - return { - latestIncomingTxBlockNumber, - txs: incomingTxs, - }; + newIncomingTxs.sort((a, b) => (a.time < b.time ? -1 : 1)); } - return { - latestIncomingTxBlockNumber: null, - txs: [], - }; + return newIncomingTxs; } - _normalizeTxFromEtherscan(txMeta, chainId) { - const time = parseInt(txMeta.timeStamp, 10) * 1000; + /** + * Transmutes a EtherscanTransaction into a TransactionMeta + * @param {EtherscanTransaction} etherscanTransaction - the transaction to normalize + * @param {string} chainId - The chainId of the current network + * @returns {TransactionMeta} + */ + _normalizeTxFromEtherscan(etherscanTransaction, chainId) { + const time = parseInt(etherscanTransaction.timeStamp, 10) * 1000; const status = - txMeta.isError === '0' + etherscanTransaction.isError === '0' ? TRANSACTION_STATUSES.CONFIRMED : TRANSACTION_STATUSES.FAILED; return { - blockNumber: txMeta.blockNumber, + blockNumber: etherscanTransaction.blockNumber, id: createId(), chainId, metamaskNetworkId: CHAIN_ID_TO_NETWORK_ID_MAP[chainId], status, time, txParams: { - from: txMeta.from, - gas: bnToHex(new BN(txMeta.gas)), - gasPrice: bnToHex(new BN(txMeta.gasPrice)), - nonce: bnToHex(new BN(txMeta.nonce)), - to: txMeta.to, - value: bnToHex(new BN(txMeta.value)), + from: etherscanTransaction.from, + gas: bnToHex(new BN(etherscanTransaction.gas)), + gasPrice: bnToHex(new BN(etherscanTransaction.gasPrice)), + nonce: bnToHex(new BN(etherscanTransaction.nonce)), + to: etherscanTransaction.to, + value: bnToHex(new BN(etherscanTransaction.value)), }, - hash: txMeta.hash, + hash: etherscanTransaction.hash, type: TRANSACTION_TYPES.INCOMING, }; } } -function pairwise(fn) { +/** + * Returns a function with arity 1 that caches the argument that the function + * is called with and invokes the comparator with both the cached, previous, + * value and the current value. If specified, the initialValue will be passed + * in as the previous value on the first invocation of the returned method. + * @template A + * @params {A=} type of compared value + * @param {(prevValue: A, nextValue: A) => void} comparator - method to compare + * previous and next values. + * @param {A} [initialValue] - initial value to supply to prevValue + * on first call of the method. + * @returns {void} + */ +function previousValueComparator(comparator, initialValue) { let first = true; let cache; return (value) => { try { if (first) { first = false; - return fn(value, value); + return comparator(initialValue ?? value, value); } - return fn(cache, value); + return comparator(cache, value); } finally { cache = value; } diff --git a/app/scripts/controllers/incoming-transactions.test.js b/app/scripts/controllers/incoming-transactions.test.js index a50c1df64..74aaad78c 100644 --- a/app/scripts/controllers/incoming-transactions.test.js +++ b/app/scripts/controllers/incoming-transactions.test.js @@ -6,20 +6,19 @@ import { cloneDeep } from 'lodash'; import waitUntilCalled from '../../../test/lib/wait-until-called'; import { - GOERLI, - KOVAN, - MAINNET, + CHAIN_ID_TO_TYPE_MAP, + GOERLI_CHAIN_ID, + KOVAN_CHAIN_ID, MAINNET_CHAIN_ID, - RINKEBY, - ROPSTEN, + RINKEBY_CHAIN_ID, ROPSTEN_CHAIN_ID, ROPSTEN_NETWORK_ID, + ROPSTEN, } from '../../../shared/constants/network'; import { TRANSACTION_TYPES, TRANSACTION_STATUSES, } from '../../../shared/constants/transaction'; -import { NETWORK_EVENTS } from './network'; const IncomingTransactionsController = proxyquire('./incoming-transactions', { '../../../shared/modules/random-id': { default: () => 54321 }, @@ -29,38 +28,43 @@ const FAKE_CHAIN_ID = '0x1338'; const MOCK_SELECTED_ADDRESS = '0x0101'; const SET_STATE_TIMEOUT = 10; +const EXISTING_INCOMING_TX = { id: 777, hash: '0x123456' }; +const PREPOPULATED_INCOMING_TXS_BY_HASH = { + [EXISTING_INCOMING_TX.hash]: EXISTING_INCOMING_TX, +}; +const PREPOPULATED_BLOCKS_BY_NETWORK = { + [GOERLI_CHAIN_ID]: 1, + [KOVAN_CHAIN_ID]: 2, + [MAINNET_CHAIN_ID]: 3, + [RINKEBY_CHAIN_ID]: 5, + [ROPSTEN_CHAIN_ID]: 4, +}; +const EMPTY_BLOCKS_BY_NETWORK = { + [GOERLI_CHAIN_ID]: null, + [KOVAN_CHAIN_ID]: null, + [MAINNET_CHAIN_ID]: null, + [RINKEBY_CHAIN_ID]: null, + [ROPSTEN_CHAIN_ID]: null, +}; + function getEmptyInitState() { return { incomingTransactions: {}, - incomingTxLastFetchedBlocksByNetwork: { - [GOERLI]: null, - [KOVAN]: null, - [MAINNET]: null, - [RINKEBY]: null, - [ROPSTEN]: null, - }, + incomingTxLastFetchedBlockByChainId: EMPTY_BLOCKS_BY_NETWORK, }; } function getNonEmptyInitState() { return { - incomingTransactions: { - '0x123456': { id: 777 }, - }, - incomingTxLastFetchedBlocksByNetwork: { - [GOERLI]: 1, - [KOVAN]: 2, - [MAINNET]: 3, - [RINKEBY]: 5, - [ROPSTEN]: 4, - }, + incomingTransactions: PREPOPULATED_INCOMING_TXS_BY_HASH, + incomingTxLastFetchedBlockByChainId: PREPOPULATED_BLOCKS_BY_NETWORK, }; } -function getMockNetworkController(chainId = FAKE_CHAIN_ID) { +function getMockNetworkControllerMethods(chainId = FAKE_CHAIN_ID) { return { getCurrentChainId: () => chainId, - on: sinon.spy(), + onNetworkDidChange: sinon.spy(), }; } @@ -90,21 +94,9 @@ function getMockBlockTracker() { } /** - * A transaction object in the format returned by the Etherscan API. - * - * Note that this is not an exhaustive type definiton; only the properties we use are defined - * - * @typedef {Object} EtherscanTransaction - * @property {string} blockNumber - The number of the block this transaction was found in, in decimal - * @property {string} from - The hex-prefixed address of the sender - * @property {string} gas - The gas limit, in decimal WEI - * @property {string} gasPrice - The gas price, in decimal WEI - * @property {string} hash - The hex-prefixed transaction hash - * @property {string} isError - Whether the transaction was confirmed or failed (0 for confirmed, 1 for failed) - * @property {string} nonce - The transaction nonce, in decimal - * @property {string} timeStamp - The timestamp for the transaction, in seconds - * @property {string} to - The hex-prefixed address of the recipient - * @property {string} value - The amount of ETH sent in this transaction, in decimal WEI + * @typedef {import( + * '../../../../app/scripts/controllers/incoming-transactions' + * ).EtherscanTransaction} EtherscanTransaction */ /** @@ -133,6 +125,25 @@ const getFakeEtherscanTransaction = ( }; }; +function nockEtherscanApiForAllChains(mockResponse) { + for (const chainId of [ + GOERLI_CHAIN_ID, + KOVAN_CHAIN_ID, + MAINNET_CHAIN_ID, + RINKEBY_CHAIN_ID, + ROPSTEN_CHAIN_ID, + 'undefined', + ]) { + nock( + `https://api${ + chainId === MAINNET_CHAIN_ID ? '' : `-${CHAIN_ID_TO_TYPE_MAP[chainId]}` + }.etherscan.io`, + ) + .get(/api.+/u) + .reply(200, JSON.stringify(mockResponse)); + } +} + describe('IncomingTransactionsController', function () { afterEach(function () { sinon.restore(); @@ -141,37 +152,32 @@ describe('IncomingTransactionsController', function () { describe('constructor', function () { it('should set up correct store, listeners and properties in the constructor', function () { + const mockedNetworkMethods = getMockNetworkControllerMethods(); const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(), + ...mockedNetworkMethods, preferencesController: getMockPreferencesController(), initState: {}, }, ); sinon.spy(incomingTransactionsController, '_update'); - assert.deepEqual( + assert.deepStrictEqual( incomingTransactionsController.store.getState(), getEmptyInitState(), ); - assert(incomingTransactionsController.networkController.on.calledOnce); - assert.equal( - incomingTransactionsController.networkController.on.getCall(0).args[0], - NETWORK_EVENTS.NETWORK_DID_CHANGE, - ); - const networkControllerListenerCallback = incomingTransactionsController.networkController.on.getCall( + assert(mockedNetworkMethods.onNetworkDidChange.calledOnce); + const networkControllerListenerCallback = mockedNetworkMethods.onNetworkDidChange.getCall( 0, - ).args[1]; - assert.equal(incomingTransactionsController._update.callCount, 0); + ).args[0]; + assert.strictEqual(incomingTransactionsController._update.callCount, 0); networkControllerListenerCallback('testNetworkType'); - assert.equal(incomingTransactionsController._update.callCount, 1); - assert.deepEqual( + assert.strictEqual(incomingTransactionsController._update.callCount, 1); + assert.deepStrictEqual( incomingTransactionsController._update.getCall(0).args[0], - { - address: '0x0101', - }, + '0x0101', ); incomingTransactionsController._update.resetHistory(); @@ -181,13 +187,13 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(), + ...getMockNetworkControllerMethods(), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - assert.deepEqual( + assert.deepStrictEqual( incomingTransactionsController.store.getState(), getNonEmptyInitState(), ); @@ -199,7 +205,7 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(), + ...getMockNetworkControllerMethods(), preferencesController: getMockPreferencesController(), initState: {}, }, @@ -210,7 +216,7 @@ describe('IncomingTransactionsController', function () { assert( incomingTransactionsController.blockTracker.addListener.calledOnce, ); - assert.equal( + assert.strictEqual( incomingTransactionsController.blockTracker.addListener.getCall(0) .args[0], 'latest', @@ -221,13 +227,13 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; + .incomingTxLastFetchedBlockByChainId[ROPSTEN_CHAIN_ID]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -284,9 +290,9 @@ describe('IncomingTransactionsController', function () { }, }, }, - incomingTxLastFetchedBlocksByNetwork: { - ...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork, - [ROPSTEN]: 11, + incomingTxLastFetchedBlockByChainId: { + ...getNonEmptyInitState().incomingTxLastFetchedBlockByChainId, + [ROPSTEN_CHAIN_ID]: 11, }, }, 'State should have been updated after first block was received', @@ -297,34 +303,17 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(), + ...getMockNetworkControllerMethods(), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction()], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction()], + }); + const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -362,7 +351,7 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(), + ...getMockNetworkControllerMethods(), preferencesController: getMockPreferencesController({ showIncomingTransactions: false, }), @@ -370,28 +359,10 @@ describe('IncomingTransactionsController', function () { }, ); // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction()], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction()], + }); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -429,34 +400,16 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction()], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction()], + }); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -492,34 +445,16 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction()], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction()], + }); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -557,14 +492,14 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9`; const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; + .incomingTxLastFetchedBlockByChainId[ROPSTEN_CHAIN_ID]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${NEW_MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -628,9 +563,9 @@ describe('IncomingTransactionsController', function () { }, }, }, - incomingTxLastFetchedBlocksByNetwork: { - ...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork, - [ROPSTEN]: 11, + incomingTxLastFetchedBlockByChainId: { + ...getNonEmptyInitState().incomingTxLastFetchedBlockByChainId, + [ROPSTEN_CHAIN_ID]: 11, }, }, 'State should have been updated after first block was received', @@ -641,35 +576,17 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: { ...getMockBlockTracker() }, - networkController: getMockNetworkController(), + ...getMockNetworkControllerMethods(), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9`; // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction(NEW_MOCK_SELECTED_ADDRESS)], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction(NEW_MOCK_SELECTED_ADDRESS)], + }); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -711,16 +628,19 @@ describe('IncomingTransactionsController', function () { }); it('should update when switching to a supported network', async function () { + const mockedNetworkMethods = getMockNetworkControllerMethods( + ROPSTEN_CHAIN_ID, + ); const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...mockedNetworkMethods, preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; + .incomingTxLastFetchedBlockByChainId[ROPSTEN_CHAIN_ID]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -741,13 +661,9 @@ describe('IncomingTransactionsController', function () { incomingTransactionsController.store, ); - const subscription = incomingTransactionsController.networkController.on.getCall( - 0, - ).args[1]; - incomingTransactionsController.networkController = getMockNetworkController( - ROPSTEN_CHAIN_ID, - ); - await subscription(ROPSTEN); + const subscription = mockedNetworkMethods.onNetworkDidChange.getCall(0) + .args[0]; + await subscription(ROPSTEN_CHAIN_ID); await updateStateCalled(); const actualState = incomingTransactionsController.store.getState(); @@ -783,9 +699,9 @@ describe('IncomingTransactionsController', function () { }, }, }, - incomingTxLastFetchedBlocksByNetwork: { - ...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork, - [ROPSTEN]: 11, + incomingTxLastFetchedBlockByChainId: { + ...getNonEmptyInitState().incomingTxLastFetchedBlockByChainId, + [ROPSTEN_CHAIN_ID]: 11, }, }, 'State should have been updated after first block was received', @@ -793,38 +709,22 @@ describe('IncomingTransactionsController', function () { }); it('should not update when switching to an unsupported network', async function () { - const networkController = getMockNetworkController(ROPSTEN_CHAIN_ID); + const mockedNetworkMethods = getMockNetworkControllerMethods( + ROPSTEN_CHAIN_ID, + ); const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController, + ...mockedNetworkMethods, preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); // reply with a valid request for any supported network, so that this test has every opportunity to fail - for (const network of [ - GOERLI, - KOVAN, - MAINNET, - RINKEBY, - ROPSTEN, - 'undefined', - ]) { - nock( - `https://api${ - network === MAINNET ? '' : `-${network.toLowerCase()}` - }.etherscan.io`, - ) - .get(/api.+/u) - .reply( - 200, - JSON.stringify({ - status: '1', - result: [getFakeEtherscanTransaction()], - }), - ); - } + nockEtherscanApiForAllChains({ + status: '1', + result: [getFakeEtherscanTransaction()], + }); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', @@ -842,11 +742,10 @@ describe('IncomingTransactionsController', function () { incomingTransactionsController.store, ); - const subscription = incomingTransactionsController.networkController.on.getCall( - 0, - ).args[1]; + const subscription = mockedNetworkMethods.onNetworkDidChange.getCall(0) + .args[0]; - networkController.getCurrentChainId = () => FAKE_CHAIN_ID; + incomingTransactionsController.getCurrentChainId = () => FAKE_CHAIN_ID; await subscription(); try { @@ -864,186 +763,200 @@ describe('IncomingTransactionsController', function () { }); }); - describe('_getDataForUpdate', function () { - it('should call fetchAll with the correct params when passed a new block number and the current network has no stored block', async function () { - const incomingTransactionsController = new IncomingTransactionsController( - { - blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), - preferencesController: getMockPreferencesController(), - initState: getEmptyInitState(), - }, - ); - incomingTransactionsController._fetchAll = sinon.stub().returns({}); + describe('_update', function () { + describe('when state is empty (initialized)', function () { + it('should use provided block number and update the latest block seen', async function () { + const incomingTransactionsController = new IncomingTransactionsController( + { + blockTracker: getMockBlockTracker(), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), + preferencesController: getMockPreferencesController(), + initState: getEmptyInitState(), + getCurrentChainId: () => ROPSTEN_CHAIN_ID, + }, + ); + sinon.spy(incomingTransactionsController.store, 'updateState'); - await incomingTransactionsController._getDataForUpdate({ - address: 'fakeAddress', - chainId: ROPSTEN_CHAIN_ID, - newBlockNumberDec: 999, - }); + incomingTransactionsController._getNewIncomingTransactions = sinon + .stub() + .returns([]); - assert(incomingTransactionsController._fetchAll.calledOnce); + await incomingTransactionsController._update('fakeAddress', 999); + assert( + incomingTransactionsController._getNewIncomingTransactions.calledOnce, + ); + assert.deepStrictEqual( + incomingTransactionsController._getNewIncomingTransactions.getCall(0) + .args, + ['fakeAddress', 999, ROPSTEN_CHAIN_ID], + ); + assert.deepStrictEqual( + incomingTransactionsController.store.updateState.getCall(0).args[0], + { + incomingTxLastFetchedBlockByChainId: { + ...EMPTY_BLOCKS_BY_NETWORK, + [ROPSTEN_CHAIN_ID]: 1000, + }, + incomingTransactions: {}, + }, + ); + }); - assert.deepEqual( - incomingTransactionsController._fetchAll.getCall(0).args, - ['fakeAddress', 999, ROPSTEN_CHAIN_ID], - ); - }); + it('should update the last fetched block for network to highest block seen in incoming txs', async function () { + const incomingTransactionsController = new IncomingTransactionsController( + { + blockTracker: getMockBlockTracker(), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), + preferencesController: getMockPreferencesController(), + initState: getEmptyInitState(), + getCurrentChainId: () => ROPSTEN_CHAIN_ID, + }, + ); - it('should call fetchAll with the correct params when passed a new block number but the current network has a stored block', async function () { - const incomingTransactionsController = new IncomingTransactionsController( - { - blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), - preferencesController: getMockPreferencesController(), - initState: getNonEmptyInitState(), - }, - ); - incomingTransactionsController._fetchAll = sinon.stub().returns({}); + const NEW_TRANSACTION_ONE = { + id: 555, + hash: '0xfff', + blockNumber: 444, + }; + const NEW_TRANSACTION_TWO = { + id: 556, + hash: '0xffa', + blockNumber: 443, + }; + + sinon.spy(incomingTransactionsController.store, 'updateState'); + + incomingTransactionsController._getNewIncomingTransactions = sinon + .stub() + .returns([NEW_TRANSACTION_ONE, NEW_TRANSACTION_TWO]); + await incomingTransactionsController._update('fakeAddress', 10); + + assert(incomingTransactionsController.store.updateState.calledOnce); + + assert.deepStrictEqual( + incomingTransactionsController._getNewIncomingTransactions.getCall(0) + .args, + ['fakeAddress', 10, ROPSTEN_CHAIN_ID], + ); - await incomingTransactionsController._getDataForUpdate({ - address: 'fakeAddress', - chainId: ROPSTEN_CHAIN_ID, - newBlockNumberDec: 999, + assert.deepStrictEqual( + incomingTransactionsController.store.updateState.getCall(0).args[0], + { + incomingTxLastFetchedBlockByChainId: { + ...EMPTY_BLOCKS_BY_NETWORK, + [ROPSTEN_CHAIN_ID]: 445, + }, + incomingTransactions: { + [NEW_TRANSACTION_ONE.hash]: NEW_TRANSACTION_ONE, + [NEW_TRANSACTION_TWO.hash]: NEW_TRANSACTION_TWO, + }, + }, + ); }); + }); - assert(incomingTransactionsController._fetchAll.calledOnce); + describe('when state is populated with prior data for network', function () { + it('should use the last fetched block for the current network and increment by 1 in state', async function () { + const incomingTransactionsController = new IncomingTransactionsController( + { + blockTracker: getMockBlockTracker(), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), + preferencesController: getMockPreferencesController(), + initState: getNonEmptyInitState(), + getCurrentChainId: () => ROPSTEN_CHAIN_ID, + }, + ); + sinon.spy(incomingTransactionsController.store, 'updateState'); + incomingTransactionsController._getNewIncomingTransactions = sinon + .stub() + .returns([]); - assert.deepEqual( - incomingTransactionsController._fetchAll.getCall(0).args, - ['fakeAddress', 4, ROPSTEN_CHAIN_ID], - ); - }); + await incomingTransactionsController._update('fakeAddress', 999); - it('should return the expected data', async function () { - const incomingTransactionsController = new IncomingTransactionsController( - { - blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), - preferencesController: getMockPreferencesController(), - initState: getNonEmptyInitState(), - }, - ); - incomingTransactionsController._fetchAll = sinon.stub().returns({ - latestIncomingTxBlockNumber: 444, - txs: [{ id: 555 }], - }); + assert( + incomingTransactionsController._getNewIncomingTransactions.calledOnce, + ); - const result = await incomingTransactionsController._getDataForUpdate({ - address: 'fakeAddress', - chainId: ROPSTEN_CHAIN_ID, - }); + assert.deepStrictEqual( + incomingTransactionsController._getNewIncomingTransactions.getCall(0) + .args, + ['fakeAddress', 4, ROPSTEN_CHAIN_ID], + ); - assert.deepEqual(result, { - latestIncomingTxBlockNumber: 444, - newTxs: [{ id: 555 }], - currentIncomingTxs: { - '0x123456': { id: 777 }, - }, - currentBlocksByNetwork: { - [GOERLI]: 1, - [KOVAN]: 2, - [MAINNET]: 3, - [RINKEBY]: 5, - [ROPSTEN]: 4, - }, - fetchedBlockNumber: 4, - chainId: ROPSTEN_CHAIN_ID, + assert.deepStrictEqual( + incomingTransactionsController.store.updateState.getCall(0).args[0], + { + incomingTxLastFetchedBlockByChainId: { + ...PREPOPULATED_BLOCKS_BY_NETWORK, + [ROPSTEN_CHAIN_ID]: + PREPOPULATED_BLOCKS_BY_NETWORK[ROPSTEN_CHAIN_ID] + 1, + }, + incomingTransactions: PREPOPULATED_INCOMING_TXS_BY_HASH, + }, + ); }); }); - }); - describe('_updateStateWithNewTxData', function () { - const MOCK_INPUT_WITHOUT_LASTEST = { - newTxs: [{ id: 555, hash: '0xfff' }], - currentIncomingTxs: { - '0x123456': { id: 777, hash: '0x123456' }, - }, - currentBlocksByNetwork: { - [GOERLI]: 1, - [KOVAN]: 2, - [MAINNET]: 3, - [RINKEBY]: 5, - [ROPSTEN]: 4, - }, - fetchedBlockNumber: 1111, - chainId: ROPSTEN_CHAIN_ID, - }; - - const MOCK_INPUT_WITH_LASTEST = { - ...MOCK_INPUT_WITHOUT_LASTEST, - latestIncomingTxBlockNumber: 444, - }; - - it('should update state with correct blockhash and transactions when passed a truthy latestIncomingTxBlockNumber', async function () { + it('should update the last fetched block for network to highest block seen in incoming txs', async function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), + getCurrentChainId: () => ROPSTEN_CHAIN_ID, }, ); - sinon.spy(incomingTransactionsController.store, 'updateState'); - - await incomingTransactionsController._updateStateWithNewTxData( - MOCK_INPUT_WITH_LASTEST, - ); - assert(incomingTransactionsController.store.updateState.calledOnce); - - assert.deepEqual( - incomingTransactionsController.store.updateState.getCall(0).args[0], - { - incomingTxLastFetchedBlocksByNetwork: { - ...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork, - [ROPSTEN]: 445, - }, - incomingTransactions: { - '0x123456': { id: 777, hash: '0x123456' }, - '0xfff': { id: 555, hash: '0xfff' }, - }, - }, - ); - }); + const NEW_TRANSACTION_ONE = { + id: 555, + hash: '0xfff', + blockNumber: 444, + }; + const NEW_TRANSACTION_TWO = { + id: 556, + hash: '0xffa', + blockNumber: 443, + }; - it('should update state with correct blockhash and transactions when passed a falsy latestIncomingTxBlockNumber', async function () { - const incomingTransactionsController = new IncomingTransactionsController( - { - blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), - preferencesController: getMockPreferencesController(), - initState: getNonEmptyInitState(), - }, - ); sinon.spy(incomingTransactionsController.store, 'updateState'); - await incomingTransactionsController._updateStateWithNewTxData( - MOCK_INPUT_WITHOUT_LASTEST, - ); + incomingTransactionsController._getNewIncomingTransactions = sinon + .stub() + .returns([NEW_TRANSACTION_ONE, NEW_TRANSACTION_TWO]); + await incomingTransactionsController._update('fakeAddress', 10); assert(incomingTransactionsController.store.updateState.calledOnce); - assert.deepEqual( + assert.deepStrictEqual( + incomingTransactionsController._getNewIncomingTransactions.getCall(0) + .args, + ['fakeAddress', 4, ROPSTEN_CHAIN_ID], + ); + + assert.deepStrictEqual( incomingTransactionsController.store.updateState.getCall(0).args[0], { - incomingTxLastFetchedBlocksByNetwork: { - ...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork, - [ROPSTEN]: 1112, + incomingTxLastFetchedBlockByChainId: { + ...PREPOPULATED_BLOCKS_BY_NETWORK, + [ROPSTEN_CHAIN_ID]: 445, }, incomingTransactions: { - '0x123456': { id: 777, hash: '0x123456' }, - '0xfff': { id: 555, hash: '0xfff' }, + ...PREPOPULATED_INCOMING_TXS_BY_HASH, + [NEW_TRANSACTION_ONE.hash]: NEW_TRANSACTION_ONE, + [NEW_TRANSACTION_TWO.hash]: NEW_TRANSACTION_TWO, }, }, ); }); }); - describe('_fetchTxs', function () { + describe('_getNewIncomingTransactions', function () { + const ADDRESS_TO_FETCH_FOR = '0xfakeaddress'; + const FETCHED_TX = getFakeEtherscanTransaction(ADDRESS_TO_FETCH_FOR); const mockFetch = sinon.stub().returns( Promise.resolve({ - json: () => Promise.resolve({ someKey: 'someValue' }), + json: () => Promise.resolve({ status: '1', result: [FETCHED_TX] }), }), ); let tempFetch; @@ -1057,262 +970,152 @@ describe('IncomingTransactionsController', function () { mockFetch.resetHistory(); }); - it('should call fetch with the expected url when passed an address, block number and supported network', async function () { + it('should call fetch with the expected url when passed an address, block number and supported chainId', async function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - await incomingTransactionsController._fetchTxs( - '0xfakeaddress', + await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, '789', ROPSTEN_CHAIN_ID, ); assert(mockFetch.calledOnce); - assert.equal( + assert.strictEqual( mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`, ); }); - it('should call fetch with the expected url when passed an address, block number and MAINNET', async function () { + it('should call fetch with the expected url when passed an address, block number and MAINNET chainId', async function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(MAINNET_CHAIN_ID), + ...getMockNetworkControllerMethods(MAINNET_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - await incomingTransactionsController._fetchTxs( - '0xfakeaddress', + await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, '789', MAINNET_CHAIN_ID, ); assert(mockFetch.calledOnce); - assert.equal( + assert.strictEqual( mockFetch.getCall(0).args[0], `https://api.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`, ); }); - it('should call fetch with the expected url when passed an address and supported network, but a falsy block number', async function () { + it('should call fetch with the expected url when passed an address and supported chainId, but a falsy block number', async function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - await incomingTransactionsController._fetchTxs( - '0xfakeaddress', + await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, null, ROPSTEN_CHAIN_ID, ); assert(mockFetch.calledOnce); - assert.equal( + assert.strictEqual( mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1`, ); }); - it('should return the results from the fetch call, plus the address and currentNetworkID, when passed an address, block number and supported network', async function () { + it('should return an array of normalized transactions', async function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - const result = await incomingTransactionsController._fetchTxs( - '0xfakeaddress', + const result = await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, '789', ROPSTEN_CHAIN_ID, ); assert(mockFetch.calledOnce); - assert.deepEqual(result, { - someKey: 'someValue', - address: '0xfakeaddress', - chainId: ROPSTEN_CHAIN_ID, - }); + assert.deepStrictEqual(result, [ + incomingTransactionsController._normalizeTxFromEtherscan( + FETCHED_TX, + ROPSTEN_CHAIN_ID, + ), + ]); }); - }); - describe('_processTxFetchResponse', function () { - it('should return a null block number and empty tx array if status is 0', function () { - const incomingTransactionsController = new IncomingTransactionsController( - { - blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), - preferencesController: getMockPreferencesController(), - initState: getNonEmptyInitState(), - }, + it('should return empty tx array if status is 0', async function () { + const mockFetchStatusZero = sinon.stub().returns( + Promise.resolve({ + json: () => Promise.resolve({ status: '0', result: [FETCHED_TX] }), + }), ); - - const result = incomingTransactionsController._processTxFetchResponse({ - status: '0', - result: [{ id: 1 }], - address: '0xfakeaddress', - }); - - assert.deepEqual(result, { - latestIncomingTxBlockNumber: null, - txs: [], - }); - }); - - it('should return a null block number and empty tx array if the passed result array is empty', function () { + const tempFetchStatusZero = window.fetch; + window.fetch = mockFetchStatusZero; const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - const result = incomingTransactionsController._processTxFetchResponse({ - status: '1', - result: [], - address: '0xfakeaddress', - }); - - assert.deepEqual(result, { - latestIncomingTxBlockNumber: null, - txs: [], - }); + const result = await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, + '789', + ROPSTEN_CHAIN_ID, + ); + assert.deepStrictEqual(result, []); + window.fetch = tempFetchStatusZero; + mockFetchStatusZero.reset(); }); - it('should return the expected block number and tx list when passed data from a successful fetch', function () { + it('should return empty tx array if result array is empty', async function () { + const mockFetchEmptyResult = sinon.stub().returns( + Promise.resolve({ + json: () => Promise.resolve({ status: '1', result: [] }), + }), + ); + const tempFetchEmptyResult = window.fetch; + window.fetch = mockFetchEmptyResult; const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, ); - incomingTransactionsController._normalizeTxFromEtherscan = (tx) => ({ - ...tx, - currentNetworkID: ROPSTEN_NETWORK_ID, - normalized: true, - }); - - const result = incomingTransactionsController._processTxFetchResponse({ - status: '1', - address: '0xfakeaddress', - chainId: ROPSTEN_CHAIN_ID, - result: [ - { - hash: '0xabc123', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5000, - time: 10, - }, - { - hash: '0xabc123', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5000, - time: 10, - }, - { - hash: '0xabc1234', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5000, - time: 9, - }, - { - hash: '0xabc12345', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5001, - time: 11, - }, - { - hash: '0xabc123456', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5001, - time: 12, - }, - { - hash: '0xabc1234567', - txParams: { - to: '0xanotherFakeaddress', - }, - blockNumber: 5002, - time: 13, - }, - ], - }); - - assert.deepEqual(result, { - latestIncomingTxBlockNumber: 5001, - txs: [ - { - hash: '0xabc1234', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5000, - time: 9, - normalized: true, - currentNetworkID: ROPSTEN_NETWORK_ID, - }, - { - hash: '0xabc123', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5000, - time: 10, - normalized: true, - currentNetworkID: ROPSTEN_NETWORK_ID, - }, - { - hash: '0xabc12345', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5001, - time: 11, - normalized: true, - currentNetworkID: ROPSTEN_NETWORK_ID, - }, - { - hash: '0xabc123456', - txParams: { - to: '0xfakeaddress', - }, - blockNumber: 5001, - time: 12, - normalized: true, - currentNetworkID: ROPSTEN_NETWORK_ID, - }, - ], - }); + const result = await incomingTransactionsController._getNewIncomingTransactions( + ADDRESS_TO_FETCH_FOR, + '789', + ROPSTEN_CHAIN_ID, + ); + assert.deepStrictEqual(result, []); + window.fetch = tempFetchEmptyResult; + mockFetchEmptyResult.reset(); }); }); @@ -1321,7 +1124,7 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, @@ -1343,7 +1146,7 @@ describe('IncomingTransactionsController', function () { ROPSTEN_CHAIN_ID, ); - assert.deepEqual(result, { + assert.deepStrictEqual(result, { blockNumber: 333, id: 54321, metamaskNetworkId: ROPSTEN_NETWORK_ID, @@ -1367,7 +1170,7 @@ describe('IncomingTransactionsController', function () { const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), - networkController: getMockNetworkController(ROPSTEN_CHAIN_ID), + ...getMockNetworkControllerMethods(ROPSTEN_CHAIN_ID), preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, @@ -1389,7 +1192,7 @@ describe('IncomingTransactionsController', function () { ROPSTEN_CHAIN_ID, ); - assert.deepEqual(result, { + assert.deepStrictEqual(result, { blockNumber: 333, id: 54321, metamaskNetworkId: ROPSTEN_NETWORK_ID, diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index eace3f918..09482d24b 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -31,7 +31,7 @@ export const SENTRY_STATE = { featureFlags: true, firstTimeFlowType: true, forgottenPassword: true, - incomingTxLastFetchedBlocksByNetwork: true, + incomingTxLastFetchedBlockByChainId: true, ipfsGateway: true, isAccountMenuOpen: true, isInitialized: true, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 14c96098c..5adc002ea 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -189,7 +189,13 @@ export default class MetamaskController extends EventEmitter { this.incomingTransactionsController = new IncomingTransactionsController({ blockTracker: this.blockTracker, - networkController: this.networkController, + onNetworkDidChange: this.networkController.on.bind( + this.networkController, + NETWORK_EVENTS.NETWORK_DID_CHANGE, + ), + getCurrentChainId: this.networkController.getCurrentChainId.bind( + this.networkController, + ), preferencesController: this.preferencesController, initState: initState.IncomingTransactionsController, }); diff --git a/app/scripts/migrations/055.js b/app/scripts/migrations/055.js new file mode 100644 index 000000000..22a06b3ce --- /dev/null +++ b/app/scripts/migrations/055.js @@ -0,0 +1,32 @@ +import { cloneDeep, mapKeys } from 'lodash'; +import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network'; + +const version = 55; + +/** + * replace 'incomingTxLastFetchedBlocksByNetwork' with 'incomingTxLastFetchedBlockByChainId' + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; + }, +}; + +function transformState(state) { + if ( + state?.IncomingTransactionsController?.incomingTxLastFetchedBlocksByNetwork + ) { + state.IncomingTransactionsController.incomingTxLastFetchedBlockByChainId = mapKeys( + state.IncomingTransactionsController.incomingTxLastFetchedBlocksByNetwork, + (_, key) => NETWORK_TYPE_TO_ID_MAP[key].chainId, + ); + delete state.IncomingTransactionsController + .incomingTxLastFetchedBlocksByNetwork; + } + return state; +} diff --git a/app/scripts/migrations/055.test.js b/app/scripts/migrations/055.test.js new file mode 100644 index 000000000..449c6291f --- /dev/null +++ b/app/scripts/migrations/055.test.js @@ -0,0 +1,96 @@ +import { strict as assert } from 'assert'; +import { + GOERLI, + GOERLI_CHAIN_ID, + KOVAN, + KOVAN_CHAIN_ID, + MAINNET, + MAINNET_CHAIN_ID, + RINKEBY, + RINKEBY_CHAIN_ID, + ROPSTEN, + ROPSTEN_CHAIN_ID, +} from '../../../shared/constants/network'; +import migration55 from './055'; + +describe('migration #55', function () { + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 54, + }, + data: {}, + }; + + const newStorage = await migration55.migrate(oldStorage); + assert.deepEqual(newStorage.meta, { + version: 55, + }); + }); + + it('should replace incomingTxLastFetchedBlocksByNetwork with incomingTxLastFetchedBlockByChainId, and carry over old values', async function () { + const oldStorage = { + meta: {}, + data: { + IncomingTransactionsController: { + incomingTransactions: { + test: { + transactionCategory: 'incoming', + txParams: { + foo: 'bar', + }, + }, + }, + incomingTxLastFetchedBlocksByNetwork: { + [MAINNET]: 1, + [ROPSTEN]: 2, + [RINKEBY]: 3, + [GOERLI]: 4, + [KOVAN]: 5, + }, + }, + foo: 'bar', + }, + }; + + const newStorage = await migration55.migrate(oldStorage); + assert.deepEqual(newStorage.data, { + IncomingTransactionsController: { + incomingTransactions: + oldStorage.data.IncomingTransactionsController.incomingTransactions, + incomingTxLastFetchedBlockByChainId: { + [MAINNET_CHAIN_ID]: 1, + [ROPSTEN_CHAIN_ID]: 2, + [RINKEBY_CHAIN_ID]: 3, + [GOERLI_CHAIN_ID]: 4, + [KOVAN_CHAIN_ID]: 5, + }, + }, + foo: 'bar', + }); + }); + + it('should do nothing if incomingTxLastFetchedBlocksByNetwork key is not populated', async function () { + const oldStorage = { + meta: {}, + data: { + IncomingTransactionsController: { + foo: 'baz', + }, + foo: 'bar', + }, + }; + + const newStorage = await migration55.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); + it('should do nothing if state is empty', async function () { + const oldStorage = { + meta: {}, + data: {}, + }; + + const newStorage = await migration55.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 00565e4d8..e03e4bc58 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -59,6 +59,7 @@ const migrations = [ require('./052').default, require('./053').default, require('./054').default, + require('./055').default, ]; export default migrations; diff --git a/shared/constants/transaction.js b/shared/constants/transaction.js index 87c33ebca..c50494e80 100644 --- a/shared/constants/transaction.js +++ b/shared/constants/transaction.js @@ -30,6 +30,12 @@ * the same nonce and higher gas fees. */ +/** + * This type will work anywhere you expect a string that can be one of the + * above transaction types. + * @typedef {TransactionTypes[keyof TransactionTypes]} TransactionTypeString + */ + /** * @type {TransactionTypes} */ @@ -65,6 +71,12 @@ export const TRANSACTION_TYPES = { * @property {'confirmed'} CONFIRMED - The transaction was confirmed by the network */ +/** + * This type will work anywhere you expect a string that can be one of the + * above transaction statuses. + * @typedef {TransactionStatuses[keyof TransactionStatuses]} TransactionStatusString + */ + /** * @type {TransactionStatuses} */ @@ -132,3 +144,45 @@ export const TRANSACTION_GROUP_CATEGORIES = { SIGNATURE_REQUEST: 'signature-request', SWAP: 'swap', }; + +/** + * @typedef {Object} TxParams + * @property {string} from - The address the transaction is sent from + * @property {string} to - The address the transaction is sent to + * @property {string} value - The amount of wei, in hexadecimal, to send + * @property {number} nonce - The transaction count for the current account/network + * @property {string} gasPrice - The amount of gwei, in hexadecimal, per unit of gas + * @property {string} gas - The max amount of gwei, in hexadecimal, the user is willing to pay + * @property {string} [data] - Hexadecimal encoded string representing calls to the EVM's ABI + */ +/** + * An object representing a transaction, in whatever state it is in. + * @typedef {Object} TransactionMeta + * + * @property {string} [blockNumber] - The block number this transaction was + * included in. Currently only present on incoming transactions! + * @property {number} id - An internally unique tx identifier. + * @property {number} time - Time the transaction was first suggested, in unix + * epoch time (ms). + * @property {TransactionTypeString} type - The type of transaction this txMeta + * represents. + * @property {TransactionStatusString} status - The current status of the + * transaction. + * @property {string} metamaskNetworkId - The transaction's network ID, used + * for EIP-155 compliance. + * @property {boolean} loadingDefaults - TODO: Document + * @property {TxParams} txParams - The transaction params as passed to the + * network provider. + * @property {Object[]} history - A history of mutations to this + * TransactionMeta object. + * @property {string} origin - A string representing the interface that + * suggested the transaction. + * @property {Object} nonceDetails - A metadata object containing information + * used to derive the suggested nonce, useful for debugging nonce issues. + * @property {string} rawTx - A hex string of the final signed transaction, + * ready to submit to the network. + * @property {string} hash - A hex string of the transaction hash, used to + * identify the transaction on the network. + * @property {number} submittedTime - The time the transaction was submitted to + * the network, in Unix epoch time (ms). + */ From 1b4504e2331cd390b917fdadce10547df7994fb3 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Mon, 22 Mar 2021 10:21:52 -0500 Subject: [PATCH 26/82] make migration more safe (#10689) --- app/scripts/migrations/055.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/scripts/migrations/055.js b/app/scripts/migrations/055.js index 22a06b3ce..98676bc63 100644 --- a/app/scripts/migrations/055.js +++ b/app/scripts/migrations/055.js @@ -17,14 +17,25 @@ export default { }, }; +const UNKNOWN_CHAIN_ID_KEY = 'UNKNOWN'; + function transformState(state) { if ( state?.IncomingTransactionsController?.incomingTxLastFetchedBlocksByNetwork ) { state.IncomingTransactionsController.incomingTxLastFetchedBlockByChainId = mapKeys( state.IncomingTransactionsController.incomingTxLastFetchedBlocksByNetwork, - (_, key) => NETWORK_TYPE_TO_ID_MAP[key].chainId, + // using optional chaining in case user's state has fetched blocks for + // RPC network types (which don't map to a single chainId). This should + // not be possible, but it's safer + (_, key) => NETWORK_TYPE_TO_ID_MAP[key]?.chainId ?? UNKNOWN_CHAIN_ID_KEY, ); + // Now that mainnet and test net last fetched blocks are keyed by their + // respective chainIds, we can safely delete anything we had for custom + // networks. Any custom network that shares a chainId with one of the + // aforementioned networks will use the value stored by chainId. + delete state.IncomingTransactionsController + .incomingTxLastFetchedBlockByChainId[UNKNOWN_CHAIN_ID_KEY]; delete state.IncomingTransactionsController .incomingTxLastFetchedBlocksByNetwork; } From fc8ffc134d79cf821ed75dd385ac6e193a59185a Mon Sep 17 00:00:00 2001 From: ryanml Date: Mon, 22 Mar 2021 09:57:34 -0700 Subject: [PATCH 27/82] Adding default properties to NetworkForm (#10682) Fixes MetaMask/metamask-extension#10681 --- .../networks-tab/network-form/network-form.component.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ui/app/pages/settings/networks-tab/network-form/network-form.component.js b/ui/app/pages/settings/networks-tab/network-form/network-form.component.js index da665045a..58a3f5754 100644 --- a/ui/app/pages/settings/networks-tab/network-form/network-form.component.js +++ b/ui/app/pages/settings/networks-tab/network-form/network-form.component.js @@ -43,6 +43,14 @@ export default class NetworkForm extends PureComponent { isFullScreen: PropTypes.bool, }; + static defaultProps = { + rpcUrl: '', + chainId: '', + ticker: '', + networkName: '', + blockExplorerUrl: '', + }; + state = { rpcUrl: this.props.rpcUrl, chainId: this.getDisplayChainId(this.props.chainId), From ff86465a24d9754a62647e58700b6f43786173c8 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 23 Mar 2021 02:02:25 +0800 Subject: [PATCH 28/82] deps - remove "remotedev-server" (#10687) * deps - remove remotedev-server * Remove stale references from allow-scripts config Any packages that are no longer in the dependency tree have been removed from the `allow-scripts` config. Co-authored-by: Mark Stacey --- package.json | 4 - yarn.lock | 559 ++------------------------------------------------- 2 files changed, 16 insertions(+), 547 deletions(-) diff --git a/package.json b/package.json index d7b242642..af6ea3340 100644 --- a/package.json +++ b/package.json @@ -269,7 +269,6 @@ "read-installed": "^4.0.3", "redux-mock-store": "^1.5.4", "remote-redux-devtools": "^0.5.16", - "remotedev-server": "^0.3.1", "resolve-url-loader": "^3.1.2", "sass": "^1.32.4", "sass-loader": "^10.1.1", @@ -300,7 +299,6 @@ "geckodriver": true, "@sentry/cli": true, "electron": true, - "sqlite3": true, "core-js": false, "core-js-pure": false, "keccak": false, @@ -309,8 +307,6 @@ "sha3": false, "bufferutil": false, "utf-8-validate": false, - "ejs": false, - "sc-uws": false, "leveldown": false, "ursa-optional": false, "gc-stats": false, diff --git a/yarn.lock b/yarn.lock index 738b2c749..34f1db8ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3590,13 +3590,6 @@ text-table "^0.2.0" webpack-log "^1.1.2" -"@wry/equality@^0.1.2": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.9.tgz#b13e18b7a8053c6858aa6c85b54911fb31e3a909" - integrity sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ== - dependencies: - tslib "^1.9.3" - "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -4048,7 +4041,7 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -4165,62 +4158,6 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -apollo-cache-control@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" - integrity sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA== - dependencies: - graphql-extensions "^0.0.x" - -apollo-link@^1.2.3: - version "1.2.12" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.12.tgz#014b514fba95f1945c38ad4c216f31bcfee68429" - integrity sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q== - dependencies: - apollo-utilities "^1.3.0" - ts-invariant "^0.4.0" - tslib "^1.9.3" - zen-observable-ts "^0.8.19" - -apollo-server-core@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" - integrity sha512-BP1Vh39krgEjkQxbjTdBURUjLHbFq1zeOChDJgaRsMxGtlhzuLWwwC6lLdPatN8jEPbeHq8Tndp9QZ3iQZOKKA== - dependencies: - apollo-cache-control "^0.1.0" - apollo-tracing "^0.1.0" - graphql-extensions "^0.0.x" - -apollo-server-express@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" - integrity sha512-zkH00nxhLnJfO0HgnNPBTfZw8qI5ILaPZ5TecMCI9+Y9Ssr2b0bFr9pBRsXy9eudPhI+/O4yqegSUsnLdF/CPw== - dependencies: - apollo-server-core "^1.4.0" - apollo-server-module-graphiql "^1.4.0" - -apollo-server-module-graphiql@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" - integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== - -apollo-tracing@^0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" - integrity sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ== - dependencies: - graphql-extensions "~0.0.9" - -apollo-utilities@^1.0.1, apollo-utilities@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.2.tgz#8cbdcf8b012f664cd6cb5767f6130f5aed9115c9" - integrity sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg== - dependencies: - "@wry/equality" "^0.1.2" - fast-json-stable-stringify "^2.0.0" - ts-invariant "^0.4.0" - tslib "^1.9.3" - app-root-dir@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" @@ -4665,20 +4602,6 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= -async@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.0.0.tgz#d0900ad385af13804540a109c42166e3ae7b2b9d" - integrity sha1-0JAK04WvE4BFQKEJxCFm4657K50= - dependencies: - lodash "^4.8.0" - -async@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" - integrity sha1-EBPRBRBH3TIP4k5JTVxm7K9hR9k= - dependencies: - lodash "^4.14.0" - async@2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" @@ -5630,11 +5553,6 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base64id@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" - integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= - base64id@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" @@ -5658,13 +5576,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" - integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== - dependencies: - safe-buffer "5.1.2" - batch-processor@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8" @@ -5883,7 +5794,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.5: +bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.5.0, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -5913,7 +5824,7 @@ bn.js@^5.1.1, bn.js@^5.1.2: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== -body-parser@1.19.0, body-parser@^1.15.0, body-parser@^1.16.0: +body-parser@1.19.0, body-parser@^1.16.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== @@ -6299,11 +6210,6 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - buffer-equal@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" @@ -6710,15 +6616,6 @@ chain-function@^1.0.0: resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.1.tgz#c63045e5b4b663fb86f1c6e186adaf1de402a1cc" integrity sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg== -chalk@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" - integrity sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -6784,11 +6681,6 @@ character-reference-invalid@^1.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz#942835f750e4ec61a308e60c2ef8cc1011202efc" integrity sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw= -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -7286,7 +7178,7 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59" integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ== -commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: +commander@^2.15.0, commander@^2.15.1, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -7582,7 +7474,7 @@ core-js-pure@^3.0.0, core-js-pure@^3.0.1: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== -core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3: +core-js@^2.4.0, core-js@^2.5.0: version "2.6.11" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== @@ -7597,7 +7489,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@^2.7.1, cors@^2.8.1: +cors@^2.8.1: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -8336,11 +8228,6 @@ depd@~2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -deprecated-decorator@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" - integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= - deps-sort@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" @@ -8779,13 +8666,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - ecurve@^1.0.0, ecurve@^1.0.3: version "1.0.6" resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" @@ -8799,11 +8679,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.4.1: - version "2.7.4" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== - ejs@^3.0.2, ejs@^3.1.2: version "3.1.5" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" @@ -10596,17 +10471,12 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expirymanager@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/expirymanager/-/expirymanager-0.9.3.tgz#e5f6b3ba00d8d76cf63311c2b71d7dfc9bde3e4f" - integrity sha1-5fazugDY12z2MxHCtx19/JvePk8= - explain-error@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.4.tgz#a793d3ac0cad4c6ab571e9968fbbab6cb2532929" integrity sha1-p5PTrAytTGq1cemWj7urbLJTKSk= -express@^4.13.3, express@^4.14.0, express@^4.17.0: +express@^4.14.0, express@^4.17.0: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -10679,15 +10549,6 @@ extensionizer@^1.0.1: resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.1.tgz#504544239a7610ba8404b15c1832091a37768d09" integrity sha512-UES5CSOYqshNsWFrpORcQR47+ph6UvQK25mguD44IyeMemt40CG+LTZrH1PgpGUHX3w7ACtNQnmM0J+qEe8G0Q== -external-editor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" - integrity sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -11196,11 +11057,6 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== -fleximap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fleximap/-/fleximap-1.0.0.tgz#1ad448de87b8e023ba6a60623b7e8b0867360ef6" - integrity sha512-zg/PthjBzESYKomTw/wivo8Id6B+obVkWriIzDuRfuw4wxEIV2/0D/NIGf+LKcGTTifHRfw73+oAAQozZ9MAhA== - flow-stoplight@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" @@ -11368,15 +11224,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" - integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -11762,11 +11609,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -getport@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/getport/-/getport-0.1.0.tgz#abddf3d5d1e77dd967ccfa2b036a0a1fb26fd7f7" - integrity sha1-q93z1dHnfdlnzPorA2oKH7Jv1/c= - gettext-parser@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" @@ -12200,14 +12042,6 @@ graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, g resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: - version "0.0.10" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" - integrity sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA== - dependencies: - core-js "^2.5.3" - source-map-support "^0.5.1" - graphql-request@^1.8.2: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" @@ -12215,31 +12049,6 @@ graphql-request@^1.8.2: dependencies: cross-fetch "2.2.2" -graphql-server-express@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/graphql-server-express/-/graphql-server-express-1.4.1.tgz#b096743fb8e3380a3e93cefbe635d0f18f7a57f5" - integrity sha512-7HEIz2USTCXgk4YMKIcOVUdVZQT429nZnPQr4Gqp5pydZ08KJM9Y2sl9+VU+3a91HGKyrtF04eUumuYeS2fDcg== - dependencies: - apollo-server-express "^1.4.0" - -graphql-tools@^4.0.3: - version "4.0.5" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.5.tgz#d2b41ee0a330bfef833e5cdae7e1f0b0d86b1754" - integrity sha512-kQCh3IZsMqquDx7zfIGWBau42xe46gmqabwYkpPlCLIjcEY1XK+auP7iGRD9/205BPyoQdY8hT96MPpgERdC9Q== - dependencies: - apollo-link "^1.2.3" - apollo-utilities "^1.0.1" - deprecated-decorator "^0.1.6" - iterall "^1.1.3" - uuid "^3.1.0" - -graphql@^0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== - dependencies: - iterall "^1.2.1" - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -12941,7 +12750,7 @@ iconv-lite@0.4.19: resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -13137,25 +12946,6 @@ inline-source-map@~0.6.0: dependencies: source-map "~0.5.3" -inquirer@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" - integrity sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.1.0" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^5.5.2" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - inquirer@7.0.4, inquirer@^7.0.0: version "7.0.4" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" @@ -13262,7 +13052,7 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -interpret@^1.0.0, interpret@^1.1.0, interpret@^1.4.0: +interpret@^1.0.0, interpret@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== @@ -14684,11 +14474,6 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -iterall@^1.1.3, iterall@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== - jake@^10.6.1: version "10.8.2" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" @@ -15032,22 +14817,6 @@ jsonschema@^1.2.4: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.4.tgz#a46bac5d3506a254465bc548876e267c6d0d6464" integrity sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw== -jsonwebtoken@^8.3.0: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -15186,23 +14955,6 @@ just-safe-set@^2.1.0: resolved "https://registry.yarnpkg.com/just-safe-set/-/just-safe-set-2.1.0.tgz#237234e681a4f330b5dfa71a5251f34962813ef9" integrity sha512-wSTg/2bQpzyivBYbWPqQgafdfxW0tr3hX9qYGDRS2ws+AXwc7tvn8ABqkp8iPQHChjj4F5JvL3t0FQLbcNuKig== -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - k-bucket@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/k-bucket/-/k-bucket-5.0.0.tgz#ef7a401fcd4c37cd31dceaa6ae4440ca91055e01" @@ -15310,28 +15062,6 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -knex@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/knex/-/knex-0.15.2.tgz#6059b87489605f4cc87599a6d2a9d265709e9340" - integrity sha1-YFm4dIlgX0zIdZmm0qnSZXCek0A= - dependencies: - babel-runtime "^6.26.0" - bluebird "^3.5.1" - chalk "2.3.2" - commander "^2.16.0" - debug "3.1.0" - inherits "~2.0.3" - interpret "^1.1.0" - liftoff "2.5.0" - lodash "^4.17.10" - minimist "1.2.0" - mkdirp "^0.5.1" - pg-connection-string "2.0.0" - tarn "^1.1.4" - tildify "1.2.0" - uuid "^3.3.2" - v8flags "^3.1.1" - known-css-properties@^0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.19.0.tgz#5d92b7fa16c72d971bda9b7fe295bdf61836ee5b" @@ -16184,20 +15914,6 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" -liftoff@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" - integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew= - dependencies: - extend "^3.0.0" - findup-sync "^2.0.0" - fined "^1.0.1" - flagged-respawn "^1.0.0" - is-plain-object "^2.0.4" - object.map "^1.0.0" - rechoir "^0.6.2" - resolve "^1.1.7" - liftoff@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" @@ -16359,11 +16075,6 @@ lodash.assign@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= -lodash.clonedeep@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.escape@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" @@ -16394,11 +16105,6 @@ lodash.includes@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= - lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -16414,16 +16120,6 @@ lodash.isfunction@^3.0.9: resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -16444,11 +16140,6 @@ lodash.memoize@~3.0.3: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8= -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= - lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" @@ -16469,7 +16160,7 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: +lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.2, lodash@~4.17.4: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -17166,7 +16857,7 @@ minimist-options@^4.0.2: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@~1.2.0: +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@~1.2.0: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -17344,17 +17035,6 @@ moo@^0.4.3: resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" integrity sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw== -morgan@^1.7.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" - integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== - dependencies: - basic-auth "~2.0.0" - debug "2.6.9" - depd "~1.1.2" - on-finished "~2.3.0" - on-headers "~1.0.1" - mortice@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/mortice/-/mortice-1.2.2.tgz#a388dcb24bb984da86c4edb04ed29d70d352882b" @@ -17655,13 +17335,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -ncom@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ncom/-/ncom-1.0.3.tgz#07f580427ac7d8aad9e0762c260658eb4dae6e7d" - integrity sha512-PfA7rjxxMAItsGo2qXrGn2GvKJIwN0bUTa3GehsblrKRVdCCEwB0QG2ymM6/DppQGUt7YqbfxQB7LaMWMiHHWQ== - dependencies: - sc-formatter "~3.0.1" - ncp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" @@ -17892,22 +17565,6 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-pre-gyp@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" - integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - node-pre-gyp@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" @@ -18423,11 +18080,6 @@ on-finished@^2.3.0, on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -19396,11 +19048,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pg-connection-string@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.0.0.tgz#3eefe5997e06d94821e4d502e42b6a1c73f8df82" - integrity sha1-Pu/lmX4G2Ugh5NUC5CtqHHP434I= - picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" @@ -21530,29 +21177,6 @@ remotedev-serialize@^0.1.8: dependencies: jsan "^3.1.13" -remotedev-server@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/remotedev-server/-/remotedev-server-0.3.1.tgz#711f413f20968d7c9f4f7e9eff82e98377f49012" - integrity sha512-EXgfeTEem2BJOZOkuU/uPiLumgSy1BkXtk0tnvJTeA91TuQ1Q0ipCWZsqBYxSq6CdH4BseuLvLQSbKgrvzzs6w== - dependencies: - body-parser "^1.15.0" - chalk "^1.1.3" - cors "^2.7.1" - ejs "^2.4.1" - express "^4.13.3" - getport "^0.1.0" - graphql "^0.13.0" - graphql-server-express "^1.4.0" - graphql-tools "^4.0.3" - knex "^0.15.2" - lodash "^4.15.0" - minimist "^1.2.0" - morgan "^1.7.0" - semver "^5.3.0" - socketcluster "^14.3.3" - sqlite3 "^4.0.4" - uuid "^3.0.1" - remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -22072,13 +21696,6 @@ rx-lite@^3.1.2: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= -rxjs@^5.5.2: - version "5.5.12" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" - integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== - dependencies: - symbol-observable "1.0.1" - rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" @@ -22165,37 +21782,6 @@ sax@^1.2.1, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -sc-auth@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/sc-auth/-/sc-auth-5.0.2.tgz#a9ac421fb30f127089dbf8b0f26b2601e009b0dc" - integrity sha512-Le3YBsFjzv5g6wIH6Y+vD+KFkK0HDXiaWy1Gm4nXtYebMQUyNYSf1cS83MtHrYzVEMlhYElRva1b0bvZ0hBqQw== - dependencies: - jsonwebtoken "^8.3.0" - sc-errors "^1.4.1" - -sc-broker-cluster@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/sc-broker-cluster/-/sc-broker-cluster-7.0.0.tgz#7c7de27843241a5b72ee8811abe50920cd4a21fd" - integrity sha512-DNG8sxiFwmRSMS0sUXA25UvDV8QTwEfYnzrutqbp4HlMU9JP65FBcs6GuNFPhjQN4s9VtwAE8BBaCNK5BjNV0g== - dependencies: - async "2.0.0" - sc-broker "^6.0.0" - sc-channel "^1.2.0" - sc-errors "^1.4.1" - sc-hasher "^1.0.1" - -sc-broker@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/sc-broker/-/sc-broker-6.0.0.tgz#cb0c5572c86b26d2f942edaf0201ef694e3e1ddb" - integrity sha512-c1mFIllUdPnEXDDFxTiX3obYW+cT0hb56fdNM5k+Xo5DI3+3Q9MYxTc8jD23qBIXOHokt4+d/CHocmZQPlAjAQ== - dependencies: - async "^2.6.1" - expirymanager "^0.9.3" - fleximap "^1.0.0" - ncom "^1.0.2" - sc-errors "^1.4.1" - uuid "3.1.0" - sc-channel@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/sc-channel/-/sc-channel-1.2.0.tgz#d9209f3a91e3fa694c66b011ce55c4ad8c3087d9" @@ -22203,38 +21789,16 @@ sc-channel@^1.2.0: dependencies: component-emitter "1.2.1" -sc-errors@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-1.4.1.tgz#53e80030fe647e133d73b51eaa7d2b0f7591fd5b" - integrity sha512-dBn92iIonpChTxYLgKkIT/PCApvmYT6EPIbRvbQKTgY6tbEbIy8XVUv4pGyKwEK4nCmvX4TKXcN0iXC6tNW6rQ== - sc-errors@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-2.0.1.tgz#3af2d934dfd82116279a4b2c1552c1e021ddcb03" integrity sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ== -sc-formatter@^3.0.1, sc-formatter@^3.0.2, sc-formatter@~3.0.1: +sc-formatter@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/sc-formatter/-/sc-formatter-3.0.2.tgz#9abdb14e71873ce7157714d3002477bbdb33c4e6" integrity sha512-9PbqYBpCq+OoEeRQ3QfFIGE6qwjjBcd2j7UjgDlhnZbtSnuGgHdcRklPKYGuYFH82V/dwd+AIpu8XvA1zqTd+A== -sc-hasher@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sc-hasher/-/sc-hasher-1.0.1.tgz#32e73edb7c71a0ef0f2eb17ee04754a7395a71a2" - integrity sha512-whZWw70Gp5ibXXMcz6+Tulmk8xkwWMs42gG70p12hGscdUg8BICBvihS3pX2T3dWTw+yeZuGKiULr3MwL37SOQ== - -sc-simple-broker@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/sc-simple-broker/-/sc-simple-broker-2.1.3.tgz#c347d32dcf860995037abac348cc34743384b3f9" - integrity sha512-ldt0ybOS5fVZSMea5Z8qVu7lmDBTy0qO9BD6TseJjRuPx+g+stfSqmPAb0RsCsQUXRH8A1koCbwsuUnI9BOxvw== - dependencies: - sc-channel "^1.2.0" - -sc-uws@^10.148.2: - version "10.148.2" - resolved "https://registry.yarnpkg.com/sc-uws/-/sc-uws-10.148.2.tgz#929823c8ece2ab4efa17468a4eea2eac05a85ad8" - integrity sha512-wGXiwsORev5O3OOewsAYi1WVyMeNFMQ4bw/Qg/6g0C0J9vsEs8xnxf19hovAAQrOq6sMVrcxCNa2k1rBiDsDzw== - scheduler@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" @@ -22872,39 +22436,6 @@ socketcluster-client@^14.2.1: uuid "3.2.1" ws "7.1.0" -socketcluster-server@^14.3.2: - version "14.4.0" - resolved "https://registry.yarnpkg.com/socketcluster-server/-/socketcluster-server-14.4.0.tgz#7a1446fefdd432294efbe12b4d86f1e2e3183a5d" - integrity sha512-qG4XVFsm9SXZNQZWUA2++LO+/n6nHC0FKCHHlSkXk2At7rM82TR0DXBr+Nll2H4IcWt+bfqZ8Z2H3rVTp+vpbg== - dependencies: - async "2.3.0" - base64id "1.0.0" - component-emitter "1.2.1" - lodash.clonedeep "4.5.0" - sc-auth "^5.0.2" - sc-errors "^1.4.1" - sc-formatter "^3.0.2" - sc-simple-broker "^2.1.3" - sc-uws "^10.148.2" - uuid "3.2.1" - ws "6.1.2" - -socketcluster@^14.3.3: - version "14.3.5" - resolved "https://registry.yarnpkg.com/socketcluster/-/socketcluster-14.3.5.tgz#ba172adf1a050c6e2647998392864f5d8bff3361" - integrity sha512-ckXuLdjDkSGde8urxpQmg37A2HC1pCxS4Bq3NReG5+sUAxzdJxuPofmUjHJ/aYHU8qDnk7lGXw1dq2sfFdszeQ== - dependencies: - async "2.3.0" - fs-extra "6.0.1" - inquirer "5.2.0" - minimist "1.2.0" - sc-auth "^5.0.2" - sc-broker-cluster "^7.0.0" - sc-errors "^1.4.1" - socketcluster-server "^14.3.2" - uid-number "0.0.6" - uuid "3.2.1" - socks-proxy-agent@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" @@ -22992,7 +22523,7 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map-support@^0.5.1, source-map-support@^0.5.11, source-map-support@^0.5.16, source-map-support@~0.5.12, source-map-support@~0.5.4: +source-map-support@^0.5.11, source-map-support@^0.5.16, source-map-support@~0.5.12, source-map-support@~0.5.4: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -23124,15 +22655,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sqlite3@^4.0.4: - version "4.0.9" - resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.0.9.tgz#cff74550fa5a1159956815400bdef69245557640" - integrity sha512-IkvzjmsWQl9BuBiM4xKpl5X8WCR4w0AeJHRdobCdXZ8dT/lNc1XS6WqvY35N6+YzIIgzSBeY5prdFObID9F9tA== - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.11.0" - request "^2.87.0" - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -23831,7 +23353,7 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" -symbol-observable@1.0.1, symbol-observable@^1.2.0, symbol-observable@^2.0.3: +symbol-observable@^1.2.0, symbol-observable@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== @@ -23946,11 +23468,6 @@ tar@^4, tar@^4.0.2: safe-buffer "^5.1.2" yallist "^3.0.3" -tarn@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d" - integrity sha512-PMtJ3HCLAZeedWjJPgGnCvcphbCOMbtZpjKgLq3qM5Qq9aQud+XHrL0WlrlgnTyS8U+jrjGbEXprFcQrxPy52g== - tcp-port-used@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.1.tgz#46061078e2d38c73979a2c2c12b5a674e6689d70" @@ -24105,13 +23622,6 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== -tildify@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" - integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= - dependencies: - os-homedir "^1.0.0" - time-cache@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/time-cache/-/time-cache-0.3.0.tgz#ed0dfcf0fda45cdc95fbd601fda830ebf1bd5d8b" @@ -24450,13 +23960,6 @@ ts-essentials@^2.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== -ts-invariant@^0.4.0: - version "0.4.4" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" - integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA== - dependencies: - tslib "^1.9.3" - ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -24628,11 +24131,6 @@ typical@^5.0.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.1.0.tgz#7116ca103caf2574985fc84fbaa8fd0ee5ea1684" integrity sha512-t5Ik8UAwBal1P1XzuVE4dc+RYQZicLUGJdvqr/vdqsED7SQECgsGBylldSsfWZL7RQjxT3xhQcKHWhLaVSR6YQ== -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= - ultron@1.0.x: version "1.0.2" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" @@ -25128,11 +24626,6 @@ uuid@2.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= -uuid@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== - uuid@3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" @@ -25143,7 +24636,7 @@ uuid@3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2, uuid@^3.3.2, uuid@^3.3.3: +uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2, uuid@^3.3.2, uuid@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== @@ -25158,7 +24651,7 @@ v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== -v8flags@^3.1.1, v8flags@^3.2.0: +v8flags@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== @@ -26031,13 +25524,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== - dependencies: - async-limiter "~1.0.0" - ws@7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/ws/-/ws-7.1.0.tgz#0395646c6fcc3ac56abf61ce1a42039637a6bd98" @@ -26393,16 +25879,3 @@ zcash-bitcore-lib@~0.13.20-rc3: elliptic "=3.0.3" inherits "=2.0.1" lodash "=3.10.1" - -zen-observable-ts@^0.8.19: - version "0.8.19" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz#c094cd20e83ddb02a11144a6e2a89706946b5694" - integrity sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ== - dependencies: - tslib "^1.9.3" - zen-observable "^0.8.0" - -zen-observable@^0.8.0: - version "0.8.14" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.14.tgz#d33058359d335bc0db1f0af66158b32872af3bf7" - integrity sha512-kQz39uonEjEESwh+qCi83kcC3rZJGh4mrZW7xjkSQYXkq//JZHTtKo+6yuVloTgMtzsIWOJrjIrKvk/dqm0L5g== From 91e5b859552852c68ad6fa7d4e46a6ed83ac67c2 Mon Sep 17 00:00:00 2001 From: ryanml Date: Mon, 22 Mar 2021 19:41:23 -0700 Subject: [PATCH 29/82] Excluding sourcemaps comment in production builds (#10695) * Excluding sourcemaps comment in production builds Fixes MetaMask/metamask-extension#7077 * Fix source map explorer script The source map explorer script now re-adds the source map comment to each file to ensure the source map visualization still works. Each module with a sourcemap is copied to a temporary directory along with the module it corresponds to, and from there it's passed into `source-map-explorer`. This should ensure the resulting visualization matches what it was before. Everything has been moved inside of functions to generally improve readability, and to allow the use of local variables. Co-authored-by: Mark Stacey --- development/build/scripts.js | 4 +++- development/source-map-explorer.sh | 35 +++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/development/build/scripts.js b/development/build/scripts.js index f3dcc8de0..c91794ec4 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -254,7 +254,9 @@ function createScriptTasks({ browserPlatforms, livereload }) { // note: sourcemaps call arity is important buildPipeline.push(sourcemaps.write()); } else { - buildPipeline.push(sourcemaps.write('../sourcemaps')); + buildPipeline.push( + sourcemaps.write('../sourcemaps', { addComment: false }), + ); } // write completed bundles diff --git a/development/source-map-explorer.sh b/development/source-map-explorer.sh index a4130d0f0..ae9563f9f 100755 --- a/development/source-map-explorer.sh +++ b/development/source-map-explorer.sh @@ -5,11 +5,30 @@ set -e set -u set -o pipefail -mkdir -p build-artifacts/source-map-explorer -yarn source-map-explorer dist/chrome/inpage.js --html build-artifacts/source-map-explorer/inpage.html -yarn source-map-explorer dist/chrome/contentscript.js --html build-artifacts/source-map-explorer/contentscript.html -yarn source-map-explorer dist/chrome/background.js --html build-artifacts/source-map-explorer/background.html -yarn source-map-explorer dist/chrome/bg-libs.js --html build-artifacts/source-map-explorer/bg-libs.html -yarn source-map-explorer dist/chrome/ui.js --html build-artifacts/source-map-explorer/ui.html -yarn source-map-explorer dist/chrome/ui-libs.js --html build-artifacts/source-map-explorer/ui-libs.html -yarn source-map-explorer dist/chrome/phishing-detect.js --html build-artifacts/source-map-explorer/phishing-detect.html +function generate_sourcemap() { + local temp_dir="${1}"; shift + local module_name="${1}"; shift + + cp "dist/chrome/${module_name}.js" "${temp_dir}/" + cp "dist/sourcemaps/${module_name}.js.map" "${temp_dir}/" + printf '//# sourceMappingURL=%s.js.map' "${module_name}" >> "${temp_dir}/${module_name}.js" + yarn source-map-explorer "${temp_dir}/${module_name}.js" "${temp_dir}/${module_name}.js.map" --html "build-artifacts/source-map-explorer/${module_name}.html" +} + +function main() { + mkdir -p build-artifacts/source-map-explorer + + local temp_dir + temp_dir="$(mktemp -d)" + + for file in dist/sourcemaps/*.js.map; do + [[ -e $file ]] || (echo 'Failed to find any JavaScript modules' && exit 1) + local filename + filename="$(basename "${file}")" + local module_name + module_name="${filename%.js.map}" + generate_sourcemap "${temp_dir}" "${module_name}" + done +} + +main From bfdc1e68f5b7a9d287d3b7e39aabbfccf9db29b5 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 23 Mar 2021 18:05:49 +0800 Subject: [PATCH 30/82] Delete setupFetchDebugging.js (#10636) * Delete setupFetchDebugging.js * remove fetch-debugging (now handled corrently by sentry) --- app/scripts/background.js | 6 ---- app/scripts/lib/setupFetchDebugging.js | 41 -------------------------- 2 files changed, 47 deletions(-) delete mode 100644 app/scripts/lib/setupFetchDebugging.js diff --git a/app/scripts/background.js b/app/scripts/background.js index 963f71daf..ae46819c1 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,12 +1,6 @@ /** * @file The entry point for the web extension singleton process. */ -// these need to run before anything else -/* eslint-disable import/first,import/order */ -import setupFetchDebugging from './lib/setupFetchDebugging'; -/* eslint-enable import/order */ - -setupFetchDebugging(); // polyfills import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'; diff --git a/app/scripts/lib/setupFetchDebugging.js b/app/scripts/lib/setupFetchDebugging.js deleted file mode 100644 index 724500b9b..000000000 --- a/app/scripts/lib/setupFetchDebugging.js +++ /dev/null @@ -1,41 +0,0 @@ -// -// This is a utility to help resolve cases where `window.fetch` throws a -// `TypeError: Failed to Fetch` without any stack or context for the request -// https://github.com/getsentry/sentry-javascript/pull/1293 -// - -export default function setupFetchDebugging() { - if (!window.fetch) { - return; - } - const originalFetch = window.fetch; - - window.fetch = wrappedFetch; - - async function wrappedFetch(...args) { - const initialStack = getCurrentStack(); - try { - return await originalFetch.call(window, ...args); - } catch (err) { - if (!err.stack) { - console.warn( - 'FetchDebugger - fetch encountered an Error without a stack', - err, - ); - console.warn( - 'FetchDebugger - overriding stack to point of original call', - ); - err.stack = initialStack; - } - throw err; - } - } -} - -function getCurrentStack() { - try { - throw new Error('Fake error for generating stack trace'); - } catch (err) { - return err.stack; - } -} From 255586aea1d2ba6cff20ab7c511d8acd00d1e4a8 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Tue, 23 Mar 2021 16:12:32 -0500 Subject: [PATCH 31/82] resolve issue with missing template error (#10692) * resolve issue with missing template error * also apply filtering to confirmation page * rename variable --- ui/app/helpers/constants/routes.js | 2 ++ ui/app/pages/confirmation/confirmation.js | 7 +++++-- ui/app/pages/confirmation/templates/index.js | 4 ++++ ui/app/pages/home/home.component.js | 6 +++--- ui/app/pages/home/home.container.js | 5 +++-- ui/app/selectors/selectors.js | 8 ++++++++ 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ui/app/helpers/constants/routes.js b/ui/app/helpers/constants/routes.js index 2079dcf40..61b21b50c 100644 --- a/ui/app/helpers/constants/routes.js +++ b/ui/app/helpers/constants/routes.js @@ -104,6 +104,8 @@ const PATH_NAME_MAP = { [CONNECTED_ACCOUNTS_ROUTE]: 'Accounts Connected To This Site Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id`]: 'Confirmation Root Page', [CONFIRM_TRANSACTION_ROUTE]: 'Confirmation Root Page', + // TODO: rename when this is the only confirmation page + [CONFIRMATION_V_NEXT_ROUTE]: 'New Confirmation Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_TOKEN_METHOD_PATH}`]: 'Confirm Token Method Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_SEND_ETHER_PATH}`]: 'Confirm Send Ether Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_SEND_TOKEN_PATH}`]: 'Confirm Send Token Transaction Page', diff --git a/ui/app/pages/confirmation/confirmation.js b/ui/app/pages/confirmation/confirmation.js index 47ce4f191..16c09b629 100644 --- a/ui/app/pages/confirmation/confirmation.js +++ b/ui/app/pages/confirmation/confirmation.js @@ -17,7 +17,7 @@ import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; import { stripHttpsScheme } from '../../helpers/utils/util'; import { useI18nContext } from '../../hooks/useI18nContext'; import { useOriginMetadata } from '../../hooks/useOriginMetadata'; -import { getUnapprovedConfirmations } from '../../selectors'; +import { getUnapprovedTemplatedConfirmations } from '../../selectors'; import NetworkDisplay from '../../components/app/network-display/network-display'; import { COLORS, SIZES } from '../../helpers/constants/design-system'; import Callout from '../../components/ui/callout'; @@ -115,7 +115,10 @@ export default function ConfirmationPage() { const t = useI18nContext(); const dispatch = useDispatch(); const history = useHistory(); - const pendingConfirmations = useSelector(getUnapprovedConfirmations, isEqual); + const pendingConfirmations = useSelector( + getUnapprovedTemplatedConfirmations, + isEqual, + ); const [currentPendingConfirmation, setCurrentPendingConfirmation] = useState( 0, ); diff --git a/ui/app/pages/confirmation/templates/index.js b/ui/app/pages/confirmation/templates/index.js index b00c1552b..3c90a68fd 100644 --- a/ui/app/pages/confirmation/templates/index.js +++ b/ui/app/pages/confirmation/templates/index.js @@ -12,6 +12,10 @@ const APPROVAL_TEMPLATES = { [MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN]: switchEthereumChain, }; +export const TEMPLATED_CONFIRMATION_MESSAGE_TYPES = Object.keys( + APPROVAL_TEMPLATES, +); + const ALLOWED_TEMPLATE_KEYS = [ 'content', 'approvalText', diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js index 3f9c14caa..84ecd217f 100644 --- a/ui/app/pages/home/home.component.js +++ b/ui/app/pages/home/home.component.js @@ -73,7 +73,7 @@ export default class Home extends PureComponent { setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired, originOfCurrentTab: PropTypes.string, disableWeb3ShimUsageAlert: PropTypes.func.isRequired, - pendingApprovals: PropTypes.arrayOf(PropTypes.object).isRequired, + pendingConfirmations: PropTypes.arrayOf(PropTypes.object).isRequired, }; state = { @@ -91,7 +91,7 @@ export default class Home extends PureComponent { haveSwapsQuotes, showAwaitingSwapScreen, swapsFetchParams, - pendingApprovals, + pendingConfirmations, } = this.props; this.setState({ mounted: true }); @@ -109,7 +109,7 @@ export default class Home extends PureComponent { history.push(CONFIRM_TRANSACTION_ROUTE); } else if (Object.keys(suggestedTokens).length > 0) { history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE); - } else if (pendingApprovals.length > 0) { + } else if (pendingConfirmations.length > 0) { history.push(CONFIRMATION_V_NEXT_ROUTE); } } diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js index 3a9422486..929833e14 100644 --- a/ui/app/pages/home/home.container.js +++ b/ui/app/pages/home/home.container.js @@ -8,6 +8,7 @@ import { getIsMainnet, getOriginOfCurrentTab, getTotalUnapprovedCount, + getUnapprovedTemplatedConfirmations, getWeb3ShimUsageStateForOrigin, unconfirmedTransactionsCountSelector, } from '../../selectors'; @@ -52,12 +53,12 @@ const mapStateToProps = (state) => { connectedStatusPopoverHasBeenShown, defaultHomeActiveTabName, swapsState, - pendingApprovals = {}, } = metamask; const accountBalance = getCurrentEthBalance(state); const { forgottenPassword, threeBoxLastUpdated } = appState; const totalUnapprovedCount = getTotalUnapprovedCount(state); const swapsEnabled = getSwapsFeatureLiveness(state); + const pendingConfirmations = getUnapprovedTemplatedConfirmations(state); const envType = getEnvironmentType(); const isPopup = envType === ENVIRONMENT_TYPE_POPUP; @@ -102,7 +103,7 @@ const mapStateToProps = (state) => { isMainnet: getIsMainnet(state), originOfCurrentTab, shouldShowWeb3ShimUsageNotification, - pendingApprovals: Object.values(pendingApprovals), + pendingConfirmations, }; }; diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 550c45983..006d0a892 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -19,6 +19,7 @@ import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP, ALLOWED_SWAPS_CHAIN_IDS, } from '../../../shared/constants/swaps'; +import { TEMPLATED_CONFIRMATION_MESSAGE_TYPES } from '../pages/confirmation/templates'; /** * One of the only remaining valid uses of selecting the network subkey of the @@ -325,6 +326,13 @@ export function getUnapprovedConfirmations(state) { return Object.values(pendingApprovals); } +export function getUnapprovedTemplatedConfirmations(state) { + const unapprovedConfirmations = getUnapprovedConfirmations(state); + return unapprovedConfirmations.filter((approval) => + TEMPLATED_CONFIRMATION_MESSAGE_TYPES.includes(approval.type), + ); +} + function getSuggestedTokenCount(state) { const { suggestedTokens = {} } = state.metamask; return Object.keys(suggestedTokens).length; From 5bed62b1b3fdfb143738fa2920f8ee365d2cbf6d Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 24 Mar 2021 12:45:28 -0230 Subject: [PATCH 32/82] Add MetaMask to list of BIP44 HD path examples (#10703) The "BIP44 Standard" HD path option in the Ledger connect flow listed only Trezor as an example. It seemed appropriate to include MetaMask as well, since we use the same path. This helps users who have imported their MetaMask seed phrase onto a Ledger device to discover this option. --- ui/app/pages/create-account/connect-hardware/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/pages/create-account/connect-hardware/index.js b/ui/app/pages/create-account/connect-hardware/index.js index 20aacb9aa..67051c213 100644 --- a/ui/app/pages/create-account/connect-hardware/index.js +++ b/ui/app/pages/create-account/connect-hardware/index.js @@ -21,7 +21,7 @@ const BIP44_PATH = `m/44'/60'/0'/0`; const HD_PATHS = [ { name: 'Ledger Live', value: LEDGER_LIVE_PATH }, { name: 'Legacy (MEW / MyCrypto)', value: MEW_PATH }, - { name: `BIP44 Standard (e.g. Trezor)`, value: BIP44_PATH }, + { name: `BIP44 Standard (e.g. MetaMask, Trezor)`, value: BIP44_PATH }, ]; class ConnectHardwareForm extends Component { From 1cfa58287c46db02f8873f853c25e9fce18f7cc5 Mon Sep 17 00:00:00 2001 From: ryanml Date: Wed, 24 Mar 2021 10:55:03 -0700 Subject: [PATCH 33/82] Removing hard references to 12 word seed phrases in copy (#10704) Adding translation entry for "Wallet Seed" Fixed label padding issue by adding missing CSS rule --- app/_locales/am/messages.json | 6 ------ app/_locales/ar/messages.json | 6 ------ app/_locales/bg/messages.json | 6 ------ app/_locales/bn/messages.json | 6 ------ app/_locales/ca/messages.json | 6 ------ app/_locales/cs/messages.json | 3 --- app/_locales/da/messages.json | 6 ------ app/_locales/de/messages.json | 6 ------ app/_locales/el/messages.json | 6 ------ app/_locales/en/messages.json | 7 +++++-- app/_locales/es/messages.json | 6 ------ app/_locales/es_419/messages.json | 6 ------ app/_locales/et/messages.json | 6 ------ app/_locales/fa/messages.json | 6 ------ app/_locales/fi/messages.json | 6 ------ app/_locales/fil/messages.json | 6 ------ app/_locales/fr/messages.json | 6 ------ app/_locales/he/messages.json | 6 ------ app/_locales/hi/messages.json | 6 ------ app/_locales/hn/messages.json | 3 --- app/_locales/hr/messages.json | 6 ------ app/_locales/ht/messages.json | 3 --- app/_locales/hu/messages.json | 6 ------ app/_locales/id/messages.json | 6 ------ app/_locales/it/messages.json | 6 ------ app/_locales/ja/messages.json | 6 ------ app/_locales/kn/messages.json | 6 ------ app/_locales/ko/messages.json | 6 ------ app/_locales/lt/messages.json | 6 ------ app/_locales/lv/messages.json | 6 ------ app/_locales/ms/messages.json | 6 ------ app/_locales/nl/messages.json | 3 --- app/_locales/no/messages.json | 6 ------ app/_locales/pl/messages.json | 6 ------ app/_locales/pt/messages.json | 3 --- app/_locales/pt_BR/messages.json | 6 ------ app/_locales/ro/messages.json | 6 ------ app/_locales/ru/messages.json | 6 ------ app/_locales/sk/messages.json | 6 ------ app/_locales/sl/messages.json | 6 ------ app/_locales/sr/messages.json | 6 ------ app/_locales/sv/messages.json | 6 ------ app/_locales/sw/messages.json | 6 ------ app/_locales/ta/messages.json | 3 --- app/_locales/th/messages.json | 3 --- app/_locales/tl/messages.json | 6 ------ app/_locales/tr/messages.json | 3 --- app/_locales/uk/messages.json | 6 ------ app/_locales/vi/messages.json | 6 ------ app/_locales/zh_CN/messages.json | 6 ------ app/_locales/zh_TW/messages.json | 6 ------ ui/app/pages/keychains/index.scss | 6 ++++++ ui/app/pages/keychains/restore-vault.js | 4 +++- 53 files changed, 14 insertions(+), 279 deletions(-) diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index cc697e452..ad11dad20 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "ቋት አስመጣ" }, - "importYourExisting": { - "message": "ባለ 12 ቃል የዘር ሐረግን በመጠቀም ነባር ቋትዎን ያስመጡ" - }, "imported": { "message": "ከውጭ የመጣ", "description": "status showing that an account has been fully loaded into the keyring" @@ -892,9 +889,6 @@ "secretBackupPhraseWarning": { "message": "ማስጠንቀቂያ፡ የመጠባበቂያ ምዕራፍዎን በጭራሽ አይግለጹ። ይህን ሐረገ የያዘ ማንኛውም ሰው የእርስዎን Ether እስከወዲያኛው ሊወስደው ይችላል።" }, - "secretPhrase": { - "message": "ካዝናዎን ወደነበረበት ለመመለስ ሚስጥራዊ ባለ አስራ ሁለት ቃል ሐረግዎን ያስገቡ።" - }, "securityAndPrivacy": { "message": "ደህንነት እና ግላዊነት" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 54095520a..82a2efd8c 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "استيراد المحفظة" }, - "importYourExisting": { - "message": "قم باستيراد محفظتك الحالية باستخدام جملة بذرية مكونة من 12 كلمة" - }, "imported": { "message": "المستوردة", "description": "status showing that an account has been fully loaded into the keyring" @@ -888,9 +885,6 @@ "secretBackupPhraseWarning": { "message": "تحذير: لا تكشف مطلقاً عن عبارة الدعم الخاصة بك. يمكن لأي شخص بهذه العبارة أن يستحوذ على الأثير الخاص بك إلى الأبد." }, - "secretPhrase": { - "message": "أدخل جملتك السرية المكونة من اثني عشر كلمة هنا لاستعادة خزنتك." - }, "securityAndPrivacy": { "message": "الأمن والخصوصية" }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index a443e38d1..119d630f3 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "Импортиране на портфейла" }, - "importYourExisting": { - "message": "Импортирайте съществуващия си портфейл с помощта на фраза зародиш с 12 думи" - }, "imported": { "message": "Импортирани", "description": "status showing that an account has been fully loaded into the keyring" @@ -891,9 +888,6 @@ "secretBackupPhraseWarning": { "message": "ВНИМАНИЕ: Никога не разкривайте резервната си фраза. Всеки с тази фраза може да вземе вашия етер завинаги." }, - "secretPhrase": { - "message": "Въведете своята тайна фраза от дванадесет думи тук, за да възстановите портфейла си." - }, "securityAndPrivacy": { "message": "Сигурност и поверителност" }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index f87c0d6dd..8069ae92d 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "ওয়ালেট আমদানি করুন" }, - "importYourExisting": { - "message": "একটি 12 শব্দের সীড ফ্রেজ ব্যবহার করে আপনার বিদ্যমান ওয়ালেট আমদানি করুন" - }, "imported": { "message": "আমদানিকৃত", "description": "status showing that an account has been fully loaded into the keyring" @@ -895,9 +892,6 @@ "secretBackupPhraseWarning": { "message": "সতর্কতা: কখনও আপনার ব্যাকআপ ফ্রেজ প্রকাশ করবেন না। এই ফ্রেজ পেয়ে গেলে যে কেউ আপনার ইথার চিরকালের জন্য নিয়ে নিতে পারবেন।" }, - "secretPhrase": { - "message": "আপনার ভল্ট রিস্টোর করতে এখানে আপনার গোপন বারো শব্দের ফ্রেজ লিখুন।" - }, "securityAndPrivacy": { "message": "নিরাপত্তা এবং গোপনীয়তা" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index cff905794..9e5030e14 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -492,9 +492,6 @@ "importWallet": { "message": "Importar Moneder" }, - "importYourExisting": { - "message": "Importa el teu moneder utilitzant la frase de recuperació de 12 paraules" - }, "imported": { "message": "Importats", "description": "status showing that an account has been fully loaded into the keyring" @@ -873,9 +870,6 @@ "secretBackupPhraseWarning": { "message": "ATENCIÓ: No divulguis mai la teva frase de recuperació. Qualsevol amb aquesta frase pot utilitzar el teu Ether per sempre." }, - "secretPhrase": { - "message": "Introdueix aquí la teva frase secreta de dotze paraules per a recuperar la teva caixa forta." - }, "securityAndPrivacy": { "message": "Seguretat i privacitat" }, diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json index f24aaf824..7ac69c33e 100644 --- a/app/_locales/cs/messages.json +++ b/app/_locales/cs/messages.json @@ -344,9 +344,6 @@ "searchTokens": { "message": "Hledat tokeny" }, - "secretPhrase": { - "message": "Zadejte svých 12 slov tajné fráze k obnovení trezoru." - }, "seedPhraseReq": { "message": "klíčové fráze mají 12 slov" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index e558751ba..8a2d0abdf 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -498,9 +498,6 @@ "importWallet": { "message": "Importér pung" }, - "importYourExisting": { - "message": "Importér din eksisterende pung med en 12-ords seedfrase" - }, "imported": { "message": "Importeret", "description": "status showing that an account has been fully loaded into the keyring" @@ -876,9 +873,6 @@ "secretBackupPhraseWarning": { "message": "ADVARSEL: Afslør aldrig din backup-frase. Enhver med denne frase kan tage din Ether for altid." }, - "secretPhrase": { - "message": "Indtast din hemmelige tolv ord lange sætning for at gendanne din vault." - }, "securityAndPrivacy": { "message": "Sikkerhed & Privatliv" }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 6db35e4d3..67ffd7a1d 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -493,9 +493,6 @@ "importWallet": { "message": "Wallet importieren" }, - "importYourExisting": { - "message": "Importieren Sie Ihre bestehende Wallet mit einem 12-Wort-Seed-Schlüssel" - }, "imported": { "message": "Importiert", "description": "status showing that an account has been fully loaded into the keyring" @@ -864,9 +861,6 @@ "secretBackupPhraseWarning": { "message": "WARNUNG: Legen Sie niemals Ihre Sicherungsphrase offen. Mit dieser Phrase kann sich jeder Ihr Ether für immer aneignen." }, - "secretPhrase": { - "message": "Gib die 12 Wörter deiner geheimem Wörterfolge ein um deinen Vault wiederherzustellen." - }, "securityAndPrivacy": { "message": "Sicherheit & Datenschutz" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 25fd175e5..48bac1c13 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -502,9 +502,6 @@ "importWallet": { "message": "Εισαγωγή Πορτοφολιού" }, - "importYourExisting": { - "message": "Εισαγάγετε το υπάρχον πορτοφόλι σας χρησιμοποιώντας μια φράση φύτρου 12 λέξεων" - }, "imported": { "message": "Έγινε εισαγωγή", "description": "status showing that an account has been fully loaded into the keyring" @@ -892,9 +889,6 @@ "secretBackupPhraseWarning": { "message": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Ποτέ μην αποκαλύπτετε την εφεδρική φράση. Όποιος έχει αυτή τη φράση μπορεί να πάρει τα Ether σας για πάντα." }, - "secretPhrase": { - "message": "Εισαγάγετε εδώ τη μυστική φράση δώδεκα λέξεων για να επαναφέρετε το χρηματοκιβώτιό σας." - }, "securityAndPrivacy": { "message": "Ασφάλεια και Απόρρητο" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 53b47fcda..4f11a75c2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -873,7 +873,7 @@ "message": "Import wallet" }, "importYourExisting": { - "message": "Import your existing wallet using a 12 word seed phrase" + "message": "Import your existing wallet using a seed phrase" }, "imported": { "message": "Imported", @@ -1455,7 +1455,7 @@ "message": "WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever." }, "secretPhrase": { - "message": "Enter your secret twelve word phrase here to restore your vault." + "message": "Enter your secret phrase here to restore your vault." }, "securityAndPrivacy": { "message": "Security & Privacy" @@ -2218,6 +2218,9 @@ "walletSeed": { "message": "Seed phrase" }, + "walletSeedRestore": { + "message": "Wallet Seed" + }, "web3ShimUsageNotification": { "message": "We noticed that the current website tried to use the removed window.web3 API. If the site appears to be broken, please click $1 for more information.", "description": "$1 is a clickable link." diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 5d2501941..bced8493f 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -800,9 +800,6 @@ "importWallet": { "message": "Importar Monedero" }, - "importYourExisting": { - "message": "Importa tu monedero existente usando la frase semilla de 12 palabras" - }, "imported": { "message": "Importado", "description": "status showing that an account has been fully loaded into the keyring" @@ -1359,9 +1356,6 @@ "secretBackupPhraseWarning": { "message": "ADVERTENCIA: Nunca revele su frase de respaldo. Cualquiera con esta frase puede tomar su Ether para siempre." }, - "secretPhrase": { - "message": "Ingresa tu frase de doce (12) palabras para restaurar tu bóveda." - }, "securityAndPrivacy": { "message": "Seguridad y Privacidad" }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 237e063ff..14efe2258 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -800,9 +800,6 @@ "importWallet": { "message": "Importar billetera" }, - "importYourExisting": { - "message": "Importa tu billetera existente con una frase semilla de 12 palabras" - }, "imported": { "message": "Importado", "description": "status showing that an account has been fully loaded into the keyring" @@ -1359,9 +1356,6 @@ "secretBackupPhraseWarning": { "message": "ADVERTENCIA: Nunca reveles tu frase de respaldo. Cualquier persona que tenga acceso a esta frase puede llevarse tus Ether permanentemente." }, - "secretPhrase": { - "message": "Ingresa tu frase secreta de doce palabras para restaurar tu almacén." - }, "securityAndPrivacy": { "message": "Seguridad y privacidad" }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 4908192e1..a005f48e5 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "Importige rahakott" }, - "importYourExisting": { - "message": "Importige 12-sõnalise seemnefraasi abil olemasolev rahakott" - }, "imported": { "message": "Imporditud", "description": "status showing that an account has been fully loaded into the keyring" @@ -885,9 +882,6 @@ "secretBackupPhraseWarning": { "message": "HOIATUS! Ärge avaldage kunagi oma varundusfraasi. Selle fraasiga on võimalik teie eeter igaveseks ära võtta." }, - "secretPhrase": { - "message": "Sisestage hoidla taastamiseks oma salajane 12-sõnaline fraas." - }, "securityAndPrivacy": { "message": "Turvalisus ja privaatsus" }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index e9eee1ddf..a6ae259fe 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "وارد سازی کیف" }, - "importYourExisting": { - "message": "کیف موجود تان را با استفاده از عبارت رمزیاب 12 کلمه یی وارد کنید" - }, "imported": { "message": "وارد شده", "description": "status showing that an account has been fully loaded into the keyring" @@ -895,9 +892,6 @@ "secretBackupPhraseWarning": { "message": "هشدار: هرگز عبارت پشتیبان تان را به کسی فاش نسازید. هرکسیکه این عبارت را داشته باشد ایتر شما را برای همیشه خواهد گرفت." }, - "secretPhrase": { - "message": "جهت بازیابی خزانه تان عبارت دوازده کلمه یی تان را اینجا وارد کنید." - }, "securityAndPrivacy": { "message": "امنیت و حریم خصوصی" }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index e8c5ec0d0..429f23fc0 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "Tuo kukkaro" }, - "importYourExisting": { - "message": "Tuo nykyinen lompakkosi käyttäen 12 sanan \n siemenlausetta" - }, "imported": { "message": "Tuotu", "description": "status showing that an account has been fully loaded into the keyring" @@ -892,9 +889,6 @@ "secretBackupPhraseWarning": { "message": "VAROITUS: älä koskaan kerro varmuuskopiolausettasi kenellekään. Kuka tahansa tämän lauseen omaava voi napata Etherisi pysyvästi." }, - "secretPhrase": { - "message": "Palauta holvisi syöttämällä tähän salainen kahdentoista sanan tekstisi." - }, "securityAndPrivacy": { "message": "Turva & yksityisyys" }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 16a07e99b..24ee12687 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -462,9 +462,6 @@ "importWallet": { "message": "Mag-import ng Wallet" }, - "importYourExisting": { - "message": "I-import ang kasalukuyan mong wallet gamit ang isang seed phrase na may 12 salita" - }, "imported": { "message": "Na-import", "description": "status showing that an account has been fully loaded into the keyring" @@ -807,9 +804,6 @@ "secretBackupPhraseWarning": { "message": "BABALA: Huwag ibunyag ang iyong backup phrase. Mananakaw ng kahit sinong may ganitong parirala ang iyong Ether at hindi na ito maibabalik." }, - "secretPhrase": { - "message": "Ilagay ang iyong lihim na pariralang may labindalawang salita para ma-restore ang iyong vault." - }, "securityAndPrivacy": { "message": "Seguridad at Privacy" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index ca0791341..23808a1b5 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -496,9 +496,6 @@ "importWallet": { "message": "Importer le portefeuille" }, - "importYourExisting": { - "message": "Importez votre portefeuille existant à l'aide d'une phrase mnémotechnique de 12 mots" - }, "imported": { "message": "Importé", "description": "status showing that an account has been fully loaded into the keyring" @@ -877,9 +874,6 @@ "secretBackupPhraseWarning": { "message": "AVERTISSEMENT : ne révélez jamais votre phrase de sauvegarde. N'importe qui avec cette phrase peut voler votre Ether pour toujours." }, - "secretPhrase": { - "message": "Entrez vos 12 mots secrets de votre phrase Seed pour restaurer votre coffre." - }, "securityAndPrivacy": { "message": "Sécurité et confidentialité" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index 5f0fa2ba3..319424a46 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "ייבא ארנק" }, - "importYourExisting": { - "message": "יבא/י את הארנק הקיים שלך באמצעות seed phrase בן 12 מילים" - }, "imported": { "message": "מיובאות", "description": "status showing that an account has been fully loaded into the keyring" @@ -889,9 +886,6 @@ "secretBackupPhraseWarning": { "message": "אזהרה: לעולם אין לחשוף את צירוף הגיבוי שלך. כל מי שברשותו צירוף זה יכול לקחת את האת'ר שלך לצמיתות." }, - "secretPhrase": { - "message": "הזנ/י את הצירוף הסודי שלך של שתים-עשרה המילים כאן כדי לשחזר את הכספת שלך." - }, "securityAndPrivacy": { "message": "אבטחה ופרטיות" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 74b404bdb..4af8b5008 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "वॉलेट आयात करें" }, - "importYourExisting": { - "message": "12 शब्द के सीडफ्रेज़ का उपयोग करके अपने मौजूदा वॉलेट को आयात करें" - }, "imported": { "message": "आयातित", "description": "status showing that an account has been fully loaded into the keyring" @@ -1350,9 +1347,6 @@ "secretBackupPhraseWarning": { "message": "चेतावनी: कभी भी अपने बैकअप वाक्यांश का खुलासा न करें। इस वाक्यांश के साथ कोई भी आपके Ether को हमेशा के लिए ले सकता है।" }, - "secretPhrase": { - "message": "अपनी तिजोरी को पुनर्स्थापित करने के लिए अपने गुप्त बारह शब्द वाक्यांश को यहाँ दर्ज करें।" - }, "securityAndPrivacy": { "message": "सुरक्षा और गोपनीयता" }, diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json index a2cef557d..9963ac5ec 100644 --- a/app/_locales/hn/messages.json +++ b/app/_locales/hn/messages.json @@ -324,9 +324,6 @@ "search": { "message": "खोज करें" }, - "secretPhrase": { - "message": "अपनी गुप्त बारह शब्द वाक्यांश यहाँ अपनी तिजोरी को पुनर्स्थापित करने के लिए दर्ज करें।" - }, "seedPhraseReq": { "message": "बीज वाक्यांश 12 शब्द लंबा हैं" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index 959d7dc77..91f88331a 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "Uvezi novčanik" }, - "importYourExisting": { - "message": "Uvezite svoj postojeći novčanik početnom rečenicom od 12 riječi" - }, "imported": { "message": "Uvezeno", "description": "status showing that an account has been fully loaded into the keyring" @@ -888,9 +885,6 @@ "secretBackupPhraseWarning": { "message": "UPOZORENJE: nikada ne otkrivajte svoju alternativnu rečenicu. Bilo tko ovom rečenicom može zauvijek preuzeti vaš Ether." }, - "secretPhrase": { - "message": "Ovdje upišite svoju tajnu rečenicu od 12 riječi kako biste obnovili svoj sef." - }, "securityAndPrivacy": { "message": "Sigurnost i privatnost" }, diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json index 2b6e4b063..0c427dbb6 100644 --- a/app/_locales/ht/messages.json +++ b/app/_locales/ht/messages.json @@ -561,9 +561,6 @@ "searchTokens": { "message": "Rechèch Tokens" }, - "secretPhrase": { - "message": "Antre fraz sekrè douz mo ou a pou w restore kòf ou a." - }, "seedPhraseReq": { "message": "Seed fraz yo se 12 long mo" }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index 1089ce3c6..6cd093e4d 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "Pénztárca importálása" }, - "importYourExisting": { - "message": "Importálja meglévő pénztárcáját a 12 szóból álló seed mondat segítségével" - }, "imported": { "message": "Importált", "description": "status showing that an account has been fully loaded into the keyring" @@ -888,9 +885,6 @@ "secretBackupPhraseWarning": { "message": "FIGYELEM: Senkise se adja meg a biztonsági szakaszát. Ennek tulajdonosa örökre elviheti Ether-jeit." }, - "secretPhrase": { - "message": "Tárolód helyreállításához írd be titkos tizenkét szavas szókapcsolatodat ide." - }, "securityAndPrivacy": { "message": "Biztonság és adatvédelem" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 768543c3e..a2505c17d 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "Impor dompet" }, - "importYourExisting": { - "message": "Impor dompet Anda yang ada menggunakan frasa pemulihan 12 kata" - }, "imported": { "message": "Diimpor", "description": "status showing that an account has been fully loaded into the keyring" @@ -1350,9 +1347,6 @@ "secretBackupPhraseWarning": { "message": "PERINGATAN: Jangan pernah ungkapkan frasa cadangan Anda. Siapa pun yang memiliki frasa ini dapat mengambil Ether Anda selamanya." }, - "secretPhrase": { - "message": "Masukkan frasa kata dua belas rahasia Anda di sini untuk memulihkan vault Anda." - }, "securityAndPrivacy": { "message": "Keamanan & Privasi" }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index c924cc30d..b5aaab033 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -803,9 +803,6 @@ "importWallet": { "message": "Importa Portafoglio" }, - "importYourExisting": { - "message": "Importa il tuo portafoglio esistente usando la tua frase seed a 12 parole" - }, "imported": { "message": "Importato", "description": "status showing that an account has been fully loaded into the keyring" @@ -1365,9 +1362,6 @@ "secretBackupPhraseWarning": { "message": "ATTENZIONE: Non dire mai a nessuno questa frase di backup. Chiunque con questa frase può rubare i tuoi Ether per sempre." }, - "secretPhrase": { - "message": "Inserisci la tua frase segreta di dodici parole per ripristinare la cassaforte." - }, "securityAndPrivacy": { "message": "Sicurezza & Privacy" }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 020d6b7b1..732166a40 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -800,9 +800,6 @@ "importWallet": { "message": "ウォレットのインポート" }, - "importYourExisting": { - "message": "12単語のシードフレーズを使用して既存のウォレットをインポートします" - }, "imported": { "message": "インポート済", "description": "status showing that an account has been fully loaded into the keyring" @@ -1359,9 +1356,6 @@ "secretBackupPhraseWarning": { "message": "警告:シードフレーズは絶対に公開しないでください。シードフレーズを使うと、誰でもアカウントからETHを盗み出せます。" }, - "secretPhrase": { - "message": "アカウント情報を復元するには、12単語で構成されたシードフレーズを入力してください。" - }, "securityAndPrivacy": { "message": "セキュリティとプライバシー" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index 32d24c6d7..f895c1f9a 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "ವ್ಯಾಲೆಟ್ ಅನ್ನು ಆಮದು ಮಾಡಿ" }, - "importYourExisting": { - "message": "12 ಪದದ ಸೀಡ್ ಫ್ರೇಸ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ವ್ಯಾಲೆಟ್ ಅನ್ನು ಆಮದು ಮಾಡಿ" - }, "imported": { "message": "ಆಮದುಮಾಡಲಾಗಿದೆ", "description": "status showing that an account has been fully loaded into the keyring" @@ -895,9 +892,6 @@ "secretBackupPhraseWarning": { "message": "ಎಚ್ಚರಿಕೆ: ನಿಮ್ಮ ಬ್ಯಾಕಪ್ ಫ್ರೇಸ್ ಅನ್ನು ಎಂದಿಗೂ ಬಹಿರಗಪಡಿಸಬೇಡಿ. ಈ ಫ್ರೇಸ್ ಅನ್ನು ಹೊಂದಿರುವ ಯಾರಾದರೂ ನಿಮ್ಮ ಎಥರ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ತೆಗೆದುಕೊಳ್ಳಬಹುದು." }, - "secretPhrase": { - "message": "ನಿಮ್ಮ ವಾಲ್ಟ್ ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಲು ನಿಮ್ಮ ರಹಸ್ಯ ಹನ್ನೆರಡು ಪದದ ಫ್ರೇಸ್ ಅನ್ನು ಇಲ್ಲಿ ನಮೂದಿಸಿ." - }, "securityAndPrivacy": { "message": "ಭದ್ರತೆ ಮತ್ತು ಗೌಪ್ಯತೆ" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 9a1bb146f..de7953333 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "지갑 가져오기" }, - "importYourExisting": { - "message": "12단어 시드 구문을 사용하여 지갑 가져오기" - }, "imported": { "message": "가져옴", "description": "status showing that an account has been fully loaded into the keyring" @@ -1347,9 +1344,6 @@ "secretBackupPhraseWarning": { "message": "경고: 백업 구문은 절대로 공개하지 마세요. 이 구문이 있는 사람은 귀하의 Ether를 영원히 소유할 수 있습니다." }, - "secretPhrase": { - "message": "금고를 복구하려면 비밀 12단어 구문을 여기에 입력하세요." - }, "securityAndPrivacy": { "message": "보안 및 개인정보 보호" }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index 4e20c2812..09183e9a1 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "Importuoti slaptažodinę" }, - "importYourExisting": { - "message": "Importuoti turimą piniginę naudojant 12 žodžių atkūrimo frazę" - }, "imported": { "message": "Importuota", "description": "status showing that an account has been fully loaded into the keyring" @@ -895,9 +892,6 @@ "secretBackupPhraseWarning": { "message": "ĮSPĖJIMAS. Niekada neatskleiskite savo atsarginės frazės. Bet kas, žinantis šią frazę, gali visiems laikams pasiimti jūsų eterius." }, - "secretPhrase": { - "message": "Savo saugyklai atkurti įveskite slaptą dvylikos žodžių frazę." - }, "securityAndPrivacy": { "message": "Sauga ir privatumas" }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 72d09faff..dc02d1c31 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -501,9 +501,6 @@ "importWallet": { "message": "Importēt maku" }, - "importYourExisting": { - "message": "Importējiet esošo maku, izmantojot 12 vārdu atkopšanas frāzi" - }, "imported": { "message": "Importēts", "description": "status showing that an account has been fully loaded into the keyring" @@ -891,9 +888,6 @@ "secretBackupPhraseWarning": { "message": "BRĪDINĀJUMS! Nekādā gadījumā neizpaudiet savu rezerves frāzi. Ikviens, kam pieejama šī frāze, var uz visiem laikiem pārņemt jūsu Ether." }, - "secretPhrase": { - "message": "Ievadiet šeit slepeno divpadsmit vārdu frāzi, lai atjaunotu savu seifu." - }, "securityAndPrivacy": { "message": "Drošība un konfidencialitāte" }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index dd3c3cfd7..3bbd5a019 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -491,9 +491,6 @@ "importWallet": { "message": "Import Dompet" }, - "importYourExisting": { - "message": "Import dompet sedia ada anda menggunakan frasa benih 12 perkataan" - }, "imported": { "message": "Diimport", "description": "status showing that an account has been fully loaded into the keyring" @@ -872,9 +869,6 @@ "secretBackupPhraseWarning": { "message": "AMARAN: Jangan sesekali dedahkan frasa sandaran anda. Sesiapa yang memperoleh frasa ini boleh mengambil Ether anda selama-lamanya." }, - "secretPhrase": { - "message": "Masukkan ungkapan rahsia dua belas perkataan di sini untuk memulihkan kekubah anda." - }, "securityAndPrivacy": { "message": "Keselamatan & Privasi" }, diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json index 6db2439eb..f25182de5 100644 --- a/app/_locales/nl/messages.json +++ b/app/_locales/nl/messages.json @@ -311,9 +311,6 @@ "search": { "message": "Zoeken" }, - "secretPhrase": { - "message": "Voer hier je geheime twaalfwoordfrase in om je kluis te herstellen." - }, "seedPhraseReq": { "message": "Back-up woorden zijn 12 woorden lang" }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 8489dff4f..5dd774f1a 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -492,9 +492,6 @@ "importWallet": { "message": "Importér lommebok " }, - "importYourExisting": { - "message": "Importer din eksisterende lommebok ved å bruk en tolvords seed-frase." - }, "imported": { "message": "Importert", "description": "status showing that an account has been fully loaded into the keyring" @@ -879,9 +876,6 @@ "secretBackupPhraseWarning": { "message": "ADVARSEL: Du må aldri avsløre gjenopprettingsfrasen din. Alle som har denne frasen kan ta fra deg Etheren din for alltid." }, - "secretPhrase": { - "message": "Skriv inn den tolv ord lange frasen her for å gjenopprette hvelvet ditt. " - }, "securityAndPrivacy": { "message": "Sikkerhet og personvern" }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 484e53c91..52817a88b 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "Importuj portfel" }, - "importYourExisting": { - "message": "Zaimportuj istniejący portfel, wprowadzając 12 słów frazy seed" - }, "imported": { "message": "Zaimportowane", "description": "status showing that an account has been fully loaded into the keyring" @@ -889,9 +886,6 @@ "secretBackupPhraseWarning": { "message": "OSTRZEŻENIE: Nigdy nie ujawniaj swojej frazy zapasowej. Każdy, kto pozna tę frazę, może bezpowrotnie odebrać Ci kryptowalutę Ether." }, - "secretPhrase": { - "message": "Żeby otworzyć schowek, wpisz tutaj swoją frazę dwunastu słów." - }, "securityAndPrivacy": { "message": "Bezpieczeństwo i prywatność" }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 0a3367d59..b21e04ef8 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -321,9 +321,6 @@ "search": { "message": "Procurar" }, - "secretPhrase": { - "message": "Introduza a sua frase secreta de 12 palavras para recuperar o seu ." - }, "seedPhraseReq": { "message": "seed phrases are 12 words long" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 6c2eb760a..6f6bba07b 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -499,9 +499,6 @@ "importWallet": { "message": "Importar Carteira" }, - "importYourExisting": { - "message": "Importe sua carteira existente usando uma frase-semente de 12 palavras" - }, "imported": { "message": "Importado", "description": "status showing that an account has been fully loaded into the keyring" @@ -883,9 +880,6 @@ "secretBackupPhraseWarning": { "message": "ATENÇÃO: Nunca revele sua frase de backup a ninguém. Qualquer pessoa com essa frase pode obter seu Ether para sempre." }, - "secretPhrase": { - "message": "Digite sua frase secreta de doze palavras aqui para restaurar seu cofre." - }, "securityAndPrivacy": { "message": "Segurança & Privacidade" }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index e697a4227..3c475cd25 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -495,9 +495,6 @@ "importWallet": { "message": "Importați portofel" }, - "importYourExisting": { - "message": "Importați portofelul existent folosind o frază seed de 12 cuvinte" - }, "imported": { "message": "Importate", "description": "status showing that an account has been fully loaded into the keyring" @@ -882,9 +879,6 @@ "secretBackupPhraseWarning": { "message": "ATENȚIE: Nu dezvăluiți niciodată expresia dvs. de rezervă. Oricine are această expresie vă poate lua Ether-ul pentru totdeauna." }, - "secretPhrase": { - "message": "Introduceți aici expresia dvs. secretă din 12 cuvinte pentru a restabili seiful." - }, "securityAndPrivacy": { "message": "Securitate și confidențialitate" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 42f94bae9..df22aa710 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "Импортировать кошелек" }, - "importYourExisting": { - "message": "Импортируйте существующий кошелек, используя начальную фразу из 12 слов" - }, "imported": { "message": "Импортированный", "description": "status showing that an account has been fully loaded into the keyring" @@ -1350,9 +1347,6 @@ "secretBackupPhraseWarning": { "message": "ПРЕДУПРЕЖДЕНИЕ: Никогда не разглашайте резервную фразу. Любой, у кого есть эта фраза, может забрать ваш Ether навсегда." }, - "secretPhrase": { - "message": "Введите здесь свою секретную фразу из двенадцати слов, чтобы восстановить свой сейф." - }, "securityAndPrivacy": { "message": "Безопасность и конфиденциальность" }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 5d2cb5be7..7769ddd3b 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -492,9 +492,6 @@ "importWallet": { "message": "Importovať Peňaženku" }, - "importYourExisting": { - "message": "Importujte svoju existujúcu peňaženku pomocou 12-slovnej seed frázy" - }, "imported": { "message": "Importováno", "description": "status showing that an account has been fully loaded into the keyring" @@ -858,9 +855,6 @@ "secretBackupPhraseWarning": { "message": "UPOZORNENIE: Nikdy nezverejňujte svoju backup frázu. Každý, kto má túto frázu, môže navždy vziať váš Ether." }, - "secretPhrase": { - "message": "Zadejte svých 12 slov tajné fráze k obnovení trezoru." - }, "securityAndPrivacy": { "message": "Bezpečnosť a súkromie" }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 6cb1434df..8392f0a64 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -496,9 +496,6 @@ "importWallet": { "message": "Uvozi denarnico" }, - "importYourExisting": { - "message": "Uvozite svojo obstoječo denarnico s pomočjo 12-besednega gesla seed phrase" - }, "imported": { "message": "Uvoženo", "description": "status showing that an account has been fully loaded into the keyring" @@ -877,9 +874,6 @@ "secretBackupPhraseWarning": { "message": "OPOZORILO: Nikoli nikomur ne razkrijte varnostne kopije. Kdorkoli lahko tem geslom vedno prevzame vaš Ether." }, - "secretPhrase": { - "message": "Vnesite vaših dvanajst besed za obnovitev vaših računov." - }, "securityAndPrivacy": { "message": "Varnost in zasebnost" }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index 1409dc795..b094ddd2d 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -502,9 +502,6 @@ "importWallet": { "message": "Uvezite novčanik" }, - "importYourExisting": { - "message": "Uvezite vaš postojeći novčanik koristeći seed frazu sa 12 reči" - }, "imported": { "message": "Увезени", "description": "status showing that an account has been fully loaded into the keyring" @@ -886,9 +883,6 @@ "secretBackupPhraseWarning": { "message": "UPOZORENJE: Nikada ne otkrivajte svoju rezervnu frazu. Svako sa ovom frazom može zauvek da Vam uzme Vaš Ether." }, - "secretPhrase": { - "message": "Unesite ovde svoj tajni izraz od dvanaest reči kako biste povratili svoj trezor." - }, "securityAndPrivacy": { "message": "Bezbednost i privatnost" }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index c9552fa0b..c7af7fdde 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -495,9 +495,6 @@ "importWallet": { "message": "Importera plånbok" }, - "importYourExisting": { - "message": "Importera din existerande plånbok med hjälp av en 12 ord lång seedfras" - }, "imported": { "message": "Importerade", "description": "status showing that an account has been fully loaded into the keyring" @@ -879,9 +876,6 @@ "secretBackupPhraseWarning": { "message": "VARNING: avslöja aldrig din backup-fras. Någon som känner till denna fras kan ta dina Ether för alltid." }, - "secretPhrase": { - "message": "Ange din tolv ord långa hemliga fras här för att återställa ditt valv." - }, "securityAndPrivacy": { "message": "Säkerhet och integritet" }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 6bd385ad9..a4451aee5 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -492,9 +492,6 @@ "importWallet": { "message": "Hamisha Waleti" }, - "importYourExisting": { - "message": "Hamisha waleti iliyopo kwa kutumia kirai kianzio cha maneno 12" - }, "imported": { "message": "Zilizoingizwa", "description": "status showing that an account has been fully loaded into the keyring" @@ -873,9 +870,6 @@ "secretBackupPhraseWarning": { "message": "ONYO: Kamwe usiweke wazi kirai chako cha hifadhi mbadala. Mtu yeyote mwenye kirai hiki anaweza kuchukua Ether yako daima." }, - "secretPhrase": { - "message": "Ingiza hapa kirai chako cha siri cha maneno kumi na mawili ili urejeshe vault yako." - }, "securityAndPrivacy": { "message": "Ulinzi na Faragha" }, diff --git a/app/_locales/ta/messages.json b/app/_locales/ta/messages.json index 58f48caab..92e063943 100644 --- a/app/_locales/ta/messages.json +++ b/app/_locales/ta/messages.json @@ -426,9 +426,6 @@ "searchTokens": { "message": "தேடல் டோக்கன்ஸ்" }, - "secretPhrase": { - "message": "உங்கள் பெட்டகத்தை மீட்டெடுப்பதற்காக இங்கே உங்கள் ரகசிய பன்னிரண்டு வார்த்தை சொற்றொடரை உள்ளிடவும்." - }, "seedPhraseReq": { "message": "விதை வாக்கியங்கள் 12 வார்த்தைகள் நீண்டவை" }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index 02b3ff61f..aba919b3f 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -420,9 +420,6 @@ "search": { "message": "ค้นหา" }, - "secretPhrase": { - "message": "ป้อนกลุ่มคำสิบสองคำเพื่อกู้คืนตู้เซฟของคุณ" - }, "seedPhraseReq": { "message": "กลุ่มคำชีดมีความยาว 12 คำ" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 8b9ecb5fc..49e83c002 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "I-import ang wallet" }, - "importYourExisting": { - "message": "I-import ang iyong kasalukuyang wallet gamit ang 12 salita na seed phrase" - }, "imported": { "message": "Na-import", "description": "status showing that an account has been fully loaded into the keyring" @@ -1347,9 +1344,6 @@ "secretBackupPhraseWarning": { "message": "BABALA: Huwag kailanman ipaalam ang iyong phrase sa pag-back up. Ang sinumang may phrase na ito ay maaaring angkinin ang iyong Ether." }, - "secretPhrase": { - "message": "Ilagay ang iyong labindalawang lihim na phrase dito para ma-restore ang iyong vault." - }, "securityAndPrivacy": { "message": "Seguridad at Pagkapribado" }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index b6ebceed0..964f8bb1e 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -366,9 +366,6 @@ "searchTokens": { "message": "Jeton ara" }, - "secretPhrase": { - "message": "Kasanızı geri getirmek için gizli 12 kelimelik ifadenizi giriniz." - }, "seedPhraseReq": { "message": "Kaynak ifadeleri 12 kelimedir." }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index ef54267bb..789e3c64c 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -505,9 +505,6 @@ "importWallet": { "message": "Імпортувати гаманець" }, - "importYourExisting": { - "message": "Імпортуйте ваш гаманець, що існує, використовуючи початкову фразу з 12 слів" - }, "imported": { "message": "Імпортовано", "description": "status showing that an account has been fully loaded into the keyring" @@ -895,9 +892,6 @@ "secretBackupPhraseWarning": { "message": "ЗАСТЕРЕЖЕННЯ: Ніколи не розголошуйте вашу резервну фразу. Будь-хто з цією фразою зможе забрати ваш Ether назавжди." }, - "secretPhrase": { - "message": "Введіть секретну фразу з дванадцяти слів, щоб відновити своє сховище." - }, "securityAndPrivacy": { "message": "Безпека й конфіденційність" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index dc0592c75..2c01eb147 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -791,9 +791,6 @@ "importWallet": { "message": "Nhập ví" }, - "importYourExisting": { - "message": "Nhập ví hiện có của bạn bằng cụm mật khẩu gốc gồm 12 từ" - }, "imported": { "message": "Đã nhập", "description": "status showing that an account has been fully loaded into the keyring" @@ -1350,9 +1347,6 @@ "secretBackupPhraseWarning": { "message": "CẢNH BÁO: Tuyệt đối không để lộ cụm mật khẩu sao lưu của bạn. Bất kỳ ai có cụm mật khẩu này cũng có thể lấy Ether của bạn vĩnh viễn." }, - "secretPhrase": { - "message": "Nhập cụm mật khẩu bí mật gồm 12 từ vào đây để khôi phục két của bạn." - }, "securityAndPrivacy": { "message": "Bảo mật và quyền riêng tư" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 26724aa42..00129d3f3 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -800,9 +800,6 @@ "importWallet": { "message": "导入钱包" }, - "importYourExisting": { - "message": "使用 12 个单词的账户助记词导入您现有的钱包账户。" - }, "imported": { "message": "已导入", "description": "status showing that an account has been fully loaded into the keyring" @@ -1359,9 +1356,6 @@ "secretBackupPhraseWarning": { "message": "警告:切勿向他人透露您的账户助记词。任何人一旦持有该账户助记词,即可控制您的 Ether。" }, - "secretPhrase": { - "message": "输入 12 个单词组成的账户助记词恢复您的账户。" - }, "securityAndPrivacy": { "message": "安全与隐私" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index a88f2fe65..2c8dba349 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -514,9 +514,6 @@ "importWallet": { "message": "匯入錢包" }, - "importYourExisting": { - "message": "使用 12 字的助記詞來匯入你現有的錢包" - }, "imported": { "message": "已匯入私鑰", "description": "status showing that an account has been fully loaded into the keyring" @@ -889,9 +886,6 @@ "secretBackupPhraseWarning": { "message": "警告: 絕對不要洩漏您的助憶詞。任何人只要得知助憶詞代表他可以竊取您所有的以太幣和代幣。" }, - "secretPhrase": { - "message": "輸入您的12個助憶詞以回復金庫" - }, "securityAndPrivacy": { "message": "安全&隱私" }, diff --git a/ui/app/pages/keychains/index.scss b/ui/app/pages/keychains/index.scss index a5934bb7a..263a1073c 100644 --- a/ui/app/pages/keychains/index.scss +++ b/ui/app/pages/keychains/index.scss @@ -25,6 +25,12 @@ margin: 60px 0 30px 0; position: relative; max-width: initial; + + &__input-label { + padding-bottom: 10px; + font-weight: 400; + display: inline-block; + } } @media only screen and (max-width: 575px) { diff --git a/ui/app/pages/keychains/restore-vault.js b/ui/app/pages/keychains/restore-vault.js index fc1121c7b..6073c647a 100644 --- a/ui/app/pages/keychains/restore-vault.js +++ b/ui/app/pages/keychains/restore-vault.js @@ -157,7 +157,9 @@ class RestoreVaultPage extends Component { {this.context.t('secretPhrase')}
    - + {showSeedPhrase ? (