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 sync-master

* origin/develop: (107 commits)
  Clear Account Details in AppState (#9238)
  Permit all-caps addresses (#9227)
  Send web3 usage metrics once per origin/property (#9237)
  Fix import/no-extraneous-dependencies issues (#9232)
  Remove unused buyEth fn from bg (#9236)
  Fix max-statements-per-line issues (#9218)
  Consolidate ESLint config files (#9231)
  Delete page-container.component.test.js (#9229)
  Tidy up getAccountLink (#9223)
  Tidy ConnectHardwareForm#checkIfUnlocked (#9224)
  Fix require-unicode-regexp issues (#9212)
  Fix no-negated-condition issues (#9222)
  Fix no-empty-function issues (#9216)
  Fix import/extensions issues (#9217)
  Dedupe glob-parent versions (#9220)
  Fix no-template-curly-in-string issues (#9221)
  Fix no-process-exit issues (#9219)
  Fix prefer-rest-params issues (#9215)
  Fix no-prototype-builtins issues (#9213)
  Fix no-nested-ternary issues (#9214)
  ...
This commit is contained in:
Mark Stacey 2020-08-14 20:32:32 -03:00
commit 52fd72feac
326 changed files with 2503 additions and 3527 deletions

View File

@ -3,14 +3,9 @@
node_modules/**
dist/**
builds/**
test-builds/**
test-*/**
docs/**
coverage/
app/scripts/lib/extension-instance.js
app/scripts/chromereload.js
app/vendor/**
ui/lib/blockies.js
package-lock.json

View File

@ -44,8 +44,32 @@ module.exports = {
/* TODO: Remove these when upgrading to `@metamask/eslint-config@2` */
'array-callback-return': 'error',
'callback-return': 'error',
'consistent-return': 'error',
'global-require': 'error',
'guard-for-in': 'error',
'implicit-arrow-linebreak': 'error',
'import/extensions': ['error', 'never', { 'json': 'always' }],
'import/no-extraneous-dependencies': 'error',
'max-statements-per-line': ['error', { 'max': 1 }],
'no-case-declarations': 'error',
'no-constant-condition': 'error',
'no-dupe-else-if': 'error',
'no-empty': 'error',
'no-empty-function': 'error',
'no-eq-null': 'error',
'no-global-assign': 'error',
'no-loop-func': 'error',
'no-negated-condition': 'error',
'no-nested-ternary': 'error',
'no-plusplus': ['error', { 'allowForLoopAfterthoughts': true }],
'no-process-exit': 'error',
'no-prototype-builtins': 'error',
'no-template-curly-in-string': 'error',
'no-useless-catch': 'error',
'no-useless-concat': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'require-unicode-regexp': 'error',
/* End v2 rules */
'arrow-parens': 'error',
'no-tabs': 'error',
@ -95,11 +119,22 @@ module.exports = {
'logical': 'parens-new-line',
'prop': 'parens-new-line',
}],
'no-invalid-this': 'off',
'babel/no-invalid-this': 'error',
'babel/semi': ['error', 'never'],
'mocha/no-setup-in-describe': 'off',
},
overrides: [{
files: [
'test/e2e/**/*.js',
],
rules: {
'mocha/no-hooks-for-single-case': 'off',
},
}, {
files: [
'app/scripts/migrations/*.js',
'*.stories.js',
@ -114,6 +149,24 @@ module.exports = {
rules: {
'global-require': 'off',
},
}, {
files: [
'test/**/*-test.js',
'test/**/*.spec.js',
],
rules: {
// Mocha will re-assign `this` in a test context
'babel/no-invalid-this': 'off',
},
}, {
files: [
'development/**/*.js',
'test/e2e/benchmark.js',
'test/helper.js',
],
rules: {
'no-process-exit': 'off',
},
}],
settings: {

View File

@ -1,5 +1,5 @@
module.exports = {
stories: ['../ui/app/components/**/*.stories.js'],
stories: ['../ui/app/**/*.stories.js'],
addons: [
'@storybook/addon-knobs',
'@storybook/addon-actions',

View File

@ -29,11 +29,13 @@ module.exports = {
],
},
plugins: [
new CopyWebpackPlugin([
{
from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('fonts', 'fontawesome'),
},
]),
new CopyWebpackPlugin({
patterns: [
{
from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('fonts', 'fontawesome'),
},
],
}),
],
}

Binary file not shown.

Binary file not shown.

View File

@ -8,7 +8,7 @@ const accountImporter = {
importAccount (strategy, args) {
try {
const importer = this.strategies[strategy]
const privateKeyHex = importer.apply(null, args)
const privateKeyHex = importer(...args)
return Promise.resolve(privateKeyHex)
} catch (e) {
return Promise.reject(e)

View File

@ -26,7 +26,7 @@ import Migrator from './lib/migrator'
import migrations from './migrations'
import PortStream from 'extension-port-stream'
import createStreamSink from './lib/createStreamSink'
import NotificationManager from './lib/notification-manager.js'
import NotificationManager from './lib/notification-manager'
import MetamaskController from './metamask-controller'
import rawFirstTimeState from './first-time-state'
import setupSentry from './lib/setupSentry'
@ -327,7 +327,7 @@ function setupController (initState, initLangCode) {
const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]
if (metamaskBlockedPorts.includes(remotePort.name)) {
return false
return
}
if (isMetaMaskInternalProcess) {

View File

@ -155,8 +155,8 @@ function doctypeCheck () {
*/
function suffixCheck () {
const prohibitedTypes = [
/\.xml$/,
/\.pdf$/,
/\.xml$/u,
/\.pdf$/u,
]
const currentUrl = window.location.pathname
for (let i = 0; i < prohibitedTypes.length; i++) {
@ -202,7 +202,7 @@ function blockedDomainCheck () {
let currentRegex
for (let i = 0; i < blockedDomains.length; i++) {
const blockedDomain = blockedDomains[i].replace('.', '\\.')
currentRegex = new RegExp(`(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`)
currentRegex = new RegExp(`(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`, 'u')
if (!currentRegex.test(currentUrl)) {
return true
}
@ -228,7 +228,7 @@ function redirectToPhishingWarning () {
async function domIsReady () {
// already loaded
if (['interactive', 'complete'].includes(document.readyState)) {
return
return undefined
}
// wait for load
return new Promise((resolve) => window.addEventListener('DOMContentLoaded', resolve, { once: true }))

View File

@ -19,7 +19,7 @@ export default class AppStateController extends EventEmitter {
super()
this.onInactiveTimeout = onInactiveTimeout || (() => {})
this.onInactiveTimeout = onInactiveTimeout || (() => undefined)
this.store = new ObservableStore(Object.assign({
timeoutMinutes: 0,
connectedStatusPopoverHasBeenShown: true,

View File

@ -5,11 +5,13 @@ export function createPendingNonceMiddleware ({ getPendingNonce }) {
return createAsyncMiddleware(async (req, res, next) => {
const { method, params } = req
if (method !== 'eth_getTransactionCount') {
return next()
next()
return
}
const [param, blockRef] = params
if (blockRef !== 'pending') {
return next()
next()
return
}
res.result = await getPendingNonce(param)
})
@ -19,12 +21,14 @@ export function createPendingTxMiddleware ({ getPendingTransactionByHash }) {
return createAsyncMiddleware(async (req, res, next) => {
const { method, params } = req
if (method !== 'eth_getTransactionByHash') {
return next()
next()
return
}
const [hash] = params
const txMeta = getPendingTransactionByHash(hash)
if (!txMeta) {
return next()
next()
return
}
res.result = formatTxMetaForRpcResult(txMeta)
})

View File

@ -93,7 +93,8 @@ export default class NetworkController extends EventEmitter {
setNetworkState (network, type) {
if (network === 'loading') {
return this.networkStore.putState(network)
this.networkStore.putState(network)
return
}
// type must be defined
@ -101,7 +102,7 @@ export default class NetworkController extends EventEmitter {
return
}
network = networks.networkList[type]?.chainId || network
return this.networkStore.putState(network)
this.networkStore.putState(network)
}
isNetworkLoading () {
@ -111,7 +112,8 @@ export default class NetworkController extends EventEmitter {
lookupNetwork () {
// Prevent firing when provider is not defined.
if (!this._provider) {
return log.warn('NetworkController - lookupNetwork aborted due to missing provider')
log.warn('NetworkController - lookupNetwork aborted due to missing provider')
return
}
const { type } = this.providerStore.getState()
const ethQuery = new EthQuery(this._provider)
@ -120,7 +122,8 @@ export default class NetworkController extends EventEmitter {
const currentNetwork = this.getNetworkState()
if (initialNetwork === currentNetwork) {
if (err) {
return this.setNetworkState('loading')
this.setNetworkState('loading')
return
}
log.info('web3.getNetwork returned ' + network)
this.setNetworkState(network, type)

View File

@ -132,7 +132,7 @@ export class PermissionsController {
const req = { method: 'eth_accounts' }
const res = {}
this.permissions.providerMiddlewareFunction(
{ origin }, req, res, () => {}, _end,
{ origin }, req, res, () => undefined, _end,
)
function _end () {
@ -187,7 +187,7 @@ export class PermissionsController {
const res = {}
this.permissions.providerMiddlewareFunction(
domain, req, res, () => {}, _end,
domain, req, res, () => undefined, _end,
)
function _end (_err) {

View File

@ -116,7 +116,8 @@ export default class PermissionsLogController {
requestedMethods = [ 'eth_accounts' ]
} else {
// no-op
return next()
next()
return
}
// call next with a return handler for capturing the response

View File

@ -24,12 +24,13 @@ export default function createPermissionsMethodMiddleware ({
// Intercepting eth_accounts requests for backwards compatibility:
// The getAccounts call below wraps the rpc-cap middleware, and returns
// an empty array in case of errors (such as 4100:unauthorized)
case 'eth_accounts':
case 'eth_accounts': {
res.result = await getAccounts()
return
}
case 'eth_requestAccounts':
case 'eth_requestAccounts': {
if (isProcessingRequestAccounts) {
res.error = ethErrors.rpc.resourceUnavailable(
@ -73,19 +74,21 @@ export default function createPermissionsMethodMiddleware ({
}
return
}
// custom method for getting metadata from the requesting domain,
// sent automatically by the inpage provider when it's initialized
case 'wallet_sendDomainMetadata':
case 'wallet_sendDomainMetadata': {
if (typeof req.domainMetadata?.name === 'string') {
addDomainMetadata(req.origin, req.domainMetadata)
}
res.result = true
return
}
// register return handler to send accountsChanged notification
case 'wallet_requestPermissions':
case 'wallet_requestPermissions': {
if ('eth_accounts' in req.params?.[0]) {
@ -101,6 +104,7 @@ export default function createPermissionsMethodMiddleware ({
}
}
break
}
default:
break

View File

@ -198,7 +198,7 @@ export default class PreferencesController {
) {
const { type, options } = req.params
switch (type) {
case 'ERC20':
case 'ERC20': {
const result = await this._handleWatchAssetERC20(options)
if (result instanceof Error) {
end(result)
@ -207,6 +207,7 @@ export default class PreferencesController {
end()
}
return
}
default:
end(new Error(`Asset of type ${type} not supported`))
return

View File

@ -123,7 +123,7 @@ export default class ThreeBoxController {
const threeBoxConfig = await Box.getConfig(this.address)
backupExists = threeBoxConfig.spaces && threeBoxConfig.spaces.metamask
} catch (e) {
if (e.message.match(/^Error: Invalid response \(404\)/)) {
if (e.message.match(/^Error: Invalid response \(404\)/u)) {
backupExists = false
} else {
throw e

View File

@ -16,7 +16,7 @@ import {
SEND_ETHER_ACTION_KEY,
DEPLOY_CONTRACT_ACTION_KEY,
CONTRACT_INTERACTION_KEY,
} from '../../../../ui/app/helpers/constants/transactions.js'
} from '../../../../ui/app/helpers/constants/transactions'
import TransactionStateManager from './tx-state-manager'
import TxGasUtil from './tx-gas-utils'
@ -287,11 +287,11 @@ export default class TransactionController extends EventEmitter {
/**
* Gets default gas price, or returns `undefined` if gas price is already set
* @param {Object} txMeta - The txMeta object
* @returns {Promise<string>} The default gas price
* @returns {Promise<string|undefined>} The default gas price
*/
async _getDefaultGasPrice (txMeta) {
if (txMeta.txParams.gasPrice) {
return
return undefined
}
const gasPrice = await this.query.gasPrice()
@ -560,9 +560,9 @@ export default class TransactionController extends EventEmitter {
// It seems that sometimes the numerical values being returned from
// this.query.getTransactionReceipt are BN instances and not strings.
const gasUsed = typeof txReceipt.gasUsed !== 'string'
? txReceipt.gasUsed.toString(16)
: txReceipt.gasUsed
const gasUsed = typeof txReceipt.gasUsed === 'string'
? txReceipt.gasUsed
: txReceipt.gasUsed.toString(16)
txMeta.txReceipt = {
...txReceipt,
@ -684,7 +684,7 @@ export default class TransactionController extends EventEmitter {
if (!('retryCount' in txMeta)) {
txMeta.retryCount = 0
}
txMeta.retryCount++
txMeta.retryCount += 1
this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:retry')
})
}

View File

@ -129,7 +129,7 @@ export default class PendingTransactionTracker extends EventEmitter {
// Exponential backoff to limit retries at publishing
if (txBlockDistance <= Math.pow(2, retryCount) - 1) {
return
return undefined
}
// Only auto-submit already-signed txs:
@ -239,11 +239,11 @@ export default class PendingTransactionTracker extends EventEmitter {
async _checkIfNonceIsTaken (txMeta) {
const address = txMeta.txParams.from
const completed = this.getCompletedTransactions(address)
return completed.some((other) =>
return completed.some(
// This is called while the transaction is in-flight, so it is possible that the
// list of completed transactions now includes the transaction we were looking at
// and if that is the case, don't consider the transaction to have taken its own nonce
!(other.id === txMeta.id) && other.txParams.nonce === txMeta.txParams.nonce,
(other) => !(other.id === txMeta.id) && other.txParams.nonce === txMeta.txParams.nonce,
)
}
}

View File

@ -164,10 +164,10 @@ export default class TransactionStateManager extends EventEmitter {
txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams)
}
this.once(`${txMeta.id}:signed`, function () {
this.once(`${txMeta.id}:signed`, () => {
this.removeAllListeners(`${txMeta.id}:rejected`)
})
this.once(`${txMeta.id}:rejected`, function () {
this.once(`${txMeta.id}:rejected`, () => {
this.removeAllListeners(`${txMeta.id}:signed`)
})
// initialize history
@ -424,7 +424,7 @@ export default class TransactionStateManager extends EventEmitter {
@param {erroObject} err - error object
*/
setTxStatusFailed (txId, err) {
const error = !err ? new Error('Internal metamask failure') : err
const error = err || new Error('Internal metamask failure')
const txMeta = this.getTx(txId)
txMeta.err = {

View File

@ -35,7 +35,7 @@ import LocalMessageDuplexStream from 'post-message-stream'
import { initProvider } from '@metamask/inpage-provider'
// TODO:deprecate:2020
import setupWeb3 from './lib/setupWeb3.js'
import setupWeb3 from './lib/setupWeb3'
restoreContextAfterImports()

View File

@ -25,7 +25,7 @@ export default class ComposableObservableStore extends ObservableStore {
this.config = config
this.removeAllListeners()
for (const key in config) {
if (config.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(config, key)) {
config[key].subscribe((state) => {
this.updateState({ [key]: state })
})
@ -42,7 +42,7 @@ export default class ComposableObservableStore extends ObservableStore {
getFlatState () {
let flatState = {}
for (const key in this.config) {
if (this.config.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(this.config, key)) {
const controller = this.config[key]
const state = controller.getState ? controller.getState() : controller.state
flatState = { ...flatState, ...state }

View File

@ -256,7 +256,8 @@ export default class AccountTracker {
ethContract.balances(addresses, ethBalance, (error, result) => {
if (error) {
log.warn(`MetaMask - Account Tracker single call balance fetch failed`, error)
return Promise.all(addresses.map(this._updateAccount.bind(this)))
Promise.all(addresses.map(this._updateAccount.bind(this)))
return
}
addresses.forEach((address, index) => {
const balance = bnToHex(result[index])

View File

@ -2,9 +2,6 @@ import { getBackgroundMetaMetricState } from '../../../ui/app/selectors'
import { sendMetaMetricsEvent } from '../../../ui/app/helpers/utils/metametrics.util'
export default function backgroundMetaMetricsEvent (metaMaskState, version, eventData) {
eventData.eventOpts['category'] = 'Background'
const stateEventData = getBackgroundMetaMetricState({ metamask: metaMaskState })
if (stateEventData.participateInMetaMetrics) {
sendMetaMetricsEvent({

View File

@ -14,7 +14,7 @@ export default function createMethodMiddleware ({ origin, sendMetrics }) {
return function methodMiddleware (req, res, next, end) {
switch (req.method) {
case 'metamask_logInjectedWeb3Usage':
case 'metamask_logInjectedWeb3Usage': {
const { action, name } = req.params[0]
@ -32,6 +32,7 @@ export default function createMethodMiddleware ({ origin, sendMetrics }) {
res.result = true
break
}
default:
return next()

View File

@ -5,7 +5,7 @@ import { ethErrors } from 'eth-json-rpc-errors'
import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
const hexRe = /^[0-9A-Fa-f]+$/g
const hexRe = /^[0-9A-Fa-f]+$/ug
import log from 'loglevel'
/**
@ -65,7 +65,8 @@ export default class DecryptMessageManager extends EventEmitter {
getUnapprovedMsgs () {
return this.messages.filter((msg) => msg.status === 'unapproved')
.reduce((result, msg) => {
result[msg.id] = msg; return result
result[msg.id] = msg
return result
}, {})
}
@ -82,19 +83,24 @@ export default class DecryptMessageManager extends EventEmitter {
addUnapprovedMessageAsync (msgParams, req) {
return new Promise((resolve, reject) => {
if (!msgParams.from) {
return reject(new Error('MetaMask Decryption: from field is required.'))
reject(new Error('MetaMask Decryption: from field is required.'))
return
}
const msgId = this.addUnapprovedMessage(msgParams, req)
this.once(`${msgId}:finished`, (data) => {
switch (data.status) {
case 'decrypted':
return resolve(data.rawData)
resolve(data.rawData)
return
case 'rejected':
return reject(ethErrors.provider.userRejectedRequest('MetaMask Decryption: User denied message decryption.'))
reject(ethErrors.provider.userRejectedRequest('MetaMask Decryption: User denied message decryption.'))
return
case 'errored':
return reject(new Error('This message cannot be decrypted'))
reject(new Error('This message cannot be decrypted'))
return
default:
return reject(new Error(`MetaMask Decryption: Unknown problem: ${JSON.stringify(msgParams)}`))
reject(new Error(`MetaMask Decryption: Unknown problem: ${JSON.stringify(msgParams)}`))
return
}
})
})
@ -248,7 +254,7 @@ export default class DecryptMessageManager extends EventEmitter {
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) {
throw new Error('DecryptMessageManager - Message not found for id: "${msgId}".')
throw new Error(`DecryptMessageManager - Message not found for id: "${msgId}".`)
}
msg.status = status
this._updateMsg(msg)

View File

@ -62,7 +62,8 @@ export default class EncryptionPublicKeyManager extends EventEmitter {
getUnapprovedMsgs () {
return this.messages.filter((msg) => msg.status === 'unapproved')
.reduce((result, msg) => {
result[msg.id] = msg; return result
result[msg.id] = msg
return result
}, {})
}
@ -79,17 +80,21 @@ export default class EncryptionPublicKeyManager extends EventEmitter {
addUnapprovedMessageAsync (address, req) {
return new Promise((resolve, reject) => {
if (!address) {
return reject(new Error('MetaMask Message: address field is required.'))
reject(new Error('MetaMask Message: address field is required.'))
return
}
const msgId = this.addUnapprovedMessage(address, req)
this.once(`${msgId}:finished`, (data) => {
switch (data.status) {
case 'received':
return resolve(data.rawData)
resolve(data.rawData)
return
case 'rejected':
return reject(ethErrors.provider.userRejectedRequest('MetaMask EncryptionPublicKey: User denied message EncryptionPublicKey.'))
reject(ethErrors.provider.userRejectedRequest('MetaMask EncryptionPublicKey: User denied message EncryptionPublicKey.'))
return
default:
return reject(new Error(`MetaMask EncryptionPublicKey: Unknown problem: ${JSON.stringify(address)}`))
reject(new Error(`MetaMask EncryptionPublicKey: Unknown problem: ${JSON.stringify(address)}`))
return
}
})
})
@ -243,7 +248,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter {
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) {
throw new Error('EncryptionPublicKeyManager - Message not found for id: "${msgId}".')
throw new Error(`EncryptionPublicKeyManager - Message not found for id: "${msgId}".`)
}
msg.status = status
this._updateMsg(msg)

View File

@ -1,6 +1,6 @@
import urlUtil from 'url'
import extension from 'extensionizer'
import resolveEnsToIpfsContentId from './resolver.js'
import resolveEnsToIpfsContentId from './resolver'
const supportedTopLevelDomains = ['eth']

View File

@ -30,11 +30,11 @@ function freeze (target, key, value, enumerable = true) {
configurable: false, writable: false,
}
if (value !== undefined) {
if (value === undefined) {
target[key] = deepFreeze(target[key])
} else {
opts.value = deepFreeze(value)
opts.enumerable = enumerable
} else {
target[key] = deepFreeze(target[key])
}
Object.defineProperty(target, key, opts)

View File

@ -40,7 +40,7 @@ export default async function getFirstPreferredLangCode () {
const firstPreferredLangCode = userPreferredLocaleCodes
.map((code) => code.toLowerCase().replace('_', '-'))
.find((code) => existingLocaleCodes.hasOwnProperty(code))
.find((code) => Object.prototype.hasOwnProperty.call(existingLocaleCodes, code))
return existingLocaleCodes[firstPreferredLangCode] || 'en'
}

View File

@ -64,7 +64,8 @@ export default class MessageManager extends EventEmitter {
getUnapprovedMsgs () {
return this.messages.filter((msg) => msg.status === 'unapproved')
.reduce((result, msg) => {
result[msg.id] = msg; return result
result[msg.id] = msg
return result
}, {})
}
@ -225,7 +226,7 @@ export default class MessageManager extends EventEmitter {
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) {
throw new Error('MessageManager - Message not found for id: "${msgId}".')
throw new Error(`MessageManager - Message not found for id: "${msgId}".`)
}
msg.status = status
this._updateMsg(msg)

View File

@ -15,9 +15,7 @@ const callbackNoop = function (err) {
*
*/
export default function nodeify (fn, context) {
return function () {
// parse arguments
const args = [].slice.call(arguments)
return function (...args) {
const lastArg = args[args.length - 1]
const lastArgIsCallback = typeof lastArg === 'function'
let callback

View File

@ -5,7 +5,7 @@ import { ethErrors } from 'eth-json-rpc-errors'
import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
const hexRe = /^[0-9A-Fa-f]+$/g
const hexRe = /^[0-9A-Fa-f]+$/ug
import log from 'loglevel'
/**
@ -68,7 +68,8 @@ export default class PersonalMessageManager extends EventEmitter {
getUnapprovedMsgs () {
return this.messages.filter((msg) => msg.status === 'unapproved')
.reduce((result, msg) => {
result[msg.id] = msg; return result
result[msg.id] = msg
return result
}, {})
}
@ -85,17 +86,21 @@ export default class PersonalMessageManager extends EventEmitter {
addUnapprovedMessageAsync (msgParams, req) {
return new Promise((resolve, reject) => {
if (!msgParams.from) {
return reject(new Error('MetaMask Message Signature: from field is required.'))
reject(new Error('MetaMask Message Signature: from field is required.'))
return
}
const msgId = this.addUnapprovedMessage(msgParams, req)
this.once(`${msgId}:finished`, (data) => {
switch (data.status) {
case 'signed':
return resolve(data.rawSig)
resolve(data.rawSig)
return
case 'rejected':
return reject(ethErrors.provider.userRejectedRequest('MetaMask Message Signature: User denied message signature.'))
reject(ethErrors.provider.userRejectedRequest('MetaMask Message Signature: User denied message signature.'))
return
default:
return reject(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
reject(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
return
}
})
})

View File

@ -3,5 +3,6 @@ const MAX = Number.MAX_SAFE_INTEGER
let idCounter = Math.round(Math.random() * MAX)
export default function createRandomId () {
idCounter = idCounter % MAX
// eslint-disable-next-line no-plusplus
return idCounter++
}

View File

@ -72,7 +72,7 @@ export default function setupSentry ({ release, getState }) {
let sentryTarget
if (METAMASK_DEBUG) {
return
return undefined
} else if (METAMASK_ENVIRONMENT === 'production') {
if (!process.env.SENTRY_DSN) {
throw new Error(`Missing SENTRY_DSN environment variable in production environment`)

View File

@ -3,7 +3,7 @@
// TODO:deprecate:2020
// Delete this file
import 'web3/dist/web3.min.js'
import 'web3/dist/web3.min'
const shouldLogUsage = !([
'docs.metamask.io',

View File

@ -61,7 +61,8 @@ export default class TypedMessageManager extends EventEmitter {
getUnapprovedMsgs () {
return this.messages.filter((msg) => msg.status === 'unapproved')
.reduce((result, msg) => {
result[msg.id] = msg; return result
result[msg.id] = msg
return result
}, {})
}
@ -154,7 +155,7 @@ export default class TypedMessageManager extends EventEmitter {
}, 'Signing data must be valid EIP-712 typed data.')
break
case 'V3':
case 'V4':
case 'V4': {
assert.equal(typeof params.data, 'string', '"params.data" must be a string.')
let data
assert.doesNotThrow(() => {
@ -167,6 +168,7 @@ export default class TypedMessageManager extends EventEmitter {
const activeChainId = parseInt(this.networkController.getNetworkState())
chainId && assert.equal(chainId, activeChainId, `Provided chainId "${chainId}" must match the active chainId "${activeChainId}"`)
break
}
default:
assert.fail(`Unknown typed data version "${params.version}"`)
}
@ -291,7 +293,7 @@ export default class TypedMessageManager extends EventEmitter {
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) {
throw new Error('TypedMessageManager - Message not found for id: "${msgId}".')
throw new Error(`TypedMessageManager - Message not found for id: "${msgId}".`)
}
msg.status = status
this._updateMsg(msg)

View File

@ -55,19 +55,19 @@ const getEnvironmentType = (url = window.location.href) => getEnvironmentTypeMem
*/
const getPlatform = (_) => {
const ua = window.navigator.userAgent
if (ua.search('Firefox') !== -1) {
return PLATFORM_FIREFOX
} else {
if (ua.search('Firefox') === -1) {
if (window && window.chrome && window.chrome.ipcRenderer) {
return PLATFORM_BRAVE
} else if (ua.search('Edge') !== -1) {
return PLATFORM_EDGE
} else if (ua.search('OPR') !== -1) {
return PLATFORM_OPERA
} else {
return PLATFORM_CHROME
}
if (ua.search('Edge') !== -1) {
return PLATFORM_EDGE
}
if (ua.search('OPR') !== -1) {
return PLATFORM_OPERA
}
return PLATFORM_CHROME
}
return PLATFORM_FIREFOX
}
/**
@ -135,12 +135,12 @@ function BnMultiplyByFraction (targetBN, numerator, denominator) {
/**
* Returns an Error if extension.runtime.lastError is present
* this is a workaround for the non-standard error object that's used
* @returns {Error}
* @returns {Error|undefined}
*/
function checkForError () {
const lastError = extension.runtime.lastError
if (!lastError) {
return
return undefined
}
// if it quacks like an Error, its an Error
if (lastError.stack && lastError.message) {

View File

@ -24,7 +24,7 @@ import createOriginMiddleware from './lib/createOriginMiddleware'
import createTabIdMiddleware from './lib/createTabIdMiddleware'
import createOnboardingMiddleware from './lib/createOnboardingMiddleware'
import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware'
import { setupMultiplex } from './lib/stream-utils.js'
import { setupMultiplex } from './lib/stream-utils'
import KeyringController from 'eth-keyring-controller'
import EnsController from './controllers/ens'
import NetworkController from './controllers/network'
@ -47,7 +47,6 @@ import { PermissionsController } from './controllers/permissions'
import getRestrictedMethods from './controllers/permissions/restrictedMethods'
import nodeify from './lib/nodeify'
import accountImporter from './account-import-strategies'
import getBuyEthUrl from './lib/buy-eth-url'
import selectChainId from './lib/select-chain-id'
import { Mutex } from 'await-semaphore'
import { version } from '../manifest/_base.json'
@ -449,7 +448,6 @@ export default class MetamaskController extends EventEmitter {
setCurrentLocale: this.setCurrentLocale.bind(this),
markPasswordForgotten: this.markPasswordForgotten.bind(this),
unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this),
buyEth: this.buyEth.bind(this),
safelistPhishingDomain: this.safelistPhishingDomain.bind(this),
getRequestAccountTabIds: (cb) => cb(null, this.getRequestAccountTabIds()),
getOpenMetamaskTabsIds: (cb) => cb(null, this.getOpenMetamaskTabsIds()),
@ -601,8 +599,6 @@ export default class MetamaskController extends EventEmitter {
this.selectFirstIdentity()
}
return vault
} catch (err) {
throw err
} finally {
releaseLock()
}
@ -658,8 +654,6 @@ export default class MetamaskController extends EventEmitter {
this.preferencesController.setAddresses(accounts)
this.selectFirstIdentity()
return vault
} catch (err) {
throw err
} finally {
releaseLock()
}
@ -714,15 +708,16 @@ export default class MetamaskController extends EventEmitter {
Object.keys(accountTokens).forEach((address) => {
const checksummedAddress = ethUtil.toChecksumAddress(address)
filteredAccountTokens[checksummedAddress] = {}
Object.keys(accountTokens[address]).forEach(
(networkType) => (filteredAccountTokens[checksummedAddress][networkType] = networkType !== 'mainnet' ?
accountTokens[address][networkType] :
accountTokens[address][networkType].filter(({ address }) => {
const tokenAddress = ethUtil.toChecksumAddress(address)
return contractMap[tokenAddress] ? contractMap[tokenAddress].erc20 : true
})
),
)
Object.keys(accountTokens[address]).forEach((networkType) => {
filteredAccountTokens[checksummedAddress][networkType] = networkType === 'mainnet'
? (
accountTokens[address][networkType].filter(({ address }) => {
const tokenAddress = ethUtil.toChecksumAddress(address)
return contractMap[tokenAddress] ? contractMap[tokenAddress].erc20 : true
})
)
: accountTokens[address][networkType]
})
})
const preferences = {
@ -1349,7 +1344,7 @@ export default class MetamaskController extends EventEmitter {
* Triggers the callback in newUnsignedTypedMessage.
*
* @param {Object} msgParams - The params passed to eth_signTypedData.
* @returns {Object} - Full state update.
* @returns {Object|undefined} - Full state update.
*/
async signTypedMessage (msgParams) {
log.info('MetaMaskController - eth_signTypedData')
@ -1372,6 +1367,7 @@ export default class MetamaskController extends EventEmitter {
} catch (error) {
log.info('MetaMaskController - eth_signTypedData failed.', error)
this.typedMessageManager.errorMessage(msgId, error)
return undefined
}
}
@ -1401,13 +1397,9 @@ export default class MetamaskController extends EventEmitter {
* @returns {Object} - MetaMask state
*/
async createCancelTransaction (originalTxId, customGasPrice) {
try {
await this.txController.createCancelTransaction(originalTxId, customGasPrice)
const state = await this.getState()
return state
} catch (error) {
throw error
}
await this.txController.createCancelTransaction(originalTxId, customGasPrice)
const state = await this.getState()
return state
}
async createSpeedUpTransaction (originalTxId, customGasPrice, customGasLimit) {
@ -1526,7 +1518,7 @@ export default class MetamaskController extends EventEmitter {
const api = this.getApi()
const dnode = Dnode(api)
// report new active controller connection
this.activeControllerConnections++
this.activeControllerConnections += 1
this.emit('controllerConnectionChanged', this.activeControllerConnections)
// connect dnode api to remote connection
pump(
@ -1535,7 +1527,7 @@ export default class MetamaskController extends EventEmitter {
outStream,
(err) => {
// report new active controller connection
this.activeControllerConnections--
this.activeControllerConnections -= 1
this.emit('controllerConnectionChanged', this.activeControllerConnections)
// report any error
if (err) {
@ -1850,6 +1842,7 @@ export default class MetamaskController extends EventEmitter {
customVariables,
eventOpts: {
action,
category: 'Background',
name,
},
},
@ -1884,24 +1877,6 @@ export default class MetamaskController extends EventEmitter {
}
}
/**
* A method for forwarding the user to the easiest way to obtain ether,
* or the network "gas" currency, for the current selected network.
*
* @param {string} address - The address to fund.
* @param {string} amount - The amount of ether desired, as a base 10 string.
*/
buyEth (address, amount) {
if (!amount) {
amount = '5'
}
const network = this.networkController.getNetworkState()
const url = getBuyEthUrl({ network, address, amount })
if (url) {
this.platform.openTab({ url })
}
}
// network
/**
* A method for selecting a custom URL for an ethereum RPC provider and updating it

View File

@ -14,7 +14,9 @@ export default {
versionedData.data.config.provider.type = 'rpc'
versionedData.data.config.provider.rpcTarget = 'https://rpc.metamask.io/'
}
} catch (e) {}
} catch (_) {
// empty
}
return Promise.resolve(versionedData)
},
}

View File

@ -14,7 +14,9 @@ export default {
if (versionedData.data.config.provider.rpcTarget === oldTestRpc) {
versionedData.data.config.provider.rpcTarget = newTestRpc
}
} catch (e) {}
} catch (_) {
// empty
}
return Promise.resolve(versionedData)
},
}

View File

@ -25,7 +25,9 @@ export default {
break
// No default
}
} catch (_) {}
} catch (_) {
// empty
}
return Promise.resolve(safeVersionedData)
},
}

View File

@ -72,7 +72,7 @@ function getHighestContinuousFrom (txList, startPoint) {
let highest = startPoint
while (nonces.includes(highest)) {
highest++
highest += 1
}
return highest

View File

@ -3,7 +3,7 @@ import dnode from 'dnode'
import { EventEmitter } from 'events'
import PortStream from 'extension-port-stream'
import extension from 'extensionizer'
import { setupMultiplex } from './lib/stream-utils.js'
import { setupMultiplex } from './lib/stream-utils'
import { getEnvironmentType } from './lib/util'
import ExtensionPlatform from './platforms/extension'

View File

@ -24,7 +24,7 @@ import Eth from 'ethjs'
import EthQuery from 'eth-query'
import launchMetaMaskUi from '../../ui'
import StreamProvider from 'web3-stream-provider'
import { setupMultiplex } from './lib/stream-utils.js'
import { setupMultiplex } from './lib/stream-utils'
import log from 'loglevel'
start().catch(log.error)
@ -62,7 +62,8 @@ async function start () {
const container = document.getElementById('app-content')
initializeUi(tab, container, connectionStream, (err, store) => {
if (err) {
return displayCriticalError(container, err)
displayCriticalError(container, err)
return
}
const state = store.getState()
@ -102,7 +103,8 @@ async function queryCurrentActiveTab (windowType) {
function initializeUi (activeTab, container, connectionStream, cb) {
connectToAccountManager(connectionStream, (err, backgroundConnection) => {
if (err) {
return cb(err)
cb(err)
return
}
launchMetaMaskUi({

View File

@ -25,7 +25,7 @@ module.exports = createScriptTasks
const dependencies = Object.keys((packageJSON && packageJSON.dependencies) || {})
const materialUIDependencies = ['@material-ui/core']
const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/))
const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/u))
const d3Dependencies = ['c3', 'd3']
const externalDependenciesMap = {
@ -365,7 +365,7 @@ function getEnvironment ({ devMode, test }) {
return 'testing'
} else if (process.env.CIRCLE_BRANCH === 'master') {
return 'production'
} else if (/^Version-v(\d+)[.](\d+)[.](\d+)/.test(process.env.CIRCLE_BRANCH)) {
} else if (/^Version-v(\d+)[.](\d+)[.](\d+)/u.test(process.env.CIRCLE_BRANCH)) {
return 'release-candidate'
} else if (process.env.CIRCLE_BRANCH === 'develop') {
return 'staging'

View File

@ -81,10 +81,7 @@ async function start () {
const summaryPlatform = 'chrome'
const summaryPage = 'home'
let commentBody
if (!benchmarkResults[summaryPlatform]) {
console.log(`No results for ${summaryPlatform} found; skipping benchmark`)
commentBody = artifactsBody
} else {
if (benchmarkResults[summaryPlatform]) {
try {
const summaryPageLoad = Math.round(parseFloat(benchmarkResults[summaryPlatform][summaryPage].average.load))
const summaryPageLoadMarginOfError = Math.round(parseFloat(benchmarkResults[summaryPlatform][summaryPage].marginOfError.load))
@ -147,6 +144,9 @@ async function start () {
console.error(`Error constructing benchmark results: '${error}'`)
commentBody = artifactsBody
}
} else {
console.log(`No results for ${summaryPlatform} found; skipping benchmark`)
commentBody = artifactsBody
}
const JSON_PAYLOAD = JSON.stringify({ body: commentBody })

View File

@ -50,7 +50,7 @@ class Mock3Box {
},
}
},
logout: () => {},
logout: () => undefined,
})
}

View File

@ -25,12 +25,14 @@ async function start () {
// check if version has artifacts or not
const versionHasArtifacts = versionAlreadyExists && await checkIfVersionHasArtifacts()
if (!versionHasArtifacts) {
// upload sentry source and sourcemaps
await exec(`./development/sentry-upload-artifacts.sh --release ${VERSION}`)
} else {
if (versionHasArtifacts) {
console.log(`Version "${VERSION}" already has artifacts on Sentry, skipping sourcemap upload`)
return
}
// upload sentry source and sourcemaps
await exec(`./development/sentry-upload-artifacts.sh --release ${VERSION}`)
}
async function checkIfAuthWorks () {

View File

@ -49,7 +49,9 @@ async function validateSourcemapForFile ({ buildName }) {
try {
const filePath = path.join(__dirname, `/../dist/${platform}/`, `${buildName}`)
rawBuild = await fsAsync.readFile(filePath, 'utf8')
} catch (err) {}
} catch (_) {
// empty
}
if (!rawBuild) {
throw new Error(`SourcemapValidator - failed to load source file for "${buildName}"`)
}
@ -58,12 +60,16 @@ async function validateSourcemapForFile ({ buildName }) {
try {
const filePath = path.join(__dirname, `/../dist/sourcemaps/`, `${buildName}.map`)
rawSourceMap = await fsAsync.readFile(filePath, 'utf8')
} catch (err) {}
} catch (_) {
// empty
}
// attempt to load in dev mode
try {
const filePath = path.join(__dirname, `/../dist/${platform}/`, `${buildName}.map`)
rawSourceMap = await fsAsync.readFile(filePath, 'utf8')
} catch (err) {}
} catch (_) {
// empty
}
if (!rawSourceMap) {
throw new Error(`SourcemapValidator - failed to load sourcemaps for "${buildName}"`)
}
@ -85,7 +91,7 @@ async function validateSourcemapForFile ({ buildName }) {
const matchesPerLine = buildLines.map((line) => indicesOf(targetString, line))
matchesPerLine.forEach((matchIndices, lineIndex) => {
matchIndices.forEach((matchColumn) => {
sampleCount++
sampleCount += 1
const position = { line: lineIndex + 1, column: matchColumn }
const result = consumer.originalPositionFor(position)
// warn if source content is missing

View File

@ -61,7 +61,7 @@ const main = async () => {
}
while (args.length) {
if (/^(--port|-p)$/i.test(args[0])) {
if (/^(--port|-p)$/u.test(args[0])) {
if (args[1] === undefined) {
throw new Error('Missing port argument')
}

View File

@ -97,6 +97,7 @@ async function getLocale (code) {
log.error(`Error opening your locale ("${code}") file: `, e)
}
process.exit(1)
return undefined
}
}
@ -111,6 +112,7 @@ async function writeLocale (code, locale) {
log.error(`Error writing your locale ("${code}") file: `, e)
}
process.exit(1)
return undefined
}
}
@ -156,6 +158,8 @@ async function verifyLocale (code, fix = false) {
}
return true
}
return false
}
async function verifyEnglishLocale (fix = false) {
@ -165,11 +169,11 @@ async function verifyEnglishLocale (fix = false) {
// match "t(`...`)" because constructing message keys from template strings
// prevents this script from finding the messages, and then inappropriately
// deletes them
const templateStringRegex = /\bt\(`.*`\)/g
const templateStringRegex = /\bt\(`.*`\)/ug
const templateUsage = []
// match the keys from the locale file
const keyRegex = /'(\w+)'|"(\w+)"/g
const keyRegex = /'(\w+)'|"(\w+)"/ug
const usedMessages = new Set()
for await (const fileContents of getFileContents(javascriptFiles)) {
for (const match of matchAll.call(fileContents, keyRegex)) {

View File

@ -202,7 +202,7 @@
"chalk": "^3.0.0",
"chromedriver": "^79.0.0",
"concurrently": "^5.2.0",
"copy-webpack-plugin": "^5.1.1",
"copy-webpack-plugin": "^6.0.3",
"coveralls": "^3.0.0",
"css-loader": "^2.1.1",
"del": "^3.0.0",

View File

@ -1,5 +0,0 @@
module.exports = {
rules: {
'mocha/no-hooks-for-single-case': 'off',
},
}

View File

@ -152,7 +152,7 @@ describe('MetaMask', function () {
it('balance renders', async function () {
const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .list-item__heading'))
await driver.wait(until.elementTextMatches(balance, /25\s*ETH/))
await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u))
await driver.delay(regularDelayMs)
})
})
@ -202,7 +202,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000)
})
})
@ -239,7 +239,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-2\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-2\s*ETH/u), 10000)
})
})
})

View File

@ -92,7 +92,7 @@ async function isWritable (directory) {
}
async function getFirstParentDirectoryThatExists (directory) {
while (true) {
for (;;) {
try {
await fs.access(directory, fsConstants.F_OK)
return directory
@ -117,7 +117,7 @@ async function main () {
let existingParentDirectory
while (args.length) {
if (/^(--pages|-p)$/i.test(args[0])) {
if (/^(--pages|-p)$/u.test(args[0])) {
if (args[1] === undefined) {
throw new Error('Missing pages argument')
}
@ -128,7 +128,7 @@ async function main () {
}
}
args.splice(0, 2)
} else if (/^(--samples|-s)$/i.test(args[0])) {
} else if (/^(--samples|-s)$/u.test(args[0])) {
if (args[1] === undefined) {
throw new Error('Missing number of samples')
}
@ -137,7 +137,7 @@ async function main () {
throw new Error(`Invalid 'samples' argument given: '${args[1]}'`)
}
args.splice(0, 2)
} else if (/^(--out|-o)$/i.test(args[0])) {
} else if (/^(--out|-o)$/u.test(args[0])) {
if (args[1] === undefined) {
throw new Error('Missing output filename')
}

View File

@ -89,11 +89,11 @@ describe('MetaMask', function () {
})
it('gets the current accounts address', async function () {
const addressInput = await driver.findElement(By.css('.qr-ellip-address'))
const addressInput = await driver.findElement(By.css('.readonly-input__input'))
publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs)

View File

@ -44,7 +44,7 @@ class FixtureServer {
return
}
return new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
this._server.close()
this._server.once('error', reject)
this._server.once('close', resolve)

View File

@ -99,24 +99,24 @@ describe('Using MetaMask with an existing account', function () {
it('shows the correct account address', async function () {
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
await driver.findVisibleElement(By.css('.qr-code__wrapper'))
await driver.delay(regularDelayMs)
const [address] = await driver.findElements(By.css('input.qr-ellip-address'))
const [address] = await driver.findElements(By.css('.readonly-input__input'))
assert.equal(await address.getAttribute('value'), testAddress)
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.delay(largeDelayMs)
})
it('shows a QR code for the account', async function () {
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
await driver.findVisibleElement(By.css('.qr-code__wrapper'))
const detailModal = await driver.findElement(By.css('span .modal'))
await driver.delay(regularDelayMs)
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(detailModal))
await driver.delay(regularDelayMs)
})
@ -223,7 +223,7 @@ describe('Using MetaMask with an existing account', function () {
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
assert.equal(txValues.length, 1)
assert.ok(/-1\s*ETH/.test(await txValues[0].getText()))
assert.ok(/-1\s*ETH/u.test(await txValues[0].getText()))
})
})

View File

@ -95,12 +95,12 @@ describe('MetaMask', function () {
})
it('gets the current accounts address', async function () {
const addressInput = await driver.findElement(By.css('.qr-ellip-address'))
const addressInput = await driver.findElement(By.css('.readonly-input__input'))
publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs)
@ -127,7 +127,7 @@ describe('MetaMask', function () {
await driver.clickElement(By.css('#send'))
const txStatus = await driver.findElement(By.css('#success'))
await driver.wait(until.elementTextMatches(txStatus, /Success/), 15000)
await driver.wait(until.elementTextMatches(txStatus, /Success/u), 15000)
})
it('switches back to MetaMask', async function () {
@ -136,7 +136,7 @@ describe('MetaMask', function () {
it('should have the correct amount of eth', async function () {
const balances = await driver.findElements(By.css('.currency-display-component__text'))
await driver.wait(until.elementTextMatches(balances[0], /1/), 15000)
await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000)
const balance = await balances[0].getText()
assert.equal(balance, '1')
@ -193,7 +193,7 @@ describe('MetaMask', function () {
it('should have the correct amount of eth', async function () {
const balances = await driver.findElements(By.css('.currency-display-component__text'))
await driver.wait(until.elementTextMatches(balances[0], /1/), 15000)
await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000)
const balance = await balances[0].getText()
assert.equal(balance, '1')

View File

@ -167,7 +167,7 @@ describe('MetaMask', function () {
it('balance renders', async function () {
const balance = await driver.findElement(By.css('[data-testid="eth-overview__primary-currency"]'))
await driver.wait(until.elementTextMatches(balance, /100\s*ETH/))
await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u))
await driver.delay(regularDelayMs)
})
})
@ -218,7 +218,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000)
})
})
})

View File

@ -121,11 +121,11 @@ describe('MetaMask', function () {
it('shows the QR code for the account', async function () {
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.findVisibleElement(By.css('.qr-wrapper'))
await driver.findVisibleElement(By.css('.qr-code__wrapper'))
await driver.delay(regularDelayMs)
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs)
@ -208,7 +208,7 @@ describe('MetaMask', function () {
it('balance renders', async function () {
const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .list-item__heading'))
await driver.wait(until.elementTextMatches(balance, /100\s*ETH/))
await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u))
await driver.delay(regularDelayMs)
})
})
@ -273,7 +273,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000)
})
})
@ -312,7 +312,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000)
})
})
@ -360,7 +360,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000)
})
})
@ -463,7 +463,7 @@ describe('MetaMask', function () {
}, 10000)
const txValue = await driver.findClickableElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValue, /-3\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValue, /-3\s*ETH/u), 10000)
})
it('the transaction has the expected gas price', async function () {
@ -471,7 +471,7 @@ describe('MetaMask', function () {
await txValue.click()
const popoverCloseButton = await driver.findClickableElement(By.css('.popover-header__button'))
const txGasPrice = await driver.findElement(By.css('[data-testid="transaction-breakdown__gas-price"]'))
await driver.wait(until.elementTextMatches(txGasPrice, /^10$/), 10000)
await driver.wait(until.elementTextMatches(txGasPrice, /^10$/u), 10000)
await popoverCloseButton.click()
})
})
@ -654,7 +654,7 @@ describe('MetaMask', function () {
}, 10000)
const txAction = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txAction[0], /Contract\sDeployment/), 10000)
await driver.wait(until.elementTextMatches(txAction[0], /Contract\sDeployment/u), 10000)
await driver.delay(regularDelayMs)
})
@ -663,20 +663,20 @@ describe('MetaMask', function () {
await driver.delay(regularDelayMs)
let contractStatus = await driver.findElement(By.css('#contractStatus'))
await driver.wait(until.elementTextMatches(contractStatus, /Deployed/), 15000)
await driver.wait(until.elementTextMatches(contractStatus, /Deployed/u), 15000)
await driver.clickElement(By.css('#depositButton'))
await driver.delay(largeDelayMs)
contractStatus = await driver.findElement(By.css('#contractStatus'))
await driver.wait(until.elementTextMatches(contractStatus, /Deposit\sinitiated/), 10000)
await driver.wait(until.elementTextMatches(contractStatus, /Deposit\sinitiated/u), 10000)
await driver.switchToWindow(extension)
await driver.delay(largeDelayMs * 2)
await driver.findElements(By.css('.transaction-list-item'))
const txListValue = await driver.findClickableElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txListValue, /-4\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txListValue, /-4\s*ETH/u), 10000)
await txListValue.click()
await driver.delay(regularDelayMs)
@ -718,7 +718,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues[0], /-4\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues[0], /-4\s*ETH/u), 10000)
})
it('calls and confirms a contract method where ETH is received', async function () {
@ -743,7 +743,7 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues, /-0\s*ETH/), 10000)
await driver.wait(until.elementTextMatches(txValues, /-0\s*ETH/u), 10000)
await driver.closeAllWindowHandlesExcept([extension, dapp])
await driver.switchToWindow(extension)
@ -752,9 +752,9 @@ describe('MetaMask', function () {
it('renders the correct ETH balance', async function () {
const balance = await driver.findElement(By.css('[data-testid="eth-overview__primary-currency"]'))
await driver.delay(regularDelayMs)
await driver.wait(until.elementTextMatches(balance, /^87.*\s*ETH.*$/), 10000)
await driver.wait(until.elementTextMatches(balance, /^87.*\s*ETH.*$/u), 10000)
const tokenAmount = await balance.getText()
assert.ok(/^87.*\s*ETH.*$/.test(tokenAmount))
assert.ok(/^87.*\s*ETH.*$/u.test(tokenAmount))
await driver.delay(regularDelayMs)
})
})
@ -797,7 +797,7 @@ describe('MetaMask', function () {
await driver.delay(tinyDelayMs)
const tokenContractAddress = await driver.findElement(By.css('#tokenAddress'))
await driver.wait(until.elementTextMatches(tokenContractAddress, /0x/))
await driver.wait(until.elementTextMatches(tokenContractAddress, /0x/u))
tokenAddress = await tokenContractAddress.getText()
await driver.delay(regularDelayMs)
@ -830,9 +830,9 @@ describe('MetaMask', function () {
it('renders the balance for the new token', async function () {
const balance = await driver.findElement(By.css('.wallet-overview .token-overview__primary-balance'))
await driver.wait(until.elementTextMatches(balance, /^10\s*TST\s*$/))
await driver.wait(until.elementTextMatches(balance, /^10\s*TST\s*$/u))
const tokenAmount = await balance.getText()
assert.ok(/^10\s*TST\s*$/.test(tokenAmount))
assert.ok(/^10\s*TST\s*$/u.test(tokenAmount))
await driver.delay(regularDelayMs)
})
})
@ -887,7 +887,7 @@ describe('MetaMask', function () {
const confirmDataText = await confirmDataDiv.getText()
await driver.delay(regularDelayMs)
assert(confirmDataText.match(/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/))
assert(confirmDataText.match(/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/u))
await driver.clickElement(By.xpath(`//li[contains(text(), 'Details')]`))
await driver.delay(regularDelayMs)
@ -906,10 +906,10 @@ describe('MetaMask', function () {
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
assert.equal(txValues.length, 1)
await driver.wait(until.elementTextMatches(txValues[0], /-1\s*TST/), 10000)
await driver.wait(until.elementTextMatches(txValues[0], /-1\s*TST/u), 10000)
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/i), 10000)
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/u), 10000)
})
})
@ -931,7 +931,7 @@ describe('MetaMask', function () {
await driver.findElements(By.css('.transaction-list__pending-transactions'))
const txListValue = await driver.findClickableElement(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/), 10000)
await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/u), 10000)
await txListValue.click()
await driver.delay(regularDelayMs)
@ -987,12 +987,12 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/))
await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u))
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/), 10000)
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/u), 10000)
const tokenBalanceAmount = await driver.findElements(By.css('.token-overview__primary-balance'))
await driver.wait(until.elementTextMatches(tokenBalanceAmount[0], /7.5\s*TST/), 10000)
await driver.wait(until.elementTextMatches(tokenBalanceAmount[0], /7.5\s*TST/u), 10000)
})
})
@ -1019,7 +1019,7 @@ describe('MetaMask', function () {
}, 10000)
const [txtListHeading] = await driver.findElements(By.css('.transaction-list-item .list-item__heading'))
await driver.wait(until.elementTextMatches(txtListHeading, /Approve TST spend limit/))
await driver.wait(until.elementTextMatches(txtListHeading, /Approve TST spend limit/u))
await driver.clickElement(By.css('.transaction-list-item'))
await driver.delay(regularDelayMs)
})
@ -1034,7 +1034,7 @@ describe('MetaMask', function () {
const confirmDataDiv = await driver.findElement(By.css('.confirm-approve-content__data__data-block'))
const confirmDataText = await confirmDataDiv.getText()
assert(confirmDataText.match(/0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef4/))
assert(confirmDataText.match(/0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef4/u))
})
it('opens the gas edit modal', async function () {
@ -1105,7 +1105,7 @@ describe('MetaMask', function () {
}, 10000)
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/u))
})
})
@ -1130,7 +1130,7 @@ describe('MetaMask', function () {
}, 10000)
const [txListValue] = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/))
await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/u))
await driver.clickElement(By.css('.transaction-list-item'))
await driver.delay(regularDelayMs)
})
@ -1148,9 +1148,9 @@ describe('MetaMask', function () {
}, 10000)
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/))
await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u))
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Send TST/))
await driver.wait(until.elementTextMatches(txStatuses[0], /Send TST/u))
})
})
@ -1176,7 +1176,7 @@ describe('MetaMask', function () {
}, 10000)
const [txtListHeading] = await driver.findElements(By.css('.transaction-list-item .list-item__heading'))
await driver.wait(until.elementTextMatches(txtListHeading, /Approve TST spend limit/))
await driver.wait(until.elementTextMatches(txtListHeading, /Approve TST spend limit/u))
await driver.clickElement(By.css('.transaction-list-item'))
await driver.delay(regularDelayMs)
})
@ -1203,7 +1203,7 @@ describe('MetaMask', function () {
}, 10000)
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/u))
})
})
@ -1244,7 +1244,7 @@ describe('MetaMask', function () {
it('renders the balance for the chosen token', async function () {
const balance = await driver.findElement(By.css('.token-overview__primary-balance'))
await driver.wait(until.elementTextMatches(balance, /0\s*BAT/))
await driver.wait(until.elementTextMatches(balance, /0\s*BAT/u))
await driver.delay(regularDelayMs)
})
})

View File

@ -32,6 +32,7 @@ const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log('mock 3box server error: ', err)
console.log('mock 3box server error: ', err)
return
}
})

View File

@ -90,11 +90,11 @@ describe('MetaMask', function () {
})
it('gets the current accounts address', async function () {
const addressInput = await driver.findElement(By.css('.qr-ellip-address'))
const addressInput = await driver.findElement(By.css('.readonly-input__input'))
publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs)

View File

@ -205,7 +205,7 @@ describe('Using MetaMask with an existing account', function () {
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
assert.equal(txValues.length, 1)
assert.ok(/-2.2\s*ETH/.test(await txValues[0].getText()))
assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText()))
})
})
})

View File

@ -124,11 +124,11 @@ describe('MetaMask', function () {
await driver.clickElement(By.css('[data-testid="account-options-menu__account-details"]'))
await driver.delay(regularDelayMs)
const addressInput = await driver.findElement(By.css('.qr-ellip-address'))
const addressInput = await driver.findElement(By.css('.readonly-input__input'))
const newPublicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close'))
await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs)

View File

@ -20,7 +20,7 @@ describe('Localization', function () {
await passwordField.sendKeys(Key.ENTER)
const secondaryBalance = await driver.findElement(By.css('[data-testid="eth-overview__secondary-currency"]'))
const secondaryBalanceText = await secondaryBalance.getText()
const [fiatAmount, fiatUnit] = secondaryBalanceText.trim().split(/\s+/)
const [fiatAmount, fiatUnit] = secondaryBalanceText.trim().split(/\s+/u)
assert.ok(fiatAmount.startsWith('₱'))
assert.equal(fiatUnit, 'PHP')
},

View File

@ -97,7 +97,7 @@ describe('MetaMask', function () {
it('balance renders', async function () {
const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .list-item__heading'))
await driver.wait(until.elementTextMatches(balance, /25\s*ETH/))
await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u))
await driver.delay(regularDelayMs)
})
})
@ -203,7 +203,7 @@ describe('MetaMask', function () {
it('balance renders', async function () {
const balance = await driver2.findElement(By.css('[data-testid="wallet-balance"] .list-item__heading'))
await driver2.wait(until.elementTextMatches(balance, /25\s*ETH/))
await driver2.wait(until.elementTextMatches(balance, /25\s*ETH/u))
await driver2.delay(regularDelayMs)
})
})

View File

@ -180,7 +180,9 @@ class Driver {
await fs.writeFile(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' })
const htmlSource = await this.driver.getPageSource()
await fs.writeFile(`${filepathBase}-dom.html`, htmlSource)
const uiState = await this.driver.executeScript(() => window.getCleanAppState())
const uiState = await this.driver.executeScript(
() => window.getCleanAppState && window.getCleanAppState(),
)
await fs.writeFile(`${filepathBase}-state.json`, JSON.stringify(uiState, null, 2))
}

View File

@ -45,7 +45,7 @@ async function setupFetchMocking (driver) {
return { json: async () => clone(fetchMockResponses.ethGasBasic) }
} else if (url.match(/http(s?):\/\/ethgasstation\.info\/json\/predictTable.*/u)) {
return { json: async () => clone(fetchMockResponses.ethGasPredictTable) }
} else if (url.match(/chromeextensionmm/)) {
} else if (url.match(/chromeextensionmm/u)) {
return { json: async () => clone(fetchMockResponses.metametrics) }
}
return window.origFetch(...args)

View File

@ -80,7 +80,7 @@ require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
window.localStorage = {}
// override metamask-logo
window.requestAnimationFrame = () => {}
window.requestAnimationFrame = () => undefined
// crypto.getRandomValues
if (!window.crypto) {

View File

@ -27,7 +27,7 @@ export function mountWithRouter (component, store = {}, pathname = '/') {
context: {
router,
t: (str) => str,
metricsEvent: () => {},
metricsEvent: () => undefined,
store,
},
childContextTypes: {

View File

@ -1,7 +1,3 @@
/* eslint-disable no-native-reassign */
// this is what we're testing
import '../../app/scripts/lib/freezeGlobals'
import assert from 'assert'
@ -10,6 +6,7 @@ describe('Promise global is immutable', function () {
it('throws when reassinging promise (syntax 1)', function () {
try {
// eslint-disable-next-line no-global-assign,no-native-reassign
Promise = {}
assert.fail('did not throw error')
} catch (err) {
@ -28,7 +25,7 @@ describe('Promise global is immutable', function () {
it('throws when mutating existing Promise property', function () {
try {
Promise.all = () => {}
Promise.all = () => undefined
assert.fail('did not throw error')
} catch (err) {
assert.ok(err, 'did throw error')

View File

@ -9,7 +9,7 @@ describe('CachedBalancesController', function () {
getNetwork: () => Promise.resolve(17),
accountTracker: {
store: {
subscribe: () => {},
subscribe: () => undefined,
},
},
initState: {
@ -32,7 +32,7 @@ describe('CachedBalancesController', function () {
const controller = new CachedBalancesController({
accountTracker: {
store: {
subscribe: () => {},
subscribe: () => undefined,
},
},
initState: {
@ -75,7 +75,7 @@ describe('CachedBalancesController', function () {
const controller = new CachedBalancesController({
accountTracker: {
store: {
subscribe: () => {},
subscribe: () => undefined,
},
},
initState: {

View File

@ -14,7 +14,7 @@ describe('DetectTokensController', function () {
const sandbox = sinon.createSandbox()
let keyringMemStore, network, preferences
const noop = () => {}
const noop = () => undefined
const networkControllerProviderConfig = {
getAccounts: noop,
@ -24,7 +24,7 @@ describe('DetectTokensController', function () {
nock('https://api.infura.io')
.get(/.*/)
.get(/.*/u)
.reply(200)
keyringMemStore = new ObservableStore({ isUnlocked: false })

View File

@ -1,7 +1,6 @@
import assert from 'assert'
import sinon from 'sinon'
import ObservableStore from 'obs-store'
import HttpProvider from 'ethjs-provider-http'
import EnsController from '../../../../app/scripts/controllers/ens'
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
@ -10,11 +9,10 @@ const ZERO_X_ERROR_ADDRESS = '0x'
describe('EnsController', function () {
describe('#constructor', function () {
it('should construct the controller given a provider and a network', async function () {
const provider = new HttpProvider('https://ropsten.infura.io')
const currentNetworkId = '3'
const networkStore = new ObservableStore(currentNetworkId)
const ens = new EnsController({
provider,
provider: { },
networkStore,
})

View File

@ -19,7 +19,7 @@ import proxyquire from 'proxyquire'
class ThreeBoxControllerMock {
constructor () {
this.store = {
subscribe: () => {},
subscribe: () => undefined,
getState: () => ({}),
}
this.init = threeBoxSpies.init
@ -78,7 +78,7 @@ const CUSTOM_RPC_URL = 'http://localhost:8545'
describe('MetaMaskController', function () {
let metamaskController
const sandbox = sinon.createSandbox()
const noop = () => {}
const noop = () => undefined
beforeEach(function () {
@ -92,12 +92,12 @@ describe('MetaMaskController', function () {
nock('https://api.infura.io')
.persist()
.get(/.*/)
.get(/.*/u)
.reply(200)
nock('https://min-api.cryptocompare.com')
.persist()
.get(/.*/)
.get(/.*/u)
.reply(200, '{"JPY":12415.9}')
metamaskController = new MetaMaskController({
@ -113,7 +113,7 @@ describe('MetaMaskController', function () {
},
},
initState: cloneDeep(firstTimeState),
platform: { showTransactionNotification: () => {} },
platform: { showTransactionNotification: () => undefined },
})
// disable diagnostics
metamaskController.diagnostics = null
@ -819,7 +819,8 @@ describe('MetaMaskController', function () {
const { promise, resolve } = deferredPromise()
const streamTest = createThoughStream((chunk, _, cb) => {
if (chunk.name !== 'phishing') {
return cb()
cb()
return
}
assert.equal(chunk.data.hostname, (new URL(phishingMessageSender.url)).hostname)
resolve()

View File

@ -6,7 +6,7 @@ import { getNetworkDisplayName } from '../../../../../app/scripts/controllers/ne
describe('NetworkController', function () {
describe('controller', function () {
let networkController
const noop = () => {}
const noop = () => undefined
const networkControllerProviderConfig = {
getAccounts: noop,
}

View File

@ -20,7 +20,7 @@ import {
* - Immutable mock values like Ethereum accounts and expected states
*/
export const noop = () => {}
export const noop = () => undefined
/**
* Mock Permissions Controller and Middleware

View File

@ -372,7 +372,7 @@ describe('preferences controller', function () {
beforeEach(function () {
req = { params: {} }
res = {}
asy = { next: () => {}, end: () => {} }
asy = { next: () => undefined, end: () => undefined }
stubNext = sandbox.stub(asy, 'next')
stubEnd = sandbox.stub(asy, 'end').returns(0)
stubHandleWatchAssetERC20 = sandbox.stub(preferencesController, '_handleWatchAssetERC20')
@ -382,7 +382,7 @@ describe('preferences controller', function () {
})
it('shouldn not do anything if method not corresponds', async function () {
const asy = { next: () => {}, end: () => {} }
const asy = { next: () => undefined, end: () => undefined }
const stubNext = sandbox.stub(asy, 'next')
const stubEnd = sandbox.stub(asy, 'end').returns(0)
req.method = 'metamask'
@ -391,7 +391,7 @@ describe('preferences controller', function () {
sandbox.assert.called(stubNext)
})
it('should do something if method is supported', async function () {
const asy = { next: () => {}, end: () => {} }
const asy = { next: () => undefined, end: () => undefined }
const stubNext = sandbox.stub(asy, 'next')
const stubEnd = sandbox.stub(asy, 'end').returns(0)
req.method = 'metamask_watchAsset'
@ -415,7 +415,7 @@ describe('preferences controller', function () {
assert.deepEqual(res, {})
})
it('should trigger handle add asset if type supported', async function () {
const asy = { next: () => {}, end: () => {} }
const asy = { next: () => undefined, end: () => undefined }
req.method = 'metamask_watchAsset'
req.params.type = 'ERC20'
await preferencesController.requestWatchAsset(req, res, asy.next, asy.end)
@ -442,7 +442,7 @@ describe('preferences controller', function () {
req.params.options = { address, symbol, decimals, image }
sandbox.stub(preferencesController, '_validateERC20AssetParams').returns(true)
preferencesController.openPopup = async () => {}
preferencesController.openPopup = async () => undefined
await preferencesController._handleWatchAssetERC20(req.params.options)
const suggested = preferencesController.getSuggestedTokens()
@ -478,46 +478,16 @@ describe('preferences controller', function () {
assert.ok(assetImages[address], `set image correctly`)
})
it('should validate ERC20 asset correctly', async function () {
const validateSpy = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpy({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 0 })
} catch (e) {}
assert.equal(validateSpy.threw(), false, 'correct options object')
const validateSpyAddress = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyAddress({ symbol: 'ABC', decimals: 0 })
} catch (e) {}
assert.equal(validateSpyAddress.threw(), true, 'options object with no address')
const validateSpySymbol = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpySymbol({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', decimals: 0 })
} catch (e) {}
assert.equal(validateSpySymbol.threw(), true, 'options object with no symbol')
const validateSpyDecimals = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyDecimals({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC' })
} catch (e) {}
assert.equal(validateSpyDecimals.threw(), true, 'options object with no decimals')
const validateSpyInvalidSymbol = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyInvalidSymbol({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: 0 })
} catch (e) {}
assert.equal(validateSpyInvalidSymbol.threw(), true, 'options object with invalid symbol')
const validateSpyInvalidDecimals1 = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyInvalidDecimals1({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: -1 })
} catch (e) {}
assert.equal(validateSpyInvalidDecimals1.threw(), true, 'options object with decimals less than zero')
const validateSpyInvalidDecimals2 = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyInvalidDecimals2({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: 38 })
} catch (e) {}
assert.equal(validateSpyInvalidDecimals2.threw(), true, 'options object with decimals more than 36')
const validateSpyInvalidAddress = sandbox.spy(preferencesController._validateERC20AssetParams)
try {
validateSpyInvalidAddress({ rawAddress: '0x123', symbol: 'ABC', decimals: 0 })
} catch (e) {}
assert.equal(validateSpyInvalidAddress.threw(), true, 'options object with address invalid')
const validate = preferencesController._validateERC20AssetParams
assert.doesNotThrow(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 0 }))
assert.throws(() => validate({ symbol: 'ABC', decimals: 0 }), 'missing address should fail')
assert.throws(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', decimals: 0 }), 'missing symbol should fail')
assert.throws(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC' }), 'missing decimals should fail')
assert.throws(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: 0 }), 'invalid symbol should fail')
assert.throws(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: -1 }), 'decimals < 0 should fail')
assert.throws(() => validate({ rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 38 }), 'decimals > 36 should fail')
assert.throws(() => validate({ rawAddress: '0x123', symbol: 'ABC', decimals: 0 }), 'invalid address should fail')
})
})

View File

@ -147,15 +147,15 @@ describe('PendingTransactionTracker', function () {
},
nonceTracker: {
getGlobalLock: async () => {
return { releaseLock: () => {} }
return { releaseLock: () => undefined }
},
},
getPendingTransactions: () => txList,
getCompletedTransactions: () => {
return []
},
publishTransaction: () => {},
confirmTransaction: () => {},
publishTransaction: () => undefined,
confirmTransaction: () => undefined,
})
const checkPendingTxStub = sinon.stub(pendingTxTracker, '_checkPendingTx').resolves()

View File

@ -13,7 +13,7 @@ import {
SEND_ETHER_ACTION_KEY,
DEPLOY_CONTRACT_ACTION_KEY,
CONTRACT_INTERACTION_KEY,
} from '../../../../../ui/app/helpers/constants/transactions.js'
} from '../../../../../ui/app/helpers/constants/transactions'
import { createTestProviderTools, getTestAccounts } from '../../../../stub/provider'
@ -47,7 +47,7 @@ describe('Transaction Controller', function () {
ethTx.sign(fromAccount.key)
resolve()
}),
getPermittedAccounts: () => {},
getPermittedAccounts: () => undefined,
})
txController.nonceTracker.getNonceLock = () => Promise.resolve({ nextNonce: 0, releaseLock: noop })
})

View File

@ -9,7 +9,7 @@ describe('txUtils', function () {
before(function () {
txUtils = new TxUtils(new Proxy({}, {
get: () => {
return () => {}
return () => undefined
},
}))
})

View File

@ -14,9 +14,6 @@ describe('Message Manager', function () {
assert.ok(Array.isArray(result))
assert.equal(result.length, 0)
})
it('should also return transactions from local storage if any', function () {
})
})
describe('#addMsg', function () {

View File

@ -16,9 +16,10 @@ describe('nodeify', function () {
if (!err) {
assert.equal(res, 'barbaz')
done()
} else {
done(new Error(err.toString()))
return
}
done(new Error(err.toString()))
})
})
@ -37,7 +38,8 @@ describe('nodeify', function () {
try {
nodified((err, result) => {
if (err) {
return done(new Error(`should not have thrown any error: ${err.message}`))
done(new Error(`should not have thrown any error: ${err.message}`))
return
}
assert.equal(42, result, 'got expected result')
})
@ -54,7 +56,8 @@ describe('nodeify', function () {
try {
nodified((err, result) => {
if (result) {
return done(new Error('should not have returned any result'))
done(new Error('should not have returned any result'))
return
}
assert.ok(err, 'got expected error')
assert.ok(err.message.includes('boom!'), 'got expected error message')

View File

@ -14,9 +14,6 @@ describe('Personal Message Manager', function () {
assert.ok(Array.isArray(result))
assert.equal(result.length, 0)
})
it('should also return transactions from local storage if any', function () {
})
})
describe('#addMsg', function () {

View File

@ -38,8 +38,10 @@ let nonDeletableCount = 0
let status
while (transactions.length <= 100) {
status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]
// This is an old migration, let's allow it
// eslint-disable-next-line no-loop-func
if (!deletableTxStates.find((s) => s === status)) {
nonDeletableCount++
nonDeletableCount += 1
}
transactions.push({ status })
}
@ -65,7 +67,7 @@ describe('storage is migrated successfully and the proper transactions are remov
const migratedTransactions = migratedData.data.TransactionController.transactions
migratedTransactions.forEach((tx) => {
if (!deletableTxStates.find((s) => s === tx.status)) {
leftoverNonDeletableTxCount++
leftoverNonDeletableTxCount += 1
}
})
assert.equal(leftoverNonDeletableTxCount, nonDeletableCount, "migration shouldn't delete transactions we want to keep")

View File

@ -1,5 +1,5 @@
import assert from 'assert'
import migrationTemplate from '../../../app/scripts/migrations/030.js'
import migrationTemplate from '../../../app/scripts/migrations/030'
const storage = {
meta: {},

View File

@ -50,7 +50,7 @@ describe('migrations', function () {
migrationNumbers = fileNames
.reduce((acc, filename) => {
const name = filename.split('.')[0]
if (/^\d+$/.test(name)) {
if (/^\d+$/u.test(name)) {
acc.push(name)
}
return acc
@ -70,7 +70,7 @@ describe('migrations', function () {
const testNumbers = fileNames
.reduce((acc, filename) => {
const name = filename.split('-test.')[0]
if (/^\d+$/.test(name)) {
if (/^\d+$/u.test(name)) {
acc.push(name)
}
return acc

View File

@ -19,7 +19,7 @@ const mockStore = (state = defaultState) => configureStore(middleware)(state)
describe('Actions', function () {
const noop = () => {}
const noop = () => undefined
const currentNetworkId = '42'

View File

@ -167,6 +167,23 @@ describe('App State', function () {
})
it('clears account details', function () {
const exportPrivKeyModal = {
accountDetail: {
subview: 'export',
accountExport: 'completed',
privateKey: 'a-priv-key',
},
}
const state = { ...metamaskState, appState: { ...exportPrivKeyModal } }
const newState = reduceApp(state, {
type: actions.CLEAR_ACCOUNT_DETAILS,
})
assert.deepStrictEqual(newState.accountDetail, {})
})
it('shoes account page', function () {
const state = reduceApp(metamaskState, {
type: actions.SHOW_ACCOUNTS_PAGE,

View File

@ -0,0 +1,51 @@
import React from 'react'
import PropTypes from 'prop-types'
import { checksumAddress } from '../../../helpers/utils/util'
import Identicon from '../../ui/identicon'
import AccountMismatchWarning from '../../ui/account-mismatch-warning/account-mismatch-warning.component'
export default function AccountListItem ({
account,
className,
displayAddress = false,
handleClick,
icon = null,
}) {
const { name, address, balance } = account || {}
return (
<div
className={`account-list-item ${className}`}
onClick={() => handleClick && handleClick({ name, address, balance })}
>
<div className="account-list-item__top-row">
<Identicon
address={address}
className="account-list-item__identicon"
diameter={18}
/>
<div className="account-list-item__account-name">{ name || address }</div>
{icon && <div className="account-list-item__icon">{ icon }</div>}
<AccountMismatchWarning address={address} />
</div>
{displayAddress && name && (
<div className="account-list-item__account-address">
{ checksumAddress(address) }
</div>
)}
</div>
)
}
AccountListItem.propTypes = {
account: PropTypes.object,
className: PropTypes.string,
displayAddress: PropTypes.bool,
handleClick: PropTypes.func,
icon: PropTypes.node,
}

View File

@ -0,0 +1 @@
export { default } from './account-list-item'

View File

@ -0,0 +1,26 @@
.account-list-item {
&__top-row {
display: flex;
margin-top: 10px;
margin-left: 8px;
position: relative;
}
&__account-name {
font-size: 16px;
margin-left: 8px;
}
&__icon {
position: absolute;
right: 12px;
top: 1px;
}
&__account-address {
margin-left: 35px;
width: 80%;
overflow: hidden;
text-overflow: ellipsis;
}
}

View File

@ -3,9 +3,8 @@ import assert from 'assert'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import * as utils from '../../../../helpers/utils/util'
import Identicon from '../../../../components/ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'
import AccountListItem from '../account-list-item.component'
import Identicon from '../../../ui/identicon'
import AccountListItem from '../account-list-item'
describe('AccountListItem Component', function () {
let wrapper, propsMethodSpies, checksumAddressStub
@ -22,11 +21,7 @@ describe('AccountListItem Component', function () {
<AccountListItem
account={ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' } }
className="mockClassName"
conversionRate={4}
currentCurrency="mockCurrentyCurrency"
nativeCurrency="ETH"
displayAddress={false}
displayBalance={false}
handleClick={propsMethodSpies.handleClick}
icon={<i className="mockIcon" />}
/>
@ -113,36 +108,5 @@ describe('AccountListItem Component', function () {
wrapper.setProps({ account: { address: 'someAddressButNoName' } })
assert.equal(wrapper.find('.account-list-item__account-address').length, 0)
})
it('should render a CurrencyDisplay with the correct props if displayBalance is true', function () {
wrapper.setProps({ displayBalance: true })
assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 2)
assert.deepEqual(
wrapper.find(UserPreferencedCurrencyDisplay).at(0).props(),
{
type: 'PRIMARY',
value: 'mockBalance',
hideTitle: true,
},
)
})
it('should only render one CurrencyDisplay if showFiat is false', function () {
wrapper.setProps({ showFiat: false, displayBalance: true })
assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 1)
assert.deepEqual(
wrapper.find(UserPreferencedCurrencyDisplay).at(0).props(),
{
type: 'PRIMARY',
value: 'mockBalance',
hideTitle: true,
},
)
})
it('should not render a CurrencyDisplay if displayBalance is false', function () {
wrapper.setProps({ displayBalance: false })
assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 0)
})
})
})

View File

@ -1,63 +0,0 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import Identicon from '../ui/identicon'
import { addressSummary, formatBalance } from '../../helpers/utils/util'
export default class AccountPanel extends Component {
static propTypes = {
identity: PropTypes.object,
account: PropTypes.object,
isFauceting: PropTypes.bool,
}
static defaultProps = {
identity: {},
account: {},
isFauceting: false,
}
render () {
const { identity, account, isFauceting } = this.props
const panelState = {
key: `accountPanel${identity.address}`,
identiconKey: identity.address,
identiconLabel: identity.name || '',
attributes: [
{
key: 'ADDRESS',
value: addressSummary(identity.address),
},
balanceOrFaucetingIndication(account, isFauceting),
],
}
return (
<div
className="identity-panel flex-row flex-space-between"
style={{ flex: '1 0 auto', cursor: panelState.onClick ? 'pointer' : undefined }}
onClick={panelState.onClick}
>
<div className="identicon-wrapper flex-column select-none">
<Identicon address={panelState.identiconKey} />
<span className="font-small">{panelState.identiconLabel.substring(0, 7) + '...'}</span>
</div>
<div className="identity-data flex-column flex-justify-center flex-grow select-none">
{panelState.attributes.map((attr, index) => (
<div className="flex-row flex-space-between" key={index}>
<label className="font-small no-select">{attr.key}</label>
<span className="font-small">{attr.value}</span>
</div>
))}
</div>
</div>
)
}
}
function balanceOrFaucetingIndication (account) {
return {
key: 'BALANCE',
value: formatBalance(account.balance),
}
}

View File

@ -30,7 +30,7 @@ describe('App Header', function () {
<AppHeader.WrappedComponent {...props} />, {
context: {
t: (str) => str,
metricsEvent: () => {},
metricsEvent: () => undefined,
},
},
)
@ -54,8 +54,8 @@ describe('App Header', function () {
const network = wrapper.find({ network: 'test' })
network.simulate('click', {
preventDefault: () => {},
stopPropagation: () => {},
preventDefault: () => undefined,
stopPropagation: () => undefined,
})
assert(props.showNetworkDropdown.calledOnce)
@ -66,8 +66,8 @@ describe('App Header', function () {
const network = wrapper.find({ network: 'test' })
network.simulate('click', {
preventDefault: () => {},
stopPropagation: () => {},
preventDefault: () => undefined,
stopPropagation: () => undefined,
})
assert(props.hideNetworkDropdown.calledOnce)

View File

@ -60,7 +60,7 @@ const AssetListItem = ({
: null
const sendTokenButton = useMemo(() => {
if (tokenAddress == null) {
if (tokenAddress === null || tokenAddress === undefined) {
return null
}
return (

View File

@ -1 +1 @@
export { default } from './asset-list.js'
export { default } from './asset-list'

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