Merge pull request #9054 from MetaMask/Version-v8.0.6

Version v8.0.6 RC
feature/default_network_editable
Mark Stacey 4 years ago committed by GitHub
commit b3304ca35e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      .eslintrc.js
  2. 9
      CHANGELOG.md
  3. 4
      app/_locales/en/messages.json
  4. 2
      app/manifest/_base.json
  5. 3
      app/scripts/controllers/detect-tokens.js
  6. 1
      app/scripts/controllers/permissions/methodMiddleware.js
  7. 12
      app/scripts/controllers/preferences.js
  8. 2
      app/scripts/controllers/transactions/README.md
  9. 2
      app/scripts/controllers/transactions/lib/tx-state-history-helpers.js
  10. 2
      app/scripts/controllers/transactions/tx-gas-utils.js
  11. 10
      app/scripts/controllers/transactions/tx-state-manager.js
  12. 4
      app/scripts/lib/ComposableObservableStore.js
  13. 2
      app/scripts/lib/createStreamSink.js
  14. 4
      app/scripts/lib/decrypt-message-manager.js
  15. 4
      app/scripts/lib/message-manager.js
  16. 3
      app/scripts/lib/migrator/index.js
  17. 2
      app/scripts/lib/notification-manager.js
  18. 2
      app/scripts/lib/personal-message-manager.js
  19. 3
      app/scripts/lib/setupSentry.js
  20. 2
      app/scripts/lib/util.js
  21. 25
      app/scripts/metamask-controller.js
  22. 4
      app/scripts/migrations/028.js
  23. 6
      app/scripts/migrations/037.js
  24. 1
      app/scripts/platforms/extension.js
  25. 6
      development/build/display.js
  26. 1
      development/run-ganache
  27. 2
      docs/add-to-firefox.md
  28. 6
      package.json
  29. 2
      test/e2e/benchmark.js
  30. 3
      test/e2e/helpers.js
  31. 24
      test/e2e/metamask-ui.spec.js
  32. 2
      test/e2e/signature-request.spec.js
  33. 2
      test/e2e/webdriver/index.js
  34. 5
      test/helper.js
  35. 6
      test/unit/app/controllers/detect-tokens-test.js
  36. 12
      test/unit/app/controllers/metamask-controller-test.js
  37. 14
      test/unit/app/controllers/transactions/tx-state-manager-test.js
  38. 10
      test/unit/migrations/023-test.js
  39. 3
      test/unit/migrations/026-test.js
  40. 3
      test/unit/migrations/027-test.js
  41. 3
      test/unit/migrations/028-test.js
  42. 1
      test/unit/ui/app/reducers/metamask.spec.js
  43. 4
      ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.scss
  44. 2
      ui/app/components/app/confirm-page-container/confirm-detail-row/index.scss
  45. 6
      ui/app/components/app/connected-accounts-list/index.scss
  46. 2
      ui/app/components/app/contact-list/contact-list.component.js
  47. 2
      ui/app/components/app/contact-list/recipient-group/recipient-group.component.js
  48. 2
      ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js
  49. 4
      ui/app/components/app/gas-customization/gas-modal-page-container/index.scss
  50. 8
      ui/app/components/app/gas-customization/gas-price-button-group/index.scss
  51. 2
      ui/app/components/app/gas-customization/gas-slider/index.scss
  52. 2
      ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js
  53. 6
      ui/app/components/app/modals/edit-approval-permission/index.scss
  54. 8
      ui/app/components/app/modals/fade-modal.js
  55. 1
      ui/app/components/app/multiple-notifications/index.scss
  56. 4
      ui/app/components/app/permission-page-container/index.scss
  57. 2
      ui/app/components/app/permissions-connect-footer/index.scss
  58. 1
      ui/app/components/app/sidebars/sidebar-content.scss
  59. 4
      ui/app/components/app/signature-request/signature-request-footer/index.scss
  60. 2
      ui/app/components/app/transaction-activity-log/index.scss
  61. 2
      ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js
  62. 2
      ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js
  63. 4
      ui/app/components/app/transaction-list-item/transaction-list-item.component.js
  64. 12
      ui/app/components/ui/alert-circle-icon/index.scss
  65. 7
      ui/app/components/ui/button/buttons.scss
  66. 4
      ui/app/components/ui/check-box/index.scss
  67. 2
      ui/app/components/ui/export-text-container/index.scss
  68. 8
      ui/app/components/ui/icon/index.scss
  69. 2
      ui/app/components/ui/identicon/index.scss
  70. 2
      ui/app/components/ui/tabs/tab/index.scss
  71. 2
      ui/app/components/ui/unit-input/tests/unit-input.component.test.js
  72. 13
      ui/app/css/index.scss
  73. 2
      ui/app/css/itcss/components/account-dropdown.scss
  74. 2
      ui/app/css/itcss/components/confirm.scss
  75. 2
      ui/app/css/itcss/components/modal.scss
  76. 4
      ui/app/css/itcss/components/new-account.scss
  77. 2
      ui/app/css/itcss/components/pages/permission-approval.scss
  78. 2
      ui/app/css/itcss/components/request-signature.scss
  79. 16
      ui/app/css/itcss/components/send.scss
  80. 69
      ui/app/css/itcss/settings/variables.scss
  81. 76
      ui/app/css/variables/colors.scss
  82. 1
      ui/app/css/variables/index.scss
  83. 1
      ui/app/helpers/higher-order-components/with-method-data/index.js
  84. 65
      ui/app/helpers/higher-order-components/with-method-data/with-method-data.component.js
  85. 4
      ui/app/helpers/utils/util.js
  86. 4
      ui/app/helpers/utils/util.test.js
  87. 2
      ui/app/hooks/tests/useCancelTransaction.test.js
  88. 2
      ui/app/hooks/useTransactionDisplayData.js
  89. 2
      ui/app/pages/add-token/index.scss
  90. 8
      ui/app/pages/confirm-approve/confirm-approve-content/index.scss
  91. 2
      ui/app/pages/connected-accounts/index.scss
  92. 2
      ui/app/pages/connected-sites/index.scss
  93. 2
      ui/app/pages/first-time-flow/index.scss
  94. 2
      ui/app/pages/first-time-flow/onboarding-initiator-util.js
  95. 2
      ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/index.scss
  96. 4
      ui/app/pages/permissions-connect/choose-account/index.scss
  97. 2
      ui/app/pages/send/send-footer/tests/send-footer-component.test.js
  98. 2
      ui/app/pages/send/send-header/tests/send-header-component.test.js
  99. 8
      ui/app/pages/send/tests/send-utils.test.js
  100. 32
      ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -41,6 +41,12 @@ module.exports = {
},
rules: {
/* TODO: Remove these when upgrading to `@metamask/eslint-config@2` */
'array-callback-return': 'error',
'callback-return': 'error',
'global-require': 'error',
'guard-for-in': 'error',
/* End v2 rules */
'arrow-parens': 'error',
'no-tabs': 'error',
'no-mixed-operators': 'error',
@ -101,6 +107,13 @@ module.exports = {
rules: {
'import/no-anonymous-default-export': ['error', { 'allowObject': true }],
},
}, {
files: [
'app/scripts/migrations/*.js',
],
rules: {
'global-require': 'off',
},
}],
settings: {

@ -2,6 +2,15 @@
## Current Develop Branch
## 8.0.6 Wed Jul 22 2020
- [#9030](https://github.com/MetaMask/metamask-extension/pull/9030): Hide "delete" button when editing contact of wallet account
- [#9031](https://github.com/MetaMask/metamask-extension/pull/9031): Fix crash upon removing contact
- [#9032](https://github.com/MetaMask/metamask-extension/pull/9032): Do not show spend limit for approvals
- [#9046](https://github.com/MetaMask/metamask-extension/pull/9046): Update @metamask/inpage-provider@6.1.0
- [#9048](https://github.com/MetaMask/metamask-extension/pull/9048): Skip attempts to resolve 0x contract prefix
- [#9051](https://github.com/MetaMask/metamask-extension/pull/9051): Use content-hash@2.5.2
- [#9056](https://github.com/MetaMask/metamask-extension/pull/9056): Display at least one significant digit of small non-zero token balances
## 8.0.5 Thu Jul 16 2020
- [#8942](https://github.com/MetaMask/metamask-extension/pull/8942): Fix display of incoming transactions (#8942)
- [#8998](https://github.com/MetaMask/metamask-extension/pull/8998): Fix `web3_clientVersion` method (#8998)

@ -224,6 +224,10 @@
"approve": {
"message": "Approve spend limit"
},
"approveSpendLimit": {
"message": "Approve $1 spend limit",
"description": "The token symbol that is being approved"
},
"approved": {
"message": "Approved"
},

@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
"version": "8.0.5",
"version": "8.0.6",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",

@ -25,8 +25,7 @@ export default class DetectTokensController {
}
/**
* For each token in eth-contract-metada, find check selectedAddress balance.
*
* For each token in eth-contract-metadata, find check selectedAddress balance.
*/
async detectNewTokens () {
if (!this.isActive) {

@ -107,6 +107,7 @@ export default function createMethodMiddleware ({
}
// when this promise resolves, the response is on its way back
// eslint-disable-next-line callback-return
await next()
if (responseHandler) {

@ -206,13 +206,15 @@ export default class PreferencesController {
res.result = result
end()
}
break
return
default:
end(new Error(`Asset of type ${type} not supported`))
return
}
} else {
next()
}
next()
return
}
/**
@ -335,9 +337,9 @@ export default class PreferencesController {
}
// store lost accounts
for (const key in newlyLost) {
Object.keys(newlyLost).forEach((key) => {
lostIdentities[key] = newlyLost[key]
}
})
}
this.store.updateState({ identities, lostIdentities })

@ -31,7 +31,7 @@ txMeta = {
"time": 1524094064821, // time of creation
"status": "confirmed",
"metamaskNetworkId": "1524091532133", //the network id for the transaction
"loadingDefaults": false, // used to tell the ui when we are done calculatyig gass defaults
"loadingDefaults": false, // used to tell the ui when we are done calculating gas defaults
"txParams": { // the txParams object
"from": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
"to": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",

@ -23,7 +23,7 @@ export function migrateFromSnapshotsToDiffs (longHistory) {
Generates an array of history objects sense the previous state.
The object has the keys
op (the operation performed),
path (the key and if a nested object then each key will be seperated with a `/`)
path (the key and if a nested object then each key will be separated with a `/`)
value
with the first entry having the note and a timestamp when the change took place
@param {Object} previousState - the previous state of the object

@ -7,7 +7,7 @@ import log from 'loglevel'
* debug information for a failed analysis.
* @typedef {Object} GasAnalysisResult
* @property {string} blockGasLimit - The gas limit of the block used for the analysis
* @property {string} estimatedGasHex - The estimated gas, in hexidecimal
* @property {string} estimatedGasHex - The estimated gas, in hexadecimal
* @property {Object} simulationFails - Debug information about why an analysis failed
*/

@ -100,7 +100,7 @@ export default class TransactionStateManager extends EventEmitter {
}
/**
@returns {array} - the tx list whos status is unapproved
@returns {array} - the tx list whose status is unapproved
*/
getUnapprovedTxList () {
const txList = this.getTxsByMetaData('status', 'unapproved')
@ -112,7 +112,7 @@ export default class TransactionStateManager extends EventEmitter {
/**
@param [address] {string} - hex prefixed address to sort the txMetas for [optional]
@returns {array} - the tx list whos status is approved if no address is provide
@returns {array} - the tx list whose status is approved if no address is provide
returns all txMetas who's status is approved for the current network
*/
getApprovedTransactions (address) {
@ -125,7 +125,7 @@ export default class TransactionStateManager extends EventEmitter {
/**
@param [address] {string} - hex prefixed address to sort the txMetas for [optional]
@returns {array} - the tx list whos status is submitted if no address is provide
@returns {array} - the tx list whose status is submitted if no address is provide
returns all txMetas who's status is submitted for the current network
*/
getPendingTransactions (address) {
@ -138,7 +138,7 @@ export default class TransactionStateManager extends EventEmitter {
/**
@param [address] {string} - hex prefixed address to sort the txMetas for [optional]
@returns {array} - the tx list whos status is confirmed if no address is provide
@returns {array} - the tx list whose status is confirmed if no address is provide
returns all txMetas who's status is confirmed for the current network
*/
getConfirmedTransactions (address) {
@ -153,7 +153,7 @@ export default class TransactionStateManager extends EventEmitter {
Adds the txMeta to the list of transactions in the store.
if the list is over txHistoryLimit it will remove a transaction that
is in its final state
it will allso add the key `history` to the txMeta with the snap shot of the original
it will also add the key `history` to the txMeta with the snap shot of the original
object
@param {Object} txMeta
@returns {Object} - the txMeta

@ -25,11 +25,13 @@ export default class ComposableObservableStore extends ObservableStore {
this.config = config
this.removeAllListeners()
for (const key in config) {
if (config.hasOwnProperty(key)) {
config[key].subscribe((state) => {
this.updateState({ [key]: state })
})
}
}
}
/**
* Merges all child store state into a single object rather than
@ -40,10 +42,12 @@ export default class ComposableObservableStore extends ObservableStore {
getFlatState () {
let flatState = {}
for (const key in this.config) {
if (this.config.hasOwnProperty(key)) {
const controller = this.config[key]
const state = controller.getState ? controller.getState() : controller.state
flatState = { ...flatState, ...state }
}
}
return flatState
}
}

@ -9,7 +9,7 @@ class AsyncWritableStream extends WritableStream {
this._asyncWriteFn = asyncWriteFn
}
// write from incomming stream to state
// write from incoming stream to state
_write (chunk, encoding, callback) {
promiseToCallback(this._asyncWriteFn(chunk, encoding))(callback)
}

@ -30,9 +30,9 @@ export default class DecryptMessageManager extends EventEmitter {
* Controller in charge of managing - storing, adding, removing, updating - DecryptMessage.
*
* @typedef {Object} DecryptMessageManager
* @property {Object} memStore The observable store where DecryptMessage are saved with persistance.
* @property {Object} memStore The observable store where DecryptMessage are saved.
* @property {Object} memStore.unapprovedDecryptMsgs A collection of all DecryptMessages in the 'unapproved' state
* @property {number} memStore.unapprovedDecryptMsgCount The count of all DecryptMessages in this.memStore.unapprobedMsgs
* @property {number} memStore.unapprovedDecryptMsgCount The count of all DecryptMessages in this.memStore.unapprovedDecryptMsgs
* @property {array} messages Holds all messages that have been created by this DecryptMessageManager
*
*/

@ -32,7 +32,7 @@ export default class MessageManager extends EventEmitter {
* @param {Object} opts @deprecated
* @property {Object} memStore The observable store where Messages are saved.
* @property {Object} memStore.unapprovedMsgs A collection of all Messages in the 'unapproved' state
* @property {number} memStore.unapprovedMsgCount The count of all Messages in this.memStore.unapprobedMsgs
* @property {number} memStore.unapprovedMsgCount The count of all Messages in this.memStore.unapprovedMsgs
* @property {array} messages Holds all messages that have been created by this MessageManager
*
*/
@ -99,7 +99,7 @@ export default class MessageManager extends EventEmitter {
* new Message to this.messages, and to save the unapproved Messages from that list to this.memStore.
*
* @param {Object} msgParams - The params for the eth_sign call to be made after the message is approved.
* @param {Object} req (optional) The original request object where the origin may be specificied
* @param {Object} req (optional) The original request object where the origin may be specified
* @returns {number} - The id of the newly created message.
*
*/

@ -35,8 +35,7 @@ export default class Migrator extends EventEmitter {
const pendingMigrations = this.migrations.filter(migrationIsPending)
// perform each migration
for (const index in pendingMigrations) {
const migration = pendingMigrations[index]
for (const migration of pendingMigrations) {
try {
// attempt migration and validate
const migratedData = await migration.migrate(versionedData)

@ -68,7 +68,7 @@ export default class NotificationManager {
* type 'popup')
*
* @private
* @param {Function} cb - A node style callback that to whcih the found notification window will be passed.
* @param {Function} cb - A node style callback that to which the found notification window will be passed.
*
*/
async _getPopup () {

@ -33,7 +33,7 @@ export default class PersonalMessageManager extends EventEmitter {
*
* @typedef {Object} PersonalMessageManager
* @param {Object} opts @deprecated
* @property {Object} memStore The observable store where PersonalMessage are saved with persistance.
* @property {Object} memStore The observable store where PersonalMessage are saved.
* @property {Object} memStore.unapprovedPersonalMsgs A collection of all PersonalMessages in the 'unapproved' state
* @property {number} memStore.unapprovedPersonalMsgCount The count of all PersonalMessages in this.memStore.unapprobedMsgs
* @property {array} messages Holds all messages that have been created by this PersonalMessageManager

@ -101,6 +101,9 @@ export default function setupSentry ({ release, getState }) {
// append app state
if (getState) {
const appState = getState()
if (!report.extra) {
report.extra = {}
}
report.extra.appState = appState
}
} catch (err) {

@ -134,7 +134,7 @@ function BnMultiplyByFraction (targetBN, numerator, denominator) {
/**
* Returns an Error if extension.runtime.lastError is present
* this is a workaround for the non-standard error object thats used
* this is a workaround for the non-standard error object that's used
* @returns {Error}
*/
function checkForError () {

@ -1119,6 +1119,7 @@ export default class MetamaskController extends EventEmitter {
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
return
}
}
@ -1177,6 +1178,7 @@ export default class MetamaskController extends EventEmitter {
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
return
}
}
@ -1197,7 +1199,7 @@ export default class MetamaskController extends EventEmitter {
}
/**
* Only decypt message and don't touch transaction state
* Only decrypt message and don't touch transaction state
*
* @param {Object} msgParams - The params of the message to decrypt.
* @returns {Promise<Object>} - A full state update.
@ -1261,6 +1263,7 @@ export default class MetamaskController extends EventEmitter {
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
return
}
}
@ -1318,6 +1321,7 @@ export default class MetamaskController extends EventEmitter {
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
return
}
}
@ -1377,6 +1381,7 @@ export default class MetamaskController extends EventEmitter {
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
return
}
}
@ -1843,8 +1848,10 @@ export default class MetamaskController extends EventEmitter {
this.currencyRateController.update(currencyState)
this.currencyRateController.configure(currencyState)
cb(null, this.currencyRateController.state)
return
} catch (err) {
cb(err)
return
}
}
@ -1925,8 +1932,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setUseBlockie(val)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -1939,8 +1948,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setUseNonceField(val)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -1953,8 +1964,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setUsePhishDetect(val)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -1967,8 +1980,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setIpfsGateway(val)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -1981,8 +1996,10 @@ export default class MetamaskController extends EventEmitter {
try {
const metaMetricsId = this.preferencesController.setParticipateInMetaMetrics(bool)
cb(null, metaMetricsId)
return
} catch (err) {
cb(err)
return
}
}
@ -1990,8 +2007,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setMetaMetricsSendCount(val)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -2004,8 +2023,10 @@ export default class MetamaskController extends EventEmitter {
try {
this.preferencesController.setFirstTimeFlowType(type)
cb(null)
return
} catch (err) {
cb(err)
return
}
}
@ -2019,8 +2040,10 @@ export default class MetamaskController extends EventEmitter {
try {
const direction = this.preferencesController.setCurrentLocale(key)
cb(null, direction)
return
} catch (err) {
cb(err)
return
}
}

@ -29,9 +29,9 @@ function transformState (state) {
const identities = newState.PreferencesController.identities
const tokens = newState.PreferencesController.tokens
newState.PreferencesController.accountTokens = {}
for (const identity in identities) {
Object.keys(identities).forEach((identity) => {
newState.PreferencesController.accountTokens[identity] = { 'mainnet': tokens }
}
})
newState.PreferencesController.tokens = []
}
}

@ -27,9 +27,9 @@ function transformState (state) {
const newAddressBook = {}
// add all of the chainIds to a set
for (const item in ab) {
chainIds.add(ab[item].chainId)
}
Object.values(ab).forEach((v) => {
chainIds.add(v.chainId)
})
// fill the chainId object with the entries with the matching chainId
for (const id of chainIds.values()) {

@ -105,6 +105,7 @@ export default class ExtensionPlatform {
})
} catch (e) {
cb(e)
return
}
}

@ -15,7 +15,7 @@ const SYMBOLS = {
Quarter: '▎',
Eighth: '▏',
RightHalf: '▐',
RightEigth: '▕',
RightEighth: '▕',
}
function setupTaskDisplay (taskEvents) {
@ -47,7 +47,7 @@ function displayChart (data) {
console.log(`\nbuild completed. task timeline:`)
// build bars for bounds
data.map((entry, index) => {
data.forEach((entry, index) => {
const [label, start, end] = entry
const [start2, end2] = [start, end].map((value) => adjust(value, first, last, 40))
const barString = barBuilder(start2, end2)
@ -141,7 +141,7 @@ function getSymbolNormalRight (value) {
} else if (rounded === 1 / 2) {
return SYMBOLS.RightHalf
} else if (rounded === 7 / 8) {
return SYMBOLS.RightEigth
return SYMBOLS.RightEighth
} else if (rounded === 1) {
return SYMBOLS.Space
} else {

@ -22,6 +22,7 @@ _int () {
trap _term SIGTERM
trap _int SIGINT
# shellcheck disable=SC2086
$ganache_cli --noVMErrorsOnRPCResponse --networkId 5777 --mnemonic "$seed_phrase" ${GANACHE_ARGS:-} &
child=$!

@ -10,5 +10,5 @@ You can optionally enable debugging, and click `Debug`, for a console window tha
If you have problems debugging, try connecting to the IRC channel `#webextensions` on `irc.mozilla.org`.
For longer questions, use the StackOverfow tag `firefox-addons`.
For longer questions, use the StackOverflow tag `firefox-addons`.

@ -67,9 +67,9 @@
"@material-ui/core": "^4.11.0",
"@metamask/controllers": "^2.0.1",
"@metamask/eth-ledger-bridge-keyring": "^0.2.6",
"@metamask/eth-token-tracker": "^2.0.0",
"@metamask/eth-token-tracker": "^3.0.0",
"@metamask/etherscan-link": "^1.1.0",
"@metamask/inpage-provider": "^6.0.1",
"@metamask/inpage-provider": "^6.1.0",
"@popperjs/core": "^2.4.0",
"@reduxjs/toolkit": "^1.3.2",
"@sentry/browser": "^5.11.1",
@ -83,7 +83,7 @@
"bn.js": "^4.11.7",
"c3": "^0.7.10",
"classnames": "^2.2.6",
"content-hash": "^2.5.0",
"content-hash": "^2.5.2",
"copy-to-clipboard": "^3.0.8",
"currency-formatter": "^1.4.2",
"d3": "^5.15.0",

@ -43,7 +43,7 @@ const standardDeviationResult = calculateResult((array) => {
const squareDiffs = array.map((value) => Math.pow(value - average, 2))
return Math.sqrt(calculateAverage(squareDiffs))
})
// 95% margin of error calculated using Student's t-distrbution
// 95% margin of error calculated using Student's t-distribution
const calculateMarginOfError = (array) => ttest(array).confidence()[1] - calculateAverage(array)
const marginOfErrorResult = calculateResult((array) => calculateMarginOfError(array))

@ -33,6 +33,7 @@ async function withFixtures (options, callback) {
const { driver } = await buildWebDriver(driverOptions)
webDriver = driver
// eslint-disable-next-line callback-return
await callback({
driver,
})
@ -46,7 +47,9 @@ async function withFixtures (options, callback) {
}
}
} catch (error) {
if (webDriver) {
await webDriver.verboseReportOnFailure(title)
}
throw error
} finally {
await fixtureServer.stop()

@ -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.000\s*TST\s*$/))
await driver.wait(until.elementTextMatches(balance, /^10\s*TST\s*$/))
const tokenAmount = await balance.getText()
assert.ok(/^10.000\s*TST\s*$/.test(tokenAmount))
assert.ok(/^10\s*TST\s*$/.test(tokenAmount))
await driver.delay(regularDelayMs)
})
})
@ -992,7 +992,7 @@ describe('MetaMask', function () {
await driver.wait(until.elementTextMatches(txStatuses[0], /Send\sTST/), 10000)
const tokenBalanceAmount = await driver.findElements(By.css('.token-overview__primary-balance'))
await driver.wait(until.elementTextMatches(tokenBalanceAmount[0], /7.500\s*TST/), 10000)
await driver.wait(until.elementTextMatches(tokenBalanceAmount[0], /7.5\s*TST/), 10000)
})
})
@ -1018,8 +1018,8 @@ describe('MetaMask', function () {
return pendingTxes.length === 1
}, 10000)
const [txListValue] = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txListValue, /-7\s*TST/))
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.clickElement(By.css('.transaction-list-item'))
await driver.delay(regularDelayMs)
})
@ -1104,14 +1104,12 @@ describe('MetaMask', function () {
return confirmedTxes.length === 3
}, 10000)
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues[0], /-5\s*TST/))
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve/))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/))
})
})
describe('Tranfers a custom token from dapp when no gas value is specified', function () {
describe('Transfers a custom token from dapp when no gas value is specified', function () {
it('transfers an already created token, without specifying gas', async function () {
const windowHandles = await driver.getAllWindowHandles()
const extension = windowHandles[0]
@ -1177,8 +1175,8 @@ describe('MetaMask', function () {
return pendingTxes.length === 1
}, 10000)
const [txListValue] = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txListValue, /-7\s*TST/))
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.clickElement(By.css('.transaction-list-item'))
await driver.delay(regularDelayMs)
})
@ -1204,10 +1202,8 @@ describe('MetaMask', function () {
return confirmedTxes.length === 5
}, 10000)
const txValues = await driver.findElements(By.css('.transaction-list-item__primary-currency'))
await driver.wait(until.elementTextMatches(txValues[0], /-7\s*TST/))
const txStatuses = await driver.findElements(By.css('.list-item__heading'))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve/))
await driver.wait(until.elementTextMatches(txStatuses[0], /Approve TST spend limit/))
})
})

@ -51,7 +51,7 @@ describe('MetaMask', function () {
await driver.quit()
})
describe('successfuly signs typed data', function () {
describe('successfully signs typed data', function () {
let extension
let popup
let dapp

@ -9,7 +9,7 @@ async function buildWebDriver ({ responsive, port } = {}) {
const extensionPath = `dist/${browser}`
const { driver: seleniumDriver, extensionId, extensionUrl } = await buildBrowserWebDriver(browser, { extensionPath, responsive, port })
setupFetchMocking(seleniumDriver)
await setupFetchMocking(seleniumDriver)
const driver = new Driver(seleniumDriver, browser, extensionUrl)
await driver.navigate()

@ -3,6 +3,8 @@ import nock from 'nock'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import log from 'loglevel'
import { JSDOM } from 'jsdom'
nock.disableNetConnect()
nock.enableNetConnect('localhost')
@ -45,8 +47,6 @@ global.log = log
//
// dom
const { JSDOM } = require('jsdom')
const jsdom = new JSDOM()
global.window = jsdom.window
@ -87,5 +87,6 @@ if (!window.crypto) {
window.crypto = {}
}
if (!window.crypto.getRandomValues) {
// eslint-disable-next-line global-require
window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues')
}

@ -89,8 +89,8 @@ describe('DetectTokensController', function () {
controller.isOpen = true
controller.isUnlocked = true
const contractAddressses = Object.keys(contracts)
const erc20ContractAddresses = contractAddressses
const contractAddresses = Object.keys(contracts)
const erc20ContractAddresses = contractAddresses
.filter((contractAddress) => contracts[contractAddress].erc20 === true)
const existingTokenAddress = erc20ContractAddresses[0]
@ -100,7 +100,7 @@ describe('DetectTokensController', function () {
const tokenAddressToAdd = erc20ContractAddresses[1]
const tokenToAdd = contracts[tokenAddressToAdd]
const contractAddresssesToDetect = contractAddressses
const contractAddresssesToDetect = contractAddresses
.filter((address) => address !== existingTokenAddress)
const indexOfTokenToAdd = contractAddresssesToDetect.indexOf(tokenAddressToAdd)

@ -53,9 +53,9 @@ const createLoggerMiddlewareMock = () => (req, res, next) => {
loggerMiddlewareMock.responses.push(res)
cb()
})
} else {
next()
return
}
next()
}
const MetaMaskController = proxyquire('../../../../app/scripts/metamask-controller', {
@ -839,9 +839,9 @@ describe('MetaMaskController', function () {
const streamTest = createThoughStream((chunk, _, cb) => {
if (chunk.data && chunk.data.method) {
cb(null, chunk)
} else {
cb()
return
}
cb()
})
metamaskController.setupUntrustedCommunication(streamTest, messageSender)
@ -877,9 +877,9 @@ describe('MetaMaskController', function () {
const streamTest = createThoughStream((chunk, _, cb) => {
if (chunk.data && chunk.data.method) {
cb(null, chunk)
} else {
cb()
return
}
cb()
})
metamaskController.setupUntrustedCommunication(streamTest, messageSender)

@ -323,7 +323,7 @@ describe('TransactionStateManager', function () {
}
const invalidValues = [1, true, {}, Symbol('1')]
for (const key in validTxParams) {
Object.keys(validTxParams).forEach((key) => {
for (const value of invalidValues) {
const tx = {
id: 1,
@ -339,7 +339,7 @@ describe('TransactionStateManager', function () {
assert.ok(Array.isArray(result), 'txList should be an array')
assert.equal(result.length, 0, 'txList should be empty')
}
}
})
})
it('does not override txs from other networks', function () {
@ -361,7 +361,7 @@ describe('TransactionStateManager', function () {
}
const result = txStateManager.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 1, 'early txs truncted')
assert.equal(result[0].id, 1, 'early txs truncated')
})
it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function () {
@ -372,7 +372,7 @@ describe('TransactionStateManager', function () {
}
const result = txStateManager.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 1, 'early txs truncted')
assert.equal(result[0].id, 1, 'early txs truncated')
})
it('cuts off early txs beyond a limit but does not cut unapproved txs', function () {
@ -387,7 +387,7 @@ describe('TransactionStateManager', function () {
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 0, 'first tx should still be there')
assert.equal(result[0].status, 'unapproved', 'first tx should be unapproved')
assert.equal(result[1].id, 2, 'early txs truncted')
assert.equal(result[1].id, 2, 'early txs truncated')
})
})
@ -416,7 +416,7 @@ describe('TransactionStateManager', function () {
txStateManager.addTx({ id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: validTxParams })
for (const key in validTxParams) {
Object.keys(validTxParams).forEach((key) => {
for (const value of invalidValues) {
const originalTx = txStateManager.getTx(1)
const newTx = {
@ -430,7 +430,7 @@ describe('TransactionStateManager', function () {
const result = txStateManager.getTx(1)
assert.deepEqual(result, originalTx, 'tx should not be updated')
}
}
})
})
it('updates gas price and adds history items', function () {

@ -68,31 +68,31 @@ describe('storage is migrated successfully and the proper transactions are remov
leftoverNonDeletableTxCount++
}
})
assert.equal(leftoverNonDeletableTxCount, nonDeletableCount, 'migration shouldnt delete transactions we want to keep')
assert.equal(leftoverNonDeletableTxCount, nonDeletableCount, "migration shouldn't delete transactions we want to keep")
assert((migratedTransactions.length >= 40), `should be equal or greater to 40 if they are non deletable states got ${migratedTransactions.length} transactions`)
done()
}).catch(done)
})
it('should not remove any transactions because 40 is the expectable limit', function (done) {
it('should not remove any transactions because 40 is the expected limit', function (done) {
storage.meta.version = 22
storage.data.TransactionController.transactions = transactions40
migration23.migrate(storage)
.then((migratedData) => {
const migratedTransactions = migratedData.data.TransactionController.transactions
assert.equal(migratedTransactions.length, 40, 'migration shouldnt delete when at limit')
assert.equal(migratedTransactions.length, 40, "migration shouldn't delete when at limit")
done()
}).catch(done)
})
it('should not remove any transactions because 20 txs is under the expectable limit', function (done) {
it('should not remove any transactions because 20 txs is under the expected limit', function (done) {
storage.meta.version = 22
storage.data.TransactionController.transactions = transactions20
migration23.migrate(storage)
.then((migratedData) => {
const migratedTransactions = migratedData.data.TransactionController.transactions
assert.equal(migratedTransactions.length, 20, 'migration shouldnt delete when under limit')
assert.equal(migratedTransactions.length, 20, "migration shouldn't delete when under limit")
done()
}).catch(done)
})

@ -1,4 +1,5 @@
import assert from 'assert'
import firstTimeState from '../../../app/scripts/first-time-state'
import migration26 from '../../../app/scripts/migrations/026'
const oldStorage = {
@ -32,7 +33,7 @@ describe('migration #26', function () {
it('should successfully migrate first time state', function (done) {
migration26.migrate({
meta: {},
data: require('../../../app/scripts/first-time-state'),
data: firstTimeState,
})
.then((migratedData) => {
assert.equal(migratedData.meta.version, migration26.version)

@ -1,4 +1,5 @@
import assert from 'assert'
import firstTimeState from '../../../app/scripts/first-time-state'
import migration27 from '../../../app/scripts/migrations/027'
const oldStorage = {
@ -42,7 +43,7 @@ describe('migration #27', function () {
it('should successfully migrate first time state', function (done) {
migration27.migrate({
meta: {},
data: require('../../../app/scripts/first-time-state'),
data: firstTimeState,
})
.then((migratedData) => {
assert.equal(migratedData.meta.version, migration27.version)

@ -1,4 +1,5 @@
import assert from 'assert'
import firstTimeState from '../../../app/scripts/first-time-state'
import migration28 from '../../../app/scripts/migrations/028'
const oldStorage = {
@ -36,7 +37,7 @@ describe('migration #28', function () {
it('should successfully migrate first time state', function (done) {
migration28.migrate({
meta: {},
data: require('../../../app/scripts/first-time-state'),
data: firstTimeState,
})
.then((migratedData) => {
assert.equal(migratedData.meta.version, migration28.version)

@ -12,7 +12,6 @@ describe('MetaMask Reducers', function () {
it('locks MetaMask', function () {
const unlockMetaMaskState = {
isUnlocked: true,
isInitialzed: false,
selectedAddress: 'test address',
}
const lockMetaMask = reduceMetamask(unlockMetaMaskState, {

@ -17,7 +17,7 @@
}
&__dismiss-button {
background: #037dd6;
background: $primary-blue;
color: white;
height: 40px;
width: 100px;
@ -29,7 +29,7 @@
margin-bottom: 16px;
padding: 16px;
font-size: 14px;
border: 1px solid #d73a49;
border: 1px solid $accent-red;
background: #f8eae8;
border-radius: 3px;
}

@ -35,7 +35,7 @@
color: $scorpion;
&--edit {
color: $curious-blue;
color: $primary-blue;
cursor: pointer;
}

@ -34,7 +34,7 @@
&,
&:hover {
color: $curious-blue;
color: $primary-blue;
cursor: pointer;
}
}
@ -49,8 +49,8 @@
border-top: 1px solid $geyser;
&--highlight {
background-color: $warning-light-yellow;
border: 1px solid $warning-yellow;
background-color: $Yellow-000;
border: 1px solid $accent-yellow;
box-sizing: border-box;
padding: 16px;
margin-bottom: 16px;

@ -67,7 +67,7 @@ export default class ContactList extends PureComponent {
return 1
} else if (letter1 === letter2) {
return 0
} else if (letter1 < letter2) {
} else {
return -1
}
})

@ -53,7 +53,7 @@ export default function RecipientGroup ({ label, items, onSelect, selectedAddres
RecipientGroup.propTypes = {
label: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape({
address: PropTypes.string,
address: PropTypes.string.isRequired,
name: PropTypes.string,
})),
onSelect: PropTypes.func.isRequired,

@ -74,7 +74,7 @@ describe('Advanced Gas Inputs', function () {
assert.equal(props.updateCustomGasLimit.calledWith(21000), true)
})
it('errors when insuffientBalance under gas price and gas limit', function () {
it('errors when insufficientBalance under gas price and gas limit', function () {
wrapper.setProps({ insufficientBalance: true })
const renderError = wrapper.find('.advanced-gas-inputs__gas-edit-row__error-text')
assert.equal(renderError.length, 2)

@ -68,8 +68,8 @@
}
&--selected {
color: $curious-blue;
border-bottom: 2px solid $curious-blue;
color: $primary-blue;
border-bottom: 2px solid $primary-blue;
}
}
}

@ -50,13 +50,13 @@
}
.button-group__button--active {
border: 2px solid $curious-blue;
border: 2px solid $primary-blue;
color: $scorpion;
i {
&:last-child {
display: flex;
color: $curious-blue;
color: $primary-blue;
margin-top: 8px;
}
}
@ -137,7 +137,7 @@
i {
&:last-child {
display: flex;
color: $curious-blue;
color: $primary-blue;
margin-top: 10px;
}
}
@ -235,7 +235,7 @@
i {
display: flex;
color: $curious-blue;
color: $primary-blue;
font-size: 12px;
}
}

@ -16,7 +16,7 @@
-webkit-appearance: none !important;
height: 34px;
width: 34px;
background-color: $curious-blue;
background-color: $primary-blue;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
border-radius: 50%;
position: relative;

@ -33,7 +33,7 @@ describe('Confirm Reset Account', function () {
assert(props.hideModal.calledOnce)
})
it('resets account and hidels modal when reset button is clicked', function (done) {
it('resets account and hides modal when reset button is clicked', function (done) {
const reset = wrapper.find('.btn-danger.modal-container__footer-button')
reset.simulate('click')

@ -97,7 +97,7 @@
}
&__option-label--selected {
color: #037dd6;
color: $primary-blue;
}
&__option-description {
@ -136,7 +136,7 @@
}
&__radio-button-outline--selected {
background: #037dd6;
background: $primary-blue;
}
&__radio-button-fill {
@ -150,7 +150,7 @@
&__radio-button-dot {
width: 8px;
height: 8px;
background: #037dd6;
background: $primary-blue;
border-radius: 4px;
position: absolute;
}

@ -25,16 +25,16 @@ const insertKeyframesRule = (keyframes) => {
const name = 'anim_' + (++index) + (+new Date())
let css = '@' + 'keyframes ' + name + ' {'
for (const key in keyframes) {
Object.keys(keyframes).forEach((key) => {
css += key + ' {'
for (const property in keyframes[key]) {
Object.keys(keyframes[key]).forEach((property) => {
const part = ':' + keyframes[key][property] + ';'
css += property + part
}
})
css += '}'
}
})
css += '}'

@ -16,7 +16,6 @@
position: relative;
width: 100%;
height: 100%;
visibility: none;
.fa-sm {
display: initial;

@ -129,8 +129,8 @@
}
&__tooltip-body {
display: 'flex';
flex-direction: 'column';
display: flex;
flex-direction: column;
}
&__bold-title-elements {

@ -14,7 +14,7 @@
margin-top: 10px;
&--link {
color: #037dd6;
color: $primary-blue;
margin-left: 4px;
cursor: pointer;
}

@ -34,7 +34,6 @@
.page-container__bottom {
display: flex;
flex-direction: column;
flex-flow: space-between;
height: 100%;
}

@ -9,11 +9,11 @@
border-radius: 3px;
}
button:first-child() {
button:first-child {
margin-left: 1rem;
}
button:last-child() {
button:last-child {
margin-right: 1rem;
}
}

@ -75,7 +75,7 @@
&__action-link {
font-size: 0.75rem;
cursor: pointer;
color: $curious-blue;
color: $primary-blue;
}
b {

@ -3,7 +3,7 @@ import { combineTransactionHistories, getActivities } from '../transaction-activ
describe('TransactionActivityLog utils', function () {
describe('combineTransactionHistories', function () {
it('should return no activites for an empty list of transactions', function () {
it('should return no activities for an empty list of transactions', function () {
assert.deepEqual(combineTransactionHistories([]), [])
})

@ -171,7 +171,7 @@ export function getActivities (transaction, isFirstTransaction = false) {
return acc
}, [])
// If txReceipt.status is '0x0', that means that an on-chain error occured for the transaction,
// If txReceipt.status is '0x0', that means that an on-chain error occurred for the transaction,
// so we add an error entry to the Activity Log.
return status === '0x0'
? historyActivities.concat({ id, hash, eventKey: TRANSACTION_ERRORED_EVENT })

@ -15,6 +15,7 @@ import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes'
import {
TRANSACTION_CATEGORY_SIGNATURE_REQUEST,
UNAPPROVED_STATUS,
TRANSACTION_CATEGORY_APPROVAL,
FAILED_STATUS,
DROPPED_STATUS,
REJECTED_STATUS,
@ -55,6 +56,7 @@ export default function TransactionListItem ({ transactionGroup, isEarliestNonce
const isSignatureReq = category === TRANSACTION_CATEGORY_SIGNATURE_REQUEST
const isApproval = category === TRANSACTION_CATEGORY_APPROVAL
const isUnapproved = status === UNAPPROVED_STATUS
const className = classnames('transaction-list-item', {
@ -137,7 +139,7 @@ export default function TransactionListItem ({ transactionGroup, isEarliestNonce
</span>
</h3>
)}
rightContent={!isSignatureReq && (
rightContent={!isSignatureReq && !isApproval && (
<>
<h2 className="transaction-list-item__primary-currency">{primaryCurrency}</h2>
<h3 className="transaction-list-item__secondary-currency">{secondaryCurrency}</h3>

@ -1,13 +1,13 @@
.alert-circle-icon {
&--danger {
border-color: $danger-red;
color: $danger-red;
background: $danger-light-red;
border-color: $accent-red;
color: $accent-red;
background: $Red-000;
}
&--warning {
border-color: $warning-yellow;
color: $warning-yellow;
background: $warning-light-yellow;
border-color: $accent-yellow;
color: $accent-yellow;
background: $Yellow-000;
}
}

@ -8,7 +8,6 @@ $hover-confirm: #0372c3;
$hover-red: #feb6bf;
$hover-red-primary: #c72837;
$hover-orange: #ffd3b5;
$danger-light-red: #ea7e77;
$warning-light-orange: #f8b588;
%button {
@ -216,7 +215,7 @@ $warning-light-orange: #f8b588;
*/
.btn-raised {
color: $curious-blue;
color: $primary-blue;
background-color: $white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
padding: 6px;
@ -297,7 +296,7 @@ button.primary {
&--disabled,
&[disabled] {
border-color: $Red-100;
color: $danger-light-red;
color: $Red-300;
}
&:active {
@ -337,7 +336,7 @@ button.primary {
&--disabled,
&[disabled] {
background-color: $danger-light-red;
background-color: $Red-300;
}
&:active {

@ -12,8 +12,8 @@
&__checked,
&__indeterminate {
color: $curious-blue;
border-color: $curious-blue;
color: $primary-blue;
border-color: $primary-blue;
}
&:disabled {

@ -39,7 +39,7 @@
align-items: center;
font-size: 12px;
cursor: pointer;
color: $curious-blue;
color: $primary-blue;
&--copy {
border-right: 1px solid $alto;

@ -2,18 +2,18 @@
margin: 0 4px;
&--success {
fill: $success-green;
fill: $accent-green;
}
&--info {
fill: $info-blue;
fill: $primary-blue;
}
&--warning {
fill: $warning-yellow;
fill: $accent-yellow;
}
&--danger {
fill: $danger-red;
fill: $accent-red;
}
}

@ -17,7 +17,7 @@
border-style: solid;
border-radius: 50%;
border-width: 2px;
border-color: $curious-blue;
border-color: $primary-blue;
}
&__eth-logo {

@ -6,6 +6,6 @@
&--active {
color: $black;
border-bottom: 2px solid $curious-blue;
border-bottom: 2px solid $primary-blue;
}
}

@ -27,7 +27,7 @@ describe('UnitInput Component', function () {
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH')
})
it('should render properly with a child omponent', function () {
it('should render properly with a child component', function () {
const wrapper = shallow(
<UnitInput>
<div className="testing">

@ -1,14 +1,25 @@
/*
MetaMask design system imports
The variables declared here should take precedence.
They are included first because they will be used to replace bad variable names in itcss
prior to it being fully removed from the system.
*/
@import './variables/index';
/*
ITCSS
http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
*/
DEPRECATED: This CSS architecture is deprecated. The following imports will be removed
overtime.
*/
@import './itcss/settings/index';
@import './itcss/tools/index';
@import './itcss/generic/index';
@import './itcss/objects/index';
@import './itcss/components/index';
@import './itcss/trumps/index';
// Other imports
@import '../../../node_modules/react-select/dist/react-select';

@ -78,7 +78,7 @@
position: absolute;
top: 3px;
left: -8px;
color: $curious-blue;
color: $primary-blue;
}
&__account-primary-balance {

@ -98,7 +98,7 @@
}
.confirm-screen-back-button {
color: $curious-blue;
color: $primary-blue;
font-family: Roboto;
font-size: 1rem;
position: absolute;

@ -342,7 +342,7 @@
}
&__link {
color: $curious-blue;
color: $primary-blue;
}
}

@ -53,8 +53,8 @@
}
&__selected {
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
color: $primary-blue;
border-bottom: 3px solid $primary-blue;
cursor: initial;
pointer-events: none;
}

@ -5,7 +5,7 @@
}
.permission_approval_origin {
font-weight: 999;
font-weight: 900;
margin-top: 16px;
word-wrap: break-word;
}

@ -230,7 +230,7 @@
&__help-link {
cursor: pointer;
text-decoration: underline;
color: $curious-blue;
color: $primary-blue;
}
&__footer {

@ -149,7 +149,7 @@
.currency-toggle {
&__item {
color: $curious-blue;
color: $primary-blue;
cursor: pointer;
&--selected {
@ -160,7 +160,7 @@
}
.send-screen-gas-input-customize {
color: $curious-blue;
color: $primary-blue;
font-size: 12px;
cursor: pointer;
}
@ -801,8 +801,8 @@
}
input:checked + &__button {
background-color: #037dd6;
border: 2px solid #037dd6;
background-color: $primary-blue;
border: 2px solid $primary-blue;
color: #fff;
}
}
@ -830,7 +830,7 @@
justify-content: center;
height: 24px;
width: 24px;
border: 1px solid $curious-blue;
border: 1px solid $primary-blue;
border-radius: 4px;
background-color: $white;
position: absolute;
@ -841,7 +841,7 @@
}
&__sliders-icon {
color: $curious-blue;
color: $primary-blue;
}
&__memo-text-area {
@ -1077,7 +1077,7 @@
justify-content: center;
height: 24px;
width: 24px;
border: 1px solid $curious-blue;
border: 1px solid $primary-blue;
border-radius: 4px;
background-color: $white;
position: absolute;
@ -1105,5 +1105,5 @@
}
.sliders-icon {
color: $curious-blue;
color: $primary-blue;
}

@ -13,23 +13,12 @@ $gray: #808080;
Colors
http://chir.ag/projects/name-that-color
*/
$white-linen: #faf6f0; // formerly 'faint orange (textfield shades)'
$rajah: #f5c26d; // formerly 'light orange (button shades)'
$buttercup: #f5a623; // formerly 'dark orange (text)'
$tundora: #4a4a4a; // formerly 'borders/font/any gray'
$flamingo: #f56821;
$valencia: #d73a49;
$gallery: #efefef;
$alabaster: #f7f7f7;
$shark: #22232c;
$wild-sand: #f6f6f6;
$white: #fff;
$dusty-gray: #9b9b9b;
$alto: #dedede;
$alabaster: #fafafa;
$silver-chalice: #aeaeae;
$curious-blue: #037dd6;
$concrete: #f3f3f3;
$tundora: #4d4d4d;
$nile-blue: #1b344d;
$scorpion: #5d5d5d;
@ -42,19 +31,12 @@ $purple: #690496;
$tulip-tree: #ebb33f;
$malibu-blue: #7ac9fd;
$athens-grey: #e9edf0;
$jaffa: #f28930;
$geyser: #d2d8dd;
$manatee: #93949d;
$spindle: #c7ddec;
$mid-gray: #5b5d67;
$cape-cod: #38393a;
$onahau: #d1edff;
$java: #29b6af;
$wild-strawberry: #ff4a8d;
$cornflower-blue: #7057ff;
$saffron: #f6c343;
$dodger-blue: #3099f2;
$zumthor: #edf7ff;
$ecstasy: #f7861c;
$linen: #fdf4f4;
$oslo-gray: #8c8e94;
@ -63,19 +45,6 @@ $blizzard-blue: #bfdef3;
$mischka: #dddee9;
$web-orange: #f2a202;
$mercury: #e5e5e5;
$lochmara: #037dd6;
/*
notification and error message colors
*/
$success-green: #28a745;
$success-light-green: #e8f9f1;
$danger-red: #d73a49;
$danger-light-red: #f8eae8;
$info-blue: #037dd6;
$info-light-blue: #e8f4fd;
$warning-yellow: #ffd33d;
$warning-light-yellow: #fefae8;
/*
Z-Indicies
@ -139,44 +108,6 @@ $break-large: 576px;
$primary-font-type: Roboto;
$Blue-000: #eaf6ff;
$Blue-100: #a7d9fe;
$Blue-200: #75c4fd;
$Blue-300: #43aefc;
$Blue-400: #1098fc;
$Blue-500: #037dd6;
$Blue-600: #0260a4;
$Blue-700: #024272;
$Blue-800: #01253f;
$Blue-900: #00080d;
$Grey-000: #f2f3f4;
$Grey-100: #d6d9dc;
$Grey-200: #bbc0c5;
$Grey-300: #9fa6ae;
$Grey-400: #848c96;
$Grey-200: #bbc0c5;
$Grey-500: #6a737d;
$Grey-600: #535a61;
$Grey-800: #24272a;
$Red-000: #fcf2f3;
$Red-100: #f7d5d8;
$Red-200: #f1b9be;
$Red-300: #e88f97;
$Red-400: #e06470;
$Red-500: #d73a49;
$Red-600: #b92534;
$Red-700: #8e1d28;
$Red-800: #64141c;
$Red-900: #3a0c10;
$Orange-000: #fef5ef;
$Orange-300: #faa66c;
$Orange-600: #c65507;
$Orange-500: #f66a0a;
$Black-100: #24292e;
// Font Sizes
%h3 {

@ -0,0 +1,76 @@
// These are the colors of the MetaMask design system
// Only design system colors should be added, no superfluous variables
// See https://bit.ly/32mnoja (link to figma design system)
$Blue-000: #eaf6ff;
$Blue-100: #a7d9fe;
$Blue-200: #75c4fd;
$Blue-300: #43aefc;
$Blue-400: #1098fc;
$Blue-500: #037dd6;
$Blue-600: #0260a4;
$Blue-700: #024272;
$Blue-800: #01253f;
$Blue-900: #00080d;
$Grey-000: #f2f3f4;
$Grey-100: #d6d9dc;
$Grey-200: #bbc0c5;
$Grey-300: #9fa6ae;
$Grey-400: #848c96;
$Grey-500: #6a737d;
$Grey-600: #535a61;
$Grey-700: #3b4046;
$Grey-800: #24272a;
$Grey-900: #141618;
$Green-000: #f3fcf5;
$Green-100: #d6ffdf;
$Green-200: #afecbd;
$Green-300: #86e29b;
$Green-400: #5dd879;
$Green-500: #28a745;
$Green-600: #1e7e34;
$Green-700: #145523;
$Green-800: #0a2c12;
$Green-900: #041007;
$Red-000: #fcf2f3;
$Red-100: #f7d5d8;
$Red-200: #f1b9be;
$Red-300: #e88f97;
$Red-400: #e06470;
$Red-500: #d73a49;
$Red-600: #b92534;
$Red-700: #8e1d28;
$Red-800: #64141c;
$Red-900: #3a0c10;
$Orange-000: #fef5ef;
$Orange-100: #fde2cf;
$Orange-200: #fbc49d;
$Orange-300: #faa66c;
$Orange-400: #f8883b;
$Orange-500: #f66a0a;
$Orange-600: #c65507;
$Orange-700: #954005;
$Orange-800: #632b04;
$Orange-900: #321602;
$Yellow-000: #fefae8; // Temporary placeholder
$Yellow-100: #fefcde;
$Yellow-500: #ffd33d;
$Black-100: #24292e;
$primary-blue: $Blue-500;
$primary-orange: $Orange-500;
$accent-yellow: $Yellow-500;
$accent-green: $Green-500;
$accent-red: $Red-500;
$accent-purple: #6f42c1;
$accent-pink: #ff45d8;
$neutral-white: #fff;
$neutral-black: $Black-100;
$neutral-grey: $Grey-500;

@ -0,0 +1 @@
@import './colors.scss';

@ -1 +0,0 @@
export { default } from './with-method-data.component'

@ -1,65 +0,0 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { getMethodDataAsync, getFourBytePrefix } from '../../utils/transactions.util'
export default function withMethodData (WrappedComponent) {
return class MethodDataWrappedComponent extends PureComponent {
static propTypes = {
transaction: PropTypes.object,
knownMethodData: PropTypes.object,
addKnownMethodData: PropTypes.func,
}
static defaultProps = {
transaction: {},
knownMethodData: {},
}
state = {
methodData: {},
done: false,
error: null,
}
componentDidMount () {
this.fetchMethodData()
}
async fetchMethodData () {
const { transaction, knownMethodData, addKnownMethodData } = this.props
const { txParams: { data = '' } = {} } = transaction
if (data) {
try {
let methodData
const fourBytePrefix = getFourBytePrefix(data)
if (fourBytePrefix in knownMethodData) {
methodData = knownMethodData[fourBytePrefix]
} else {
methodData = await getMethodDataAsync(data)
if (!Object.entries(methodData).length === 0) {
addKnownMethodData(fourBytePrefix, methodData)
}
}
this.setState({ methodData, done: true })
} catch (error) {
this.setState({ done: true, error })
}
} else {
this.setState({ done: true })
}
}
render () {
const { methodData, done, error } = this.state
return (
<WrappedComponent
{ ...this.props }
methodData={{ data: methodData, done, error }}
/>
)
}
}
}

@ -28,9 +28,9 @@ const valueTable = {
tether: '0.000000000001',
}
const bnTable = {}
for (const currency in valueTable) {
Object.keys(valueTable).forEach((currency) => {
bnTable[currency] = new ethUtil.BN(valueTable[currency], 10)
}
})
export function isEthNetwork (netId) {
if (!netId || netId === '1' || netId === '3' || netId === '4' || netId === '42' || netId === '5777') {

@ -230,11 +230,11 @@ describe('util', function () {
}
const oneEthBn = new ethUtil.BN(ethInWei, 10)
for (const currency in valueTable) {
Object.keys(valueTable).forEach((currency) => {
const value = new ethUtil.BN(valueTable[currency], 10)
const output = util.normalizeToWei(value, currency)
assert.equal(output.toString(10), valueTable.wei, `value of ${output.toString(10)} ${currency} should convert to ${oneEthBn}`)
}
})
})
})

@ -21,7 +21,7 @@ describe('useCancelTransaction', function () {
dispatch.resetHistory()
})
describe('when account has insufficent balance to cover gas', function () {
describe('when account has insufficient balance to cover gas', function () {
before(function () {
useSelector = sinon.stub(reactRedux, 'useSelector')
useSelector.callsFake((selector) => {

@ -106,7 +106,7 @@ export function useTransactionDisplayData (transactionGroup) {
subtitleContainsOrigin = true
} else if (transactionCategory === TOKEN_METHOD_APPROVE) {
category = TRANSACTION_CATEGORY_APPROVAL
title = t('approve')
title = t('approveSpendLimit', [token?.symbol || t('token')])
subtitle = origin
subtitleContainsOrigin = true
} else if (transactionCategory === DEPLOY_CONTRACT_ACTION_KEY || transactionCategory === CONTRACT_INTERACTION_KEY) {

@ -36,7 +36,7 @@
&__edit {
flex: 1 1 auto;
text-align: right;
color: $curious-blue;
color: $primary-blue;
padding-right: 4px;
cursor: pointer;
}

@ -141,7 +141,7 @@
div {
width: 22px;
height: 2px;
background: #037dd6;
background: $primary-blue;
position: absolute;
}
@ -157,7 +157,7 @@
&__circle {
width: 14px;
height: 14px;
border: 2px solid #037dd6;
border: 2px solid $primary-blue;
border-radius: 50%;
background: white;
position: absolute;
@ -236,7 +236,7 @@
font-size: 14px;
line-height: 20px;
font-weight: 500;
color: #037dd6;
color: $primary-blue;
}
&__medium-text,
@ -262,7 +262,7 @@
}
&__small-blue-text {
color: #037dd6;
color: $primary-blue;
}
&__info-row {

@ -2,7 +2,7 @@
&__footer {
a,
a:hover {
color: #037dd6;
color: $primary-blue;
cursor: pointer;
font-size: 14px;
}

@ -28,7 +28,7 @@
a:hover {
font-size: 14px;
line-height: 20px;
color: #037dd6;
color: $primary-blue;
cursor: pointer;
}
}

@ -159,6 +159,6 @@
}
&__link-text {
color: $curious-blue;
color: $primary-blue;
}
}

@ -18,7 +18,7 @@ const returnToOnboardingInitiatorTab = async (onboardingInitiator) => {
if (!tab) {
// this case can happen if the tab was closed since being checked with `extension.tabs.get`
log.warn(`Setting current tab to onboarding initator has failed; falling back to redirect`)
log.warn(`Setting current tab to onboarding initiator has failed; falling back to redirect`)
window.location.assign(onboardingInitiator.location)
} else {
window.close()

@ -54,7 +54,7 @@
}
&__export-text {
color: $curious-blue;
color: $primary-blue;
cursor: pointer;
font-weight: 500;
}

@ -34,7 +34,7 @@
}
&__text-blue {
color: $curious-blue;
color: $primary-blue;
cursor: pointer;
}
@ -143,7 +143,7 @@
display: flex;
flex-direction: column;
align-items: flex-end;
color: #037dd6;
color: $primary-blue;
}
}

@ -128,7 +128,7 @@ describe('SendFooter Component', function () {
},
}
Object.entries(config).map(([description, obj]) => {
Object.entries(config).forEach(([description, obj]) => {
it(description, function () {
wrapper.setProps(obj)
assert.equal(wrapper.instance().formShouldBeDisabled(), obj.expectedResult)

@ -56,7 +56,7 @@ describe('SendHeader Component', function () {
})
describe('render', function () {
it('should render a PageContainerHeader compenent', function () {
it('should render a PageContainerHeader component', function () {
assert.equal(wrapper.find(PageContainerHeader).length, 1)
})

@ -103,7 +103,7 @@ describe('send utils', function () {
expectedResult: false,
},
}
Object.entries(config).map(([description, obj]) => {
Object.entries(config).forEach(([description, obj]) => {
it(description, function () {
assert.equal(doesAmountErrorRequireUpdate(obj), obj.expectedResult)
})
@ -166,7 +166,7 @@ describe('send utils', function () {
expectedResult: { amount: INSUFFICIENT_TOKENS_ERROR },
},
}
Object.entries(config).map(([description, obj]) => {
Object.entries(config).forEach(([description, obj]) => {
it(description, function () {
assert.deepEqual(getAmountErrorObject(obj), obj.expectedResult)
})
@ -190,7 +190,7 @@ describe('send utils', function () {
expectedResult: { gasFee: null },
},
}
Object.entries(config).map(([description, obj]) => {
Object.entries(config).forEach(([description, obj]) => {
it(description, function () {
assert.deepEqual(getGasFeeErrorObject(obj), obj.expectedResult)
})
@ -198,7 +198,7 @@ describe('send utils', function () {
})
describe('calcTokenBalance()', function () {
it('should return the calculated token blance', function () {
it('should return the calculated token balance', function () {
assert.equal(calcTokenBalance({
sendToken: {
address: '0x0',

@ -1,5 +1,6 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { Redirect } from 'react-router-dom'
import Identicon from '../../../../components/ui/identicon'
import Button from '../../../../components/ui/button/button.component'
import TextField from '../../../../components/ui/text-field'
@ -23,11 +24,11 @@ export default class EditContact extends PureComponent {
viewRoute: PropTypes.string,
listRoute: PropTypes.string,
setAccountLabel: PropTypes.func,
showingMyAccounts: PropTypes.bool.isRequired,
}
static defaultProps = {
name: '',
address: '',
memo: '',
}
@ -40,22 +41,43 @@ export default class EditContact extends PureComponent {
render () {
const { t } = this.context
const { history, name, addToAddressBook, removeFromAddressBook, address, chainId, memo, viewRoute, listRoute, setAccountLabel } = this.props
const {
address,
addToAddressBook,
chainId,
history,
listRoute,
memo,
name,
removeFromAddressBook,
setAccountLabel,
showingMyAccounts,
viewRoute,
} = this.props
if (!address) {
return <Redirect to={{ pathname: listRoute }} />
}
return (
<div className="settings-page__content-row address-book__edit-contact">
<div className="settings-page__header address-book__header--edit">
<Identicon address={address} diameter={60} />
{
showingMyAccounts
? null
: (
<Button
type="link"
className="settings-page__address-book-button"
onClick={async () => {
await removeFromAddressBook(chainId, address)
history.push(listRoute)
}}
>
{t('deleteAccount')}
</Button>
)
}
</div>
<div className="address-book__edit-contact__content">
<div className="address-book__view-contact__group">
@ -117,7 +139,9 @@ export default class EditContact extends PureComponent {
if (isValidAddress(this.state.newAddress)) {
await removeFromAddressBook(chainId, address)
await addToAddressBook(this.state.newAddress, this.state.newName || name, this.state.newMemo || memo)
if (showingMyAccounts) {
setAccountLabel(this.state.newAddress, this.state.newName || name)
}
history.push(listRoute)
} else {
this.setState({ error: this.context.t('invalidAddress') })
@ -125,7 +149,9 @@ export default class EditContact extends PureComponent {
} else {
// update name
await addToAddressBook(address, this.state.newName || name, this.state.newMemo || memo)
if (showingMyAccounts) {
setAccountLabel(address, this.state.newName || name)
}
history.push(listRoute)
}
}}

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

Loading…
Cancel
Save