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

Merge remote-tracking branch 'origin/develop' into master-sync

This commit is contained in:
ryanml 2021-05-05 12:41:09 -07:00
commit 5f85c68112
1195 changed files with 1210 additions and 522 deletions

View File

@ -485,7 +485,7 @@ jobs:
steps: steps:
- add_ssh_keys: - add_ssh_keys:
fingerprints: fingerprints:
- "5e:a3:2d:35:b6:25:b5:87:b1:41:11:0d:77:50:96:73" - "3d:49:29:f4:b2:e8:ea:af:d1:32:eb:2a:fc:15:85:d8"
- checkout - checkout
- attach_workspace: - attach_workspace:
at: . at: .

View File

@ -16,6 +16,16 @@ then
exit 1 exit 1
fi fi
if [[ -z "${GITHUB_TOKEN:-}" ]]
then
printf '%s\n' 'GITHUB_TOKEN environment variable must be set'
exit 1
elif [[ -z "${GITHUB_TOKEN_USER:-}" ]]
then
printf '%s\n' 'GITHUB_TOKEN_USER environment variable must be set'
exit 1
fi
printf '%s\n' 'Commit the manifest version and changelog if the manifest has changed' printf '%s\n' 'Commit the manifest version and changelog if the manifest has changed'
if git diff --quiet app/manifest/_base.json; if git diff --quiet app/manifest/_base.json;

View File

@ -16,12 +16,6 @@ then
exit 1 exit 1
fi fi
if [[ -z "${GITHUB_TOKEN:-}" ]]
then
printf '%s\n' 'GITHUB_TOKEN environment variable must be set'
exit 1
fi
function install_github_cli () function install_github_cli ()
{ {
printf '%s\n' 'Installing hub CLI' printf '%s\n' 'Installing hub CLI'

View File

@ -108,7 +108,7 @@ module.exports = {
}, },
{ {
files: ['**/*.test.js'], files: ['**/*.test.js'],
excludedFiles: ['ui/**/*.test.js', 'ui/app/__mocks__/*.js'], excludedFiles: ['ui/**/*.test.js', 'ui/__mocks__/*.js'],
extends: ['@metamask/eslint-config-mocha'], extends: ['@metamask/eslint-config-mocha'],
rules: { rules: {
'mocha/no-setup-in-describe': 'off', 'mocha/no-setup-in-describe': 'off',
@ -125,7 +125,7 @@ module.exports = {
}, },
}, },
{ {
files: ['ui/**/*.test.js', 'ui/app/__mocks__/*.js'], files: ['ui/**/*.test.js', 'ui/__mocks__/*.js'],
extends: ['@metamask/eslint-config-jest'], extends: ['@metamask/eslint-config-jest'],
rules: { rules: {
'jest/no-restricted-matchers': 'off', 'jest/no-restricted-matchers': 'off',

2
.gitignore vendored
View File

@ -39,7 +39,7 @@ test-builds
build-artifacts build-artifacts
#ignore css output and sourcemaps #ignore css output and sourcemaps
ui/app/css/output/ ui/css/output/
notes.txt notes.txt

View File

@ -1,12 +1,12 @@
import React, { Component, createContext, useMemo } from 'react'; import React, { Component, createContext, useMemo } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { getMessage } from '../ui/app/helpers/utils/i18n-helper'; import { getMessage } from '../ui/helpers/utils/i18n-helper';
import { I18nContext } from '../ui/app/contexts/i18n'; import { I18nContext } from '../ui/contexts/i18n';
export { I18nContext } export { I18nContext };
export const I18nProvider = (props) => { export const I18nProvider = (props) => {
const { currentLocale, current, en } = props const { currentLocale, current, en } = props;
const t = useMemo(() => { const t = useMemo(() => {
return (key, ...args) => return (key, ...args) =>

View File

@ -1,9 +1,9 @@
const path = require('path') const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = { module.exports = {
stories: ['../ui/app/**/*.stories.js'], stories: ['../ui/**/*.stories.js'],
addons: [ addons: [
'@storybook/addon-knobs', '@storybook/addon-knobs',
'@storybook/addon-actions', '@storybook/addon-actions',
@ -12,7 +12,7 @@ module.exports = {
'./i18n-party-addon/register.js', './i18n-party-addon/register.js',
], ],
webpackFinal: async (config) => { webpackFinal: async (config) => {
config.module.strictExportPresence = true config.module.strictExportPresence = true;
config.module.rules.push({ config.module.rules.push({
test: /\.scss$/, test: /\.scss$/,
loaders: [ loaders: [
@ -31,12 +31,12 @@ module.exports = {
sourceMap: true, sourceMap: true,
implementation: require('sass'), implementation: require('sass'),
sassOptions: { sassOptions: {
includePaths: ['ui/app/css/'], includePaths: ['ui/css/'],
}, },
}, },
}, },
], ],
}) });
config.plugins.push( config.plugins.push(
new CopyWebpackPlugin({ new CopyWebpackPlugin({
patterns: [ patterns: [
@ -51,7 +51,7 @@ module.exports = {
}, },
], ],
}), }),
) );
return config return config;
}, },
} };

View File

@ -3,12 +3,12 @@ import { addDecorator, addParameters } from '@storybook/react';
import { useGlobals } from '@storybook/api'; import { useGlobals } from '@storybook/api';
import { withKnobs } from '@storybook/addon-knobs'; import { withKnobs } from '@storybook/addon-knobs';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import configureStore from '../ui/app/store/store'; import configureStore from '../ui/store/store';
import '../ui/app/css/index.scss'; import '../ui/css/index.scss';
import localeList from '../app/_locales/index.json'; import localeList from '../app/_locales/index.json';
import * as allLocales from './locales'; import * as allLocales from './locales';
import { I18nProvider, LegacyI18nProvider } from './i18n'; import { I18nProvider, LegacyI18nProvider } from './i18n';
import testData from './test-data.js' import testData from './test-data.js';
addParameters({ addParameters({
backgrounds: { backgrounds: {
@ -41,7 +41,7 @@ const styles = {
alignItems: 'center', alignItems: 'center',
}; };
const store = configureStore(testData) const store = configureStore(testData);
const metamaskDecorator = (story, context) => { const metamaskDecorator = (story, context) => {
const currentLocale = context.globals.locale; const currentLocale = context.globals.locale;

View File

@ -556,6 +556,12 @@
"dismiss": { "dismiss": {
"message": "Dismiss" "message": "Dismiss"
}, },
"dismissReminderDescriptionField": {
"message": "Turn this on to dismiss the recovery phrase backup reminder message. We highly recommend that you back up your seed phrase to avoid loss of funds"
},
"dismissReminderField": {
"message": "Dismiss recovery phrase backup reminder"
},
"done": { "done": {
"message": "Done" "message": "Done"
}, },
@ -684,6 +690,9 @@
"estimatedProcessingTimes": { "estimatedProcessingTimes": {
"message": "Estimated Processing Times" "message": "Estimated Processing Times"
}, },
"ethGasPriceFetchWarning": {
"message": "Backup gas price is provided as the main gas estimation service is unavailable right now."
},
"eth_accounts": { "eth_accounts": {
"message": "View the addresses of your permitted accounts (required)", "message": "View the addresses of your permitted accounts (required)",
"description": "The description for the `eth_accounts` permission" "description": "The description for the `eth_accounts` permission"
@ -780,6 +789,9 @@
"gasPriceExtremelyLow": { "gasPriceExtremelyLow": {
"message": "Gas Price Extremely Low" "message": "Gas Price Extremely Low"
}, },
"gasPriceFetchFailed": {
"message": "Gas price estimation failed due to network error."
},
"gasPriceInfoTooltipContent": { "gasPriceInfoTooltipContent": {
"message": "Gas price specifies the amount of Ether you are willing to pay for each unit of gas." "message": "Gas price specifies the amount of Ether you are willing to pay for each unit of gas."
}, },
@ -1966,8 +1978,8 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Below are all the quotes gathered from multiple liquidity sources." "message": "Below are all the quotes gathered from multiple liquidity sources."
}, },
"swapSlippageTooLow": { "swapSlippageNegative": {
"message": "Slippage must be greater than zero" "message": "Slippage must be greater or equal to zero"
}, },
"swapSource": { "swapSource": {
"message": "Liquidity source" "message": "Liquidity source"

View File

@ -1690,9 +1690,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "A continuación se muestran todas las cotizaciones recopiladas de múltiples fuentes de liquidez." "message": "A continuación se muestran todas las cotizaciones recopiladas de múltiples fuentes de liquidez."
}, },
"swapSlippageTooLow": {
"message": "El deslizamiento debe ser mayor que cero"
},
"swapSource": { "swapSource": {
"message": "Fuente de liquidez" "message": "Fuente de liquidez"
}, },

View File

@ -1690,9 +1690,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "A continuación se muestran todas las cotizaciones recopiladas de múltiples fuentes de liquidez." "message": "A continuación se muestran todas las cotizaciones recopiladas de múltiples fuentes de liquidez."
}, },
"swapSlippageTooLow": {
"message": "El deslizamiento debe ser mayor que cero"
},
"swapSource": { "swapSource": {
"message": "Fuente de liquidez" "message": "Fuente de liquidez"
}, },

View File

@ -1660,9 +1660,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "नीचे दिए गए सभी उद्धरण कई चलनिधि स्रोतों से एकत्र किए गए हैं।" "message": "नीचे दिए गए सभी उद्धरण कई चलनिधि स्रोतों से एकत्र किए गए हैं।"
}, },
"swapSlippageTooLow": {
"message": "स्लिपेज शून्य से अधिक होना चाहिए"
},
"swapSource": { "swapSource": {
"message": "चलनिधि का स्रोत" "message": "चलनिधि का स्रोत"
}, },

View File

@ -1660,9 +1660,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Di bawah ini adalah semua kuota yang dikumpulkan dari beberapa sumber likuiditas." "message": "Di bawah ini adalah semua kuota yang dikumpulkan dari beberapa sumber likuiditas."
}, },
"swapSlippageTooLow": {
"message": "Slippage harus lebih besar dari nol"
},
"swapSource": { "swapSource": {
"message": "Sumber likuiditas" "message": "Sumber likuiditas"
}, },

View File

@ -1702,9 +1702,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Sotto trovi tutte le quotazioni raccolte da multiple sorgenti di liquidità." "message": "Sotto trovi tutte le quotazioni raccolte da multiple sorgenti di liquidità."
}, },
"swapSlippageTooLow": {
"message": "Lo slippage deve essere maggiore di zero"
},
"swapSource": { "swapSource": {
"message": "Sorgente di liquidità" "message": "Sorgente di liquidità"
}, },

View File

@ -1690,9 +1690,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "以下は複数の流動性ソースから収集したすべての見積です。" "message": "以下は複数の流動性ソースから収集したすべての見積です。"
}, },
"swapSlippageTooLow": {
"message": "スリッページは 0 より多くする必要があります。"
},
"swapSource": { "swapSource": {
"message": "流動性ソース" "message": "流動性ソース"
}, },

View File

@ -1660,9 +1660,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "다음은 여러 유동성 소스에서 수집한 전체 견적입니다." "message": "다음은 여러 유동성 소스에서 수집한 전체 견적입니다."
}, },
"swapSlippageTooLow": {
"message": "슬리패지는 0보다 커야 합니다."
},
"swapSource": { "swapSource": {
"message": "유동성 소스" "message": "유동성 소스"
}, },

View File

@ -1660,9 +1660,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Ниже приведены все котировки, собранные из нескольких источников ликвидности." "message": "Ниже приведены все котировки, собранные из нескольких источников ликвидности."
}, },
"swapSlippageTooLow": {
"message": "Проскальзывание должно быть больше нуля"
},
"swapSource": { "swapSource": {
"message": "Источник ликвидности" "message": "Источник ликвидности"
}, },

View File

@ -1657,9 +1657,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Makikita sa ibaba ang lahat ng quote na nakuha mula sa maraming pinagkukunan ng liquidity." "message": "Makikita sa ibaba ang lahat ng quote na nakuha mula sa maraming pinagkukunan ng liquidity."
}, },
"swapSlippageTooLow": {
"message": "Dapat ay mas malaki sa zero ang slippage"
},
"swapSource": { "swapSource": {
"message": "Pinagkunan ng liquidity" "message": "Pinagkunan ng liquidity"
}, },

View File

@ -1660,9 +1660,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "Dưới đây là tất cả các báo giá thu thập từ nhiều nguồn thanh khoản." "message": "Dưới đây là tất cả các báo giá thu thập từ nhiều nguồn thanh khoản."
}, },
"swapSlippageTooLow": {
"message": "Mức trượt giá phải lớn hơn 0"
},
"swapSource": { "swapSource": {
"message": "Nguồn thanh khoản" "message": "Nguồn thanh khoản"
}, },

View File

@ -1690,9 +1690,6 @@
"swapSelectQuotePopoverDescription": { "swapSelectQuotePopoverDescription": {
"message": "以下是从多个流动资金来源收集到的所有报价。" "message": "以下是从多个流动资金来源收集到的所有报价。"
}, },
"swapSlippageTooLow": {
"message": "滑点必须大于零"
},
"swapSource": { "swapSource": {
"message": "流动资金来源" "message": "流动资金来源"
}, },

View File

@ -23,6 +23,7 @@ export default class AppStateController extends EventEmitter {
timeoutMinutes: 0, timeoutMinutes: 0,
connectedStatusPopoverHasBeenShown: true, connectedStatusPopoverHasBeenShown: true,
defaultHomeActiveTabName: null, defaultHomeActiveTabName: null,
browserEnvironment: {},
...initState, ...initState,
}); });
this.timer = null; this.timer = null;
@ -158,4 +159,12 @@ export default class AppStateController extends EventEmitter {
timeoutMinutes * 60 * 1000, timeoutMinutes * 60 * 1000,
); );
} }
/**
* Sets the current browser and OS environment
* @returns {void}
*/
setBrowserEnvironment(os, browser) {
this.store.updateState({ browserEnvironment: { os, browser } });
}
} }

View File

@ -43,6 +43,7 @@ export default class PreferencesController {
useBlockie: false, useBlockie: false,
useNonceField: false, useNonceField: false,
usePhishDetect: true, usePhishDetect: true,
dismissSeedBackUpReminder: false,
// WARNING: Do not use feature flags for security-sensitive things. // WARNING: Do not use feature flags for security-sensitive things.
// Feature flag toggling is available in the global namespace // Feature flag toggling is available in the global namespace
@ -669,7 +670,7 @@ export default class PreferencesController {
/** /**
* A setter for the `useLedgerLive` property * A setter for the `useLedgerLive` property
* @param {bool} domain - Value for ledger live support * @param {bool} useLedgerLive - Value for ledger live support
* @returns {Promise<string>} A promise of the update to useLedgerLive * @returns {Promise<string>} A promise of the update to useLedgerLive
*/ */
async setLedgerLivePreference(useLedgerLive) { async setLedgerLivePreference(useLedgerLive) {
@ -685,6 +686,17 @@ export default class PreferencesController {
return this.store.getState().useLedgerLive; return this.store.getState().useLedgerLive;
} }
/**
* A setter for the user preference to dismiss the seed phrase backup reminder
* @param {bool} dismissBackupReminder- User preference for dismissing the back up reminder
* @returns {void}
*/
async setDismissSeedBackUpReminder(dismissSeedBackUpReminder) {
await this.store.updateState({
dismissSeedBackUpReminder,
});
}
// //
// PRIVATE METHODS // PRIVATE METHODS
// //

View File

@ -4,9 +4,9 @@ import BigNumber from 'bignumber.js';
import { ObservableStore } from '@metamask/obs-store'; import { ObservableStore } from '@metamask/obs-store';
import { mapValues, cloneDeep } from 'lodash'; import { mapValues, cloneDeep } from 'lodash';
import abi from 'human-standard-token-abi'; import abi from 'human-standard-token-abi';
import { calcTokenAmount } from '../../../ui/app/helpers/utils/token-util'; import { calcTokenAmount } from '../../../ui/helpers/utils/token-util';
import { calcGasTotal } from '../../../ui/app/pages/send/send.utils'; import { calcGasTotal } from '../../../ui/pages/send/send.utils';
import { conversionUtil } from '../../../ui/app/helpers/utils/conversion-util'; import { conversionUtil } from '../../../ui/helpers/utils/conversion-util';
import { import {
DEFAULT_ERC20_APPROVE_GAS, DEFAULT_ERC20_APPROVE_GAS,
QUOTES_EXPIRED_ERROR, QUOTES_EXPIRED_ERROR,
@ -20,7 +20,7 @@ import {
fetchTradesInfo as defaultFetchTradesInfo, fetchTradesInfo as defaultFetchTradesInfo,
fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness, fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness,
fetchSwapsQuoteRefreshTime as defaultFetchSwapsQuoteRefreshTime, fetchSwapsQuoteRefreshTime as defaultFetchSwapsQuoteRefreshTime,
} from '../../../ui/app/pages/swaps/swaps.util'; } from '../../../ui/pages/swaps/swaps.util';
import { NETWORK_EVENTS } from './network'; import { NETWORK_EVENTS } from './network';
// The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator // The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator

View File

@ -16,8 +16,8 @@ import {
BnMultiplyByFraction, BnMultiplyByFraction,
addHexPrefix, addHexPrefix,
} from '../../lib/util'; } from '../../lib/util';
import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/app/helpers/constants/error-keys'; import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/helpers/constants/error-keys';
import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/app/pages/swaps/swaps.util'; import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/pages/swaps/swaps.util';
import { import {
TRANSACTION_STATUSES, TRANSACTION_STATUSES,
TRANSACTION_TYPES, TRANSACTION_TYPES,

View File

@ -476,6 +476,17 @@ export default class MetamaskController extends EventEmitter {
this.submitPassword(password); this.submitPassword(password);
} }
// Lazily update the store with the current extension environment
this.extension.runtime.getPlatformInfo(({ os }) => {
this.appStateController.setBrowserEnvironment(
os,
// This method is presently only supported by Firefox
this.extension.runtime.getBrowserInfo === undefined
? 'chrome'
: 'firefox',
);
});
// TODO:LegacyProvider: Delete // TODO:LegacyProvider: Delete
this.publicConfigStore = this.createPublicConfigStore(); this.publicConfigStore = this.createPublicConfigStore();
} }
@ -722,6 +733,10 @@ export default class MetamaskController extends EventEmitter {
preferencesController.addKnownMethodData, preferencesController.addKnownMethodData,
preferencesController, preferencesController,
), ),
setDismissSeedBackUpReminder: nodeify(
this.preferencesController.setDismissSeedBackUpReminder,
this.preferencesController,
),
// AddressController // AddressController
setAddressBook: nodeify( setAddressBook: nodeify(

View File

@ -52,6 +52,7 @@ const ExtensionizerMock = {
onInstalled: { onInstalled: {
addListener: () => undefined, addListener: () => undefined,
}, },
getPlatformInfo: async () => 'mac',
}, },
}; };

View File

@ -35,7 +35,7 @@ const copyTargets = [
dest: `fonts/fontawesome`, dest: `fonts/fontawesome`,
}, },
{ {
src: `./ui/app/css/output/`, src: `./ui/css/output/`,
pattern: `*.css`, pattern: `*.css`,
dest: ``, dest: ``,
}, },

View File

@ -18,8 +18,8 @@ function createStyleTasks({ livereload }) {
const prod = createTask( const prod = createTask(
'styles:prod', 'styles:prod',
createScssBuildTask({ createScssBuildTask({
src: 'ui/app/css/index.scss', src: 'ui/css/index.scss',
dest: 'ui/app/css/output', dest: 'ui/css/output',
devMode: false, devMode: false,
}), }),
); );
@ -27,15 +27,15 @@ function createStyleTasks({ livereload }) {
const dev = createTask( const dev = createTask(
'styles:dev', 'styles:dev',
createScssBuildTask({ createScssBuildTask({
src: 'ui/app/css/index.scss', src: 'ui/css/index.scss',
dest: 'ui/app/css/output', dest: 'ui/css/output',
devMode: true, devMode: true,
pattern: 'ui/app/**/*.scss', pattern: 'ui/**/*.scss',
}), }),
); );
const lint = createTask('lint-scss', function () { const lint = createTask('lint-scss', function () {
return gulp.src('ui/app/css/itcss/**/*.scss').pipe( return gulp.src('ui/css/itcss/**/*.scss').pipe(
gulpStylelint({ gulpStylelint({
reporters: [{ formatter: 'string', console: true }], reporters: [{ formatter: 'string', console: true }],
fix: true, fix: true,

View File

@ -171,8 +171,8 @@ async function verifyEnglishLocale() {
// In the meantime we'll use glob to specify which paths can be strict searched // In the meantime we'll use glob to specify which paths can be strict searched
// and gradually phase out the key based search // and gradually phase out the key based search
const globsToStrictSearch = [ const globsToStrictSearch = [
'ui/app/components/app/metamask-translation/*.js', 'ui/components/app/metamask-translation/*.js',
'ui/app/pages/confirmation/templates/*.js', 'ui/pages/confirmation/templates/*.js',
]; ];
const testGlob = '**/*.test.js'; const testGlob = '**/*.test.js';
const javascriptFiles = await glob(['ui/**/*.js', 'shared/**/*.js'], { const javascriptFiles = await glob(['ui/**/*.js', 'shared/**/*.js'], {

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
restoreMocks: true, restoreMocks: true,
coverageDirectory: 'jest-coverage/', coverageDirectory: 'jest-coverage/',
collectCoverageFrom: ['<rootDir>/ui/app/**/swaps/**'], collectCoverageFrom: ['<rootDir>/ui/**/swaps/**'],
coveragePathIgnorePatterns: ['.stories.js', '.snap'], coveragePathIgnorePatterns: ['.stories.js', '.snap'],
coverageThreshold: { coverageThreshold: {
global: { global: {

View File

@ -950,6 +950,16 @@
"buffer-equal": true "buffer-equal": true
} }
}, },
"are-we-there-yet": {
"builtin": {
"events.EventEmitter": true,
"util.inherits": true
},
"packages": {
"delegates": true,
"readable-stream": true
}
},
"arr-diff": { "arr-diff": {
"packages": { "packages": {
"arr-flatten": true, "arr-flatten": true,
@ -1302,6 +1312,7 @@
"anymatch": true, "anymatch": true,
"async-each": true, "async-each": true,
"braces": true, "braces": true,
"fsevents": true,
"glob-parent": true, "glob-parent": true,
"inherits": true, "inherits": true,
"is-binary-path": true, "is-binary-path": true,
@ -1553,6 +1564,16 @@
"through2": true "through2": true
} }
}, },
"detect-libc": {
"builtin": {
"child_process.spawnSync": true,
"fs.readdirSync": true,
"os.platform": true
},
"globals": {
"process.env": true
}
},
"detective": { "detective": {
"packages": { "packages": {
"acorn-node": true, "acorn-node": true,
@ -1993,6 +2014,45 @@
"process.version": true "process.version": true
} }
}, },
"fsevents": {
"builtin": {
"events.EventEmitter": true,
"fs.stat": true,
"path.join": true,
"util.inherits": true
},
"globals": {
"__dirname": true,
"process.nextTick": true,
"process.platform": true,
"setImmediate": true
},
"native": true,
"packages": {
"node-pre-gyp": true
}
},
"gauge": {
"builtin": {
"util.format": true
},
"globals": {
"clearInterval": true,
"process": true,
"setImmediate": true,
"setInterval": true
},
"packages": {
"aproba": true,
"console-control-strings": true,
"has-unicode": true,
"object-assign": true,
"signal-exit": true,
"string-width": true,
"strip-ansi": true,
"wide-align": true
}
},
"get-assigned-identifiers": { "get-assigned-identifiers": {
"builtin": { "builtin": {
"assert.equal": true "assert.equal": true
@ -2373,6 +2433,16 @@
"process.argv": true "process.argv": true
} }
}, },
"has-unicode": {
"builtin": {
"os.type": true
},
"globals": {
"process.env.LANG": true,
"process.env.LC_ALL": true,
"process.env.LC_CTYPE": true
}
},
"has-value": { "has-value": {
"packages": { "packages": {
"get-value": true, "get-value": true,
@ -2526,6 +2596,11 @@
"is-plain-object": true "is-plain-object": true
} }
}, },
"is-fullwidth-code-point": {
"packages": {
"number-is-nan": true
}
},
"is-glob": { "is-glob": {
"packages": { "packages": {
"is-extglob": true "is-extglob": true
@ -2910,6 +2985,56 @@
"setTimeout": true "setTimeout": true
} }
}, },
"node-pre-gyp": {
"builtin": {
"events.EventEmitter": true,
"fs.existsSync": true,
"fs.readFileSync": true,
"fs.renameSync": true,
"path.dirname": true,
"path.existsSync": true,
"path.join": true,
"path.resolve": true,
"url.parse": true,
"url.resolve": true,
"util.inherits": true
},
"globals": {
"__dirname": true,
"console.log": true,
"process.arch": true,
"process.cwd": true,
"process.env": true,
"process.platform": true,
"process.version.substr": true,
"process.versions": true
},
"packages": {
"detect-libc": true,
"nopt": true,
"npmlog": true,
"rimraf": true,
"semver": true
}
},
"nopt": {
"builtin": {
"path": true,
"stream.Stream": true,
"url": true
},
"globals": {
"console": true,
"process.argv": true,
"process.env.DEBUG_NOPT": true,
"process.env.NOPT_DEBUG": true,
"process.platform": true
},
"packages": {
"abbrev": true,
"osenv": true
}
},
"normalize-path": { "normalize-path": {
"packages": { "packages": {
"remove-trailing-separator": true "remove-trailing-separator": true
@ -2925,6 +3050,22 @@
"once": true "once": true
} }
}, },
"npmlog": {
"builtin": {
"events.EventEmitter": true,
"util": true
},
"globals": {
"process.nextTick": true,
"process.stderr": true
},
"packages": {
"are-we-there-yet": true,
"console-control-strings": true,
"gauge": true,
"set-blocking": true
}
},
"object-copy": { "object-copy": {
"packages": { "packages": {
"copy-descriptor": true, "copy-descriptor": true,
@ -2991,6 +3132,54 @@
"readable-stream": true "readable-stream": true
} }
}, },
"os-homedir": {
"builtin": {
"os.homedir": true
},
"globals": {
"process.env": true,
"process.getuid": true,
"process.platform": true
}
},
"os-tmpdir": {
"globals": {
"process.env.SystemRoot": true,
"process.env.TEMP": true,
"process.env.TMP": true,
"process.env.TMPDIR": true,
"process.env.windir": true,
"process.platform": true
}
},
"osenv": {
"builtin": {
"child_process.exec": true,
"path": true
},
"globals": {
"process.env.COMPUTERNAME": true,
"process.env.ComSpec": true,
"process.env.EDITOR": true,
"process.env.HOSTNAME": true,
"process.env.PATH": true,
"process.env.PROMPT": true,
"process.env.PS1": true,
"process.env.Path": true,
"process.env.SHELL": true,
"process.env.USER": true,
"process.env.USERDOMAIN": true,
"process.env.USERNAME": true,
"process.env.VISUAL": true,
"process.env.path": true,
"process.nextTick": true,
"process.platform": true
},
"packages": {
"os-homedir": true,
"os-tmpdir": true
}
},
"parent-module": { "parent-module": {
"packages": { "packages": {
"callsites": true "callsites": true
@ -3573,6 +3762,12 @@
"process": true "process": true
} }
}, },
"set-blocking": {
"globals": {
"process.stderr": true,
"process.stdout": true
}
},
"set-value": { "set-value": {
"packages": { "packages": {
"extend-shallow": true, "extend-shallow": true,
@ -3766,6 +3961,7 @@
}, },
"string-width": { "string-width": {
"packages": { "packages": {
"code-point-at": true,
"emoji-regex": true, "emoji-regex": true,
"is-fullwidth-code-point": true, "is-fullwidth-code-point": true,
"strip-ansi": true "strip-ansi": true
@ -4322,6 +4518,11 @@
"isexe": true "isexe": true
} }
}, },
"wide-align": {
"packages": {
"string-width": true
}
},
"write": { "write": {
"builtin": { "builtin": {
"fs.createWriteStream": true, "fs.createWriteStream": true,

View File

@ -49,7 +49,7 @@
"verify-locales": "node ./development/verify-locale-strings.js", "verify-locales": "node ./development/verify-locale-strings.js",
"verify-locales:fix": "node ./development/verify-locale-strings.js --fix", "verify-locales:fix": "node ./development/verify-locale-strings.js --fix",
"mozilla-lint": "addons-linter dist/firefox", "mozilla-lint": "addons-linter dist/firefox",
"watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", "watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/**/*.test.js\" \"shared/**/*.test.js\"",
"devtools:react": "react-devtools", "devtools:react": "react-devtools",
"devtools:redux": "remotedev --hostname=localhost --port=8000", "devtools:redux": "remotedev --hostname=localhost --port=8000",
"start:dev": "concurrently -k -n build,react,redux yarn:start yarn:devtools:react yarn:devtools:redux", "start:dev": "concurrently -k -n build,react,redux yarn:start yarn:devtools:react yarn:devtools:redux",
@ -328,7 +328,8 @@
"gc-stats": false, "gc-stats": false,
"github:assemblyscript/assemblyscript": false, "github:assemblyscript/assemblyscript": false,
"tiny-secp256k1": false, "tiny-secp256k1": false,
"@lavamoat/preinstall-always-fail": false "@lavamoat/preinstall-always-fail": false,
"fsevents": false
} }
} }
} }

View File

@ -1117,16 +1117,10 @@ describe('MetaMask', function () {
}); });
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 1;
}, 10000);
await driver.waitForSelector( await driver.waitForSelector(
{ {
css: '.transaction-list-item__primary-currency', css:
'.transaction-list__completed-transactions .transaction-list-item__primary-currency',
text: '-1 TST', text: '-1 TST',
}, },
{ timeout: 10000 }, { timeout: 10000 },
@ -1219,15 +1213,9 @@ describe('MetaMask', function () {
}); });
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 2;
}, 10000);
await driver.waitForSelector({ await driver.waitForSelector({
css: '.transaction-list-item__primary-currency', css:
'.transaction-list__completed-transactions .transaction-list-item__primary-currency',
text: '-1.5 TST', text: '-1.5 TST',
}); });
@ -1235,11 +1223,23 @@ describe('MetaMask', function () {
css: '.list-item__heading', css: '.list-item__heading',
text: 'Send TST', text: 'Send TST',
}); });
});
it('checks balance', async function () {
await driver.clickElement({
text: 'Assets',
tag: 'button',
});
await driver.waitForSelector({ await driver.waitForSelector({
css: '.token-overview__primary-balance', css: '.asset-list-item__token-button',
text: '7.5 TST', text: '7.5 TST',
}); });
await driver.clickElement({
text: 'Activity',
tag: 'button',
});
}); });
}); });
@ -1368,13 +1368,6 @@ describe('MetaMask', function () {
}); });
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 3;
}, 10000);
await driver.waitForSelector({ await driver.waitForSelector({
// Select only the heading of the first entry in the transaction list. // Select only the heading of the first entry in the transaction list.
css: css:
@ -1427,13 +1420,6 @@ describe('MetaMask', function () {
}); });
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 4;
}, 10000);
await driver.waitForSelector({ await driver.waitForSelector({
// Select the heading of the first transaction list item in the // Select the heading of the first transaction list item in the
// completed transaction list with text matching Send TST // completed transaction list with text matching Send TST
@ -1443,7 +1429,8 @@ describe('MetaMask', function () {
}); });
await driver.waitForSelector({ await driver.waitForSelector({
css: '.transaction-list-item__primary-currency', css:
'.transaction-list__completed-transactions .transaction-list-item:first-child .transaction-list-item__primary-currency',
text: '-1.5 TST', text: '-1.5 TST',
}); });
}); });
@ -1509,13 +1496,6 @@ describe('MetaMask', function () {
}); });
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 5;
}, 10000);
await driver.waitForSelector({ await driver.waitForSelector({
css: css:
'.transaction-list__completed-transactions .transaction-list-item:first-child .list-item__heading', '.transaction-list__completed-transactions .transaction-list-item:first-child .list-item__heading',
@ -1526,6 +1506,10 @@ describe('MetaMask', function () {
describe('Hide token', function () { describe('Hide token', function () {
it('hides the token when clicked', async function () { it('hides the token when clicked', async function () {
await driver.clickElement({ text: 'Assets', tag: 'button' });
await driver.clickElement({ text: 'TST', tag: 'span' });
await driver.clickElement('[data-testid="asset-options__button"]'); await driver.clickElement('[data-testid="asset-options__button"]');
await driver.clickElement('[data-testid="asset-options__hide"]'); await driver.clickElement('[data-testid="asset-options__hide"]');

View File

@ -1,4 +1,4 @@
import * as actions from '../../ui/app/store/actions'; import * as actions from '../../ui/store/actions';
export const setBackgroundConnection = (backgroundConnection = {}) => { export const setBackgroundConnection = (backgroundConnection = {}) => {
actions._setBackgroundConnection(backgroundConnection); actions._setBackgroundConnection(backgroundConnection);

View File

@ -4,8 +4,8 @@ import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18nContext, LegacyI18nProvider } from '../../ui/app/contexts/i18n'; import { I18nContext, LegacyI18nProvider } from '../../ui/contexts/i18n';
import { getMessage } from '../../ui/app/helpers/utils/i18n-helper'; import { getMessage } from '../../ui/helpers/utils/i18n-helper';
import * as en from '../../app/_locales/en/messages.json'; import * as en from '../../app/_locales/en/messages.json';
export const I18nProvider = (props) => { export const I18nProvider = (props) => {

View File

@ -1,13 +1,19 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
import { mount } from 'enzyme'; import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18nContext, LegacyI18nProvider } from '../../ui/app/contexts/i18n'; import { I18nContext, LegacyI18nProvider } from '../../ui/contexts/i18n';
import { getMessage } from '../../ui/app/helpers/utils/i18n-helper'; import { getMessage } from '../../ui/helpers/utils/i18n-helper';
import * as en from '../../app/_locales/en/messages.json'; import * as en from '../../app/_locales/en/messages.json';
export function shallowWithContext(jsxComponent) {
return shallow(jsxComponent, {
context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) },
});
}
export function mountWithRouter(component, store = {}, pathname = '/') { export function mountWithRouter(component, store = {}, pathname = '/') {
// Instantiate router context // Instantiate router context
const router = { const router = {

View File

@ -1,6 +1,6 @@
import assert from 'assert'; import assert from 'assert';
import currencyFormatter from 'currency-formatter'; import currencyFormatter from 'currency-formatter';
import availableCurrencies from '../../ui/app/helpers/constants/available-conversions.json'; import availableCurrencies from '../../ui/helpers/constants/available-conversions.json';
describe('currencyFormatting', function () { describe('currencyFormatting', function () {
it('be able to format any infura currency', function (done) { it('be able to format any infura currency', function (done) {

View File

@ -1,3 +0,0 @@
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../shared/constants/app';
export { ENVIRONMENT_TYPE_NOTIFICATION };

View File

@ -4,8 +4,8 @@ import { debounce } from 'lodash';
import Fuse from 'fuse.js'; import Fuse from 'fuse.js';
import InputAdornment from '@material-ui/core/InputAdornment'; import InputAdornment from '@material-ui/core/InputAdornment';
import classnames from 'classnames'; import classnames from 'classnames';
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; import { getEnvironmentType } from '../../../../app/scripts/lib/util';
import Identicon from '../../ui/identicon'; import Identicon from '../../ui/identicon';
import SiteIcon from '../../ui/site-icon'; import SiteIcon from '../../ui/site-icon';
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display';

View File

@ -2,7 +2,7 @@ import React from 'react';
import sinon from 'sinon'; import sinon from 'sinon';
import configureMockStore from 'redux-mock-store'; import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { mountWithRouter } from '../../../../../test/lib/render-helpers'; import { mountWithRouter } from '../../../../test/lib/render-helpers';
import AccountMenu from '.'; import AccountMenu from '.';
describe('Account Menu', () => { describe('Account Menu', () => {

View File

@ -6,11 +6,11 @@ import thunk from 'redux-thunk';
import { fireEvent } from '@testing-library/react'; import { fireEvent } from '@testing-library/react';
import configureMockStore from 'redux-mock-store'; import configureMockStore from 'redux-mock-store';
import { tick } from '../../../../../../test/lib/tick'; import { tick } from '../../../../../test/lib/tick';
import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import * as actions from '../../../../store/actions'; import * as actions from '../../../../store/actions';
import { KOVAN_CHAIN_ID } from '../../../../../../shared/constants/network'; import { KOVAN_CHAIN_ID } from '../../../../../shared/constants/network';
import UnconnectedAccountAlert from '.'; import UnconnectedAccountAlert from '.';
describe('Unconnected Account Alert', () => { describe('Unconnected Account Alert', () => {

View File

@ -22,6 +22,7 @@ export default class ConfirmPageContainerContent extends Component {
titleComponent: PropTypes.node, titleComponent: PropTypes.node,
warning: PropTypes.string, warning: PropTypes.string,
origin: PropTypes.string.isRequired, origin: PropTypes.string.isRequired,
ethGasPriceWarning: PropTypes.string,
// Footer // Footer
onCancelAll: PropTypes.func, onCancelAll: PropTypes.func,
onCancel: PropTypes.func, onCancel: PropTypes.func,
@ -81,11 +82,15 @@ export default class ConfirmPageContainerContent extends Component {
unapprovedTxCount, unapprovedTxCount,
rejectNText, rejectNText,
origin, origin,
ethGasPriceWarning,
} = this.props; } = this.props;
return ( return (
<div className="confirm-page-container-content"> <div className="confirm-page-container-content">
{warning && <ConfirmPageContainerWarning warning={warning} />} {warning && <ConfirmPageContainerWarning warning={warning} />}
{ethGasPriceWarning && (
<ConfirmPageContainerWarning warning={ethGasPriceWarning} />
)}
<ConfirmPageContainerSummary <ConfirmPageContainerSummary
className={classnames({ className={classnames({
'confirm-page-container-summary--border': 'confirm-page-container-summary--border':

View File

@ -1,7 +1,6 @@
.confirm-page-container-warning { .confirm-page-container-warning {
background-color: #fffcdb; background-color: #fffcdb;
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
border-bottom: 1px solid $geyser; border-bottom: 1px solid $geyser;
padding: 12px 24px; padding: 12px 24px;

View File

@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
import { import {
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
} from '../../../../../../shared/constants/app'; } from '../../../../../shared/constants/app';
import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'; import { getEnvironmentType } from '../../../../../app/scripts/lib/util';
import NetworkDisplay from '../../network-display'; import NetworkDisplay from '../../network-display';
import Identicon from '../../../ui/identicon'; import Identicon from '../../../ui/identicon';
import { shortenAddress } from '../../../../helpers/utils/util'; import { shortenAddress } from '../../../../helpers/utils/util';

View File

@ -3,10 +3,10 @@ import { shallow } from 'enzyme';
import sinon from 'sinon'; import sinon from 'sinon';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import configureStore from '../../../../store/store'; import configureStore from '../../../../store/store';
import testData from '../../../../../../.storybook/test-data'; import testData from '../../../../../.storybook/test-data';
import ConfirmPageContainerHeader from './confirm-page-container-header.component'; 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', () => { describe('Confirm Detail Row Component', () => {
describe('render', () => { describe('render', () => {

View File

@ -43,6 +43,7 @@ export default class ConfirmPageContainer extends Component {
warning: PropTypes.string, warning: PropTypes.string,
unapprovedTxCount: PropTypes.number, unapprovedTxCount: PropTypes.number,
origin: PropTypes.string.isRequired, origin: PropTypes.string.isRequired,
ethGasPriceWarning: PropTypes.string,
// Navigation // Navigation
totalTx: PropTypes.number, totalTx: PropTypes.number,
positionOfCurrentTx: PropTypes.number, positionOfCurrentTx: PropTypes.number,
@ -103,6 +104,7 @@ export default class ConfirmPageContainer extends Component {
hideSenderToRecipient, hideSenderToRecipient,
showAccountInHeader, showAccountInHeader,
origin, origin,
ethGasPriceWarning,
} = this.props; } = this.props;
const renderAssetImage = contentComponent || !identiconAddress; const renderAssetImage = contentComponent || !identiconAddress;
@ -162,6 +164,7 @@ export default class ConfirmPageContainer extends Component {
unapprovedTxCount={unapprovedTxCount} unapprovedTxCount={unapprovedTxCount}
rejectNText={this.context.t('rejectTxsN', [unapprovedTxCount])} rejectNText={this.context.t('rejectTxsN', [unapprovedTxCount])}
origin={origin} origin={origin}
ethGasPriceWarning={ethGasPriceWarning}
/> />
)} )}
{contentComponent && ( {contentComponent && (

Some files were not shown because too many files have changed in this diff Show More