1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 09:57:02 +01:00

Merge pull request #7466 from MetaMask/Version-v7.6.0

Version v7.6.0 RC
This commit is contained in:
Thomas Huang 2019-11-18 17:15:55 -08:00 committed by GitHub
commit 86c39c806e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 775 additions and 187 deletions

View File

@ -77,7 +77,7 @@ workflows:
jobs:
create_release_pull_request:
docker:
- image: circleci/node:8.15.1-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- run:
@ -89,7 +89,7 @@ jobs:
prep-deps:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- run:
@ -108,7 +108,7 @@ jobs:
prep-build:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -127,7 +127,7 @@ jobs:
prep-docs:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -142,7 +142,7 @@ jobs:
prep-scss:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -161,7 +161,7 @@ jobs:
test-lint:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -175,7 +175,7 @@ jobs:
test-deps:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -186,7 +186,7 @@ jobs:
test-e2e-chrome:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -201,7 +201,7 @@ jobs:
test-e2e-firefox:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- run:
@ -219,7 +219,7 @@ jobs:
job-publish-prerelease:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -249,7 +249,7 @@ jobs:
job-publish-release:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -273,7 +273,7 @@ jobs:
test-unit:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -288,7 +288,7 @@ jobs:
- coverage
test-unit-global:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -298,7 +298,7 @@ jobs:
command: yarn test:unit:global
test-mozilla-lint:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -309,7 +309,7 @@ jobs:
test-integration-flat-firefox:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -325,7 +325,7 @@ jobs:
environment:
browsers: '["Chrome"]'
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:
@ -336,7 +336,7 @@ jobs:
all-tests-pass:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- run:
name: All Tests Passed
@ -344,7 +344,7 @@ jobs:
coveralls-upload:
docker:
- image: circleci/node:10.16-browsers
- image: circleci/node:10.17-browsers
steps:
- checkout
- attach_workspace:

View File

@ -148,7 +148,10 @@
"operator-linebreak": [2, "after", { "overrides": { "?": "ignore", ":": "ignore" } }],
"padded-blocks": "off",
"quotes": [2, "single", {"avoidEscape": true, "allowTemplateLiterals": true}],
"react/jsx-curly-brace-presence": [2, { "props": "never", "children": "never" }],
"react/jsx-equals-spacing": 2,
"react/no-deprecated": 0,
"react/default-props-match-prop-types": 2,
"semi": [2, "never"],
"semi-spacing": [2, { "before": false, "after": true }],
"space-before-blocks": [2, "always"],

2
.nvmrc
View File

@ -1 +1 @@
v10.16.3
v10.17.0

View File

@ -2,6 +2,8 @@
## Current Develop Branch
## 7.6.0 Mon Nov 18 2019
## 7.5.3 Fri Nov 15 2019
- [#7412](https://github.com/MetaMask/metamask-extension/pull/7412): lock eth-contract-metadata (#7412)
- [#7416](https://github.com/MetaMask/metamask-extension/pull/7416): Add eslint import plugin to help detect unresolved paths

View File

@ -1,4 +1,10 @@
{
"migrateSai": {
"message": "A message from Maker: The new Multi-Collateral Dai token has been released. Your old tokens are now called Sai. Please upgrade your Sai tokens to the new Dai."
},
"migrate": {
"message": "Migrate"
},
"showIncomingTransactions": {
"message": "Show Incoming Transactions"
},

View File

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

View File

@ -0,0 +1,67 @@
const version = 39
const clone = require('clone')
const ethUtil = require('ethereumjs-util')
const DAI_V1_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
const DAI_V1_TOKEN_SYMBOL = 'DAI'
const SAI_TOKEN_SYMBOL = 'SAI'
function isOldDai (token = {}) {
return token && typeof token === 'object' &&
token.symbol === DAI_V1_TOKEN_SYMBOL &&
ethUtil.toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS
}
/**
* This migration renames the Dai token to Sai.
*
* As of 2019-11-18 Dai is now called Sai (refs https://git.io/JeooP) to facilitate
* Maker's upgrade to Multi-Collateral Dai and this migration renames the token
* at the old address.
*/
module.exports = {
version,
migrate: async function (originalVersionedData) {
const versionedData = clone(originalVersionedData)
versionedData.meta.version = version
const state = versionedData.data
versionedData.data = transformState(state)
return versionedData
},
}
function transformState (state) {
const { PreferencesController } = state
if (PreferencesController) {
const tokens = PreferencesController.tokens || []
if (Array.isArray(tokens)) {
for (const token of tokens) {
if (isOldDai(token)) {
token.symbol = SAI_TOKEN_SYMBOL
}
}
}
const accountTokens = PreferencesController.accountTokens || {}
if (accountTokens && typeof accountTokens === 'object') {
for (const address of Object.keys(accountTokens)) {
const networkTokens = accountTokens[address]
if (networkTokens && typeof networkTokens === 'object') {
for (const network of Object.keys(networkTokens)) {
const tokensOnNetwork = networkTokens[network]
if (Array.isArray(tokensOnNetwork)) {
for (const token of tokensOnNetwork) {
if (isOldDai(token)) {
token.symbol = SAI_TOKEN_SYMBOL
}
}
}
}
}
}
}
}
return state
}

View File

@ -49,4 +49,5 @@ module.exports = [
require('./036'),
require('./037'),
require('./038'),
require('./039'),
]

View File

@ -87,7 +87,7 @@
"dnode": "^1.2.2",
"end-of-stream": "^1.1.0",
"eth-block-tracker": "^4.4.2",
"eth-contract-metadata": "1.9.3",
"eth-contract-metadata": "^1.11.0",
"eth-ens-namehash": "^2.0.8",
"eth-json-rpc-errors": "^1.1.0",
"eth-json-rpc-filters": "^4.1.1",
@ -114,7 +114,7 @@
"extensionizer": "^1.0.1",
"fast-json-patch": "^2.0.4",
"fuse.js": "^3.2.0",
"gaba": "^1.8.0",
"gaba": "^1.9.0",
"human-standard-token-abi": "^2.0.0",
"jazzicon": "^1.2.0",
"json-rpc-engine": "^5.1.5",

View File

@ -0,0 +1,419 @@
const assert = require('assert')
const migration39 = require('../../../app/scripts/migrations/039')
describe('migration #39', () => {
it('should update the version metadata', (done) => {
const oldStorage = {
'meta': {
'version': 38,
},
'data': {},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.meta, {
'version': 39,
})
done()
})
.catch(done)
})
it('should update old DAI token symbol to SAI in tokens', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': [{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'DAI',
}, {
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'symbol': 'BAT',
'decimals': 18,
}, {
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'symbol': 'META',
'decimals': 18,
}],
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data.PreferencesController, {
'tokens': [{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'SAI',
}, {
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'symbol': 'BAT',
'decimals': 18,
}, {
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'symbol': 'META',
'decimals': 18,
}],
})
done()
})
.catch(done)
})
it('should update old DAI token symbol to SAI in accountTokens', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'accountTokens': {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
'mainnet': [
{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'DAI',
},
],
},
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
'mainnet': [],
'rinkeby': [],
},
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
'mainnet': [
{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'DAI',
},
{
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'decimals': 18,
'symbol': 'BAT',
},
{
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'decimals': 18,
'symbol': 'META',
},
],
},
},
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data.PreferencesController, {
'accountTokens': {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
'mainnet': [
{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'SAI',
},
],
},
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
'mainnet': [],
'rinkeby': [],
},
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
'mainnet': [
{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'SAI',
},
{
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'decimals': 18,
'symbol': 'BAT',
},
{
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'decimals': 18,
'symbol': 'META',
},
],
},
},
})
done()
})
.catch(done)
})
it('should NOT change any state if accountTokens is not an object', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'accountTokens': [],
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if accountTokens is an object with invalid values', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'accountTokens': {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': [
{
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
'decimals': 18,
'symbol': 'DAI',
},
],
'0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359': null,
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
'mainnet': [
null,
undefined,
[],
42,
],
'rinkeby': null,
},
},
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if accountTokens includes the new DAI token', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'accountTokens': {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
'mainnet': [
{
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
'decimals': 18,
'symbol': 'DAI',
},
],
},
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
'mainnet': [],
'rinkeby': [],
},
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
'mainnet': [
{
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
'decimals': 18,
'symbol': 'DAI',
},
{
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'decimals': 18,
'symbol': 'BAT',
},
{
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'decimals': 18,
'symbol': 'META',
},
],
},
},
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if tokens includes the new DAI token', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': [{
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
'symbol': 'DAI',
'decimals': 18,
}, {
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'symbol': 'META',
'decimals': 18,
}],
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if tokens does not include DAI', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': [{
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
'symbol': 'BAT',
'decimals': 18,
}, {
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
'symbol': 'META',
'decimals': 18,
}],
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if a tokens property has invalid entries', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': [
null,
[],
undefined,
42,
],
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if a tokens property is not an array', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': {},
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if a tokens property is null', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
'tokens': null,
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if a tokens property is missing', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if a accountTokens property is missing', (done) => {
const oldStorage = {
'meta': {},
'data': {
'PreferencesController': {
},
},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
it('should NOT change any state if PreferencesController is missing', (done) => {
const oldStorage = {
'meta': {},
'data': {},
}
migration39.migrate(oldStorage)
.then((newStorage) => {
assert.deepEqual(newStorage.data, oldStorage.data)
done()
})
.catch(done)
})
})

View File

@ -37,12 +37,12 @@ describe('Token Cell', () => {
wrapper = mount(
<Provider store={store}>
<TokenCell
address={'0xAnotherToken'}
symbol={'TEST'}
string={'5.000'}
address="0xAnotherToken"
symbol="TEST"
string="5.000"
network={22}
currentCurrency={'usd'}
image={'./test-image'}
currentCurrency="usd"
image="./test-image"
/>
</Provider>
)

View File

@ -76,7 +76,7 @@ export default class AccountDetails extends Component {
</div>
</div>
<Tooltip
position={'bottom'}
position="bottom"
title={hasCopied ? t('copiedExclamation') : t('copyToClipboard')}
wrapperClassName="account-details__tooltip"
>

View File

@ -14,15 +14,15 @@ describe('Confirm Detail Row Component', function () {
beforeEach(() => {
wrapper = shallow(
<ConfirmDetailRow
errorType={'mockErrorType'}
label={'mockLabel'}
errorType="mockErrorType"
label="mockLabel"
showError={false}
primaryText = {'mockFiatText'}
secondaryText = {'mockEthText'}
primaryValueTextColor= {'mockColor'}
onHeaderClick= {propsMethodSpies.onHeaderClick}
headerText = {'mockHeaderText'}
headerTextClassName = {'mockHeaderClass'}
primaryText="mockFiatText"
secondaryText="mockEthText"
primaryValueTextColor="mockColor"
onHeaderClick={propsMethodSpies.onHeaderClick}
headerText="mockHeaderText"
headerTextClassName="mockHeaderClass"
/>
)
})

View File

@ -0,0 +1,46 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import HomeNotification from '../home-notification'
export default class DaiV1MigrationNotification extends PureComponent {
static contextTypes = {
t: PropTypes.func,
}
static defaultProps = {
string: '',
symbol: '',
}
static propTypes = {
string: PropTypes.string,
symbol: PropTypes.string,
}
render () {
const { t } = this.context
const { string: balanceString, symbol } = this.props
if (!balanceString || !symbol) {
return null
}
if (balanceString === '0') {
return null
}
return (
<HomeNotification
descriptionText={t('migrateSai')}
acceptText={t('migrate')}
onAccept={() => {
window.open('https://migrate.makerdao.com', '_blank', 'noopener')
}}
ignoreText={t('learnMore')}
onIgnore={() => {
window.open('https://blog.makerdao.com/multi-collateral-dai-is-live/', '_blank', 'noopener')
}}
/>
)
}
}

View File

@ -0,0 +1,20 @@
import { connect } from 'react-redux'
import { compose } from 'recompose'
import DaiMigrationNotification from './dai-migration-notification.component'
import withTokenTracker from '../../../helpers/higher-order-components/with-token-tracker'
import { getSelectedAddress, getDaiV1Token } from '../../../selectors/selectors'
const mapStateToProps = (state) => {
const userAddress = getSelectedAddress(state)
const oldDai = getDaiV1Token(state)
return {
userAddress,
token: oldDai,
}
}
export default compose(
connect(mapStateToProps),
withTokenTracker,
)(DaiMigrationNotification)

View File

@ -0,0 +1 @@
export { default } from './dai-migration-notification.container'

View File

@ -4,8 +4,6 @@ const h = require('react-hyperscript')
const MenuDroppo = require('../../menu-droppo')
const extend = require('xtend')
const noop = () => {}
class Dropdown extends Component {
render () {
const {
@ -55,8 +53,6 @@ class Dropdown extends Component {
}
Dropdown.defaultProps = {
isOpen: false,
onClick: noop,
useCssTransition: false,
}

View File

@ -12,9 +12,9 @@ describe('Dropdown', () => {
beforeEach(() => {
wrapper = shallow(
<DropdownMenuItem
onClick = {onClickSpy}
style = {{test: 'style'}}
closeMenu = {closeMenuSpy}
onClick={onClickSpy}
style={{test: 'style'}}
closeMenu={closeMenuSpy}
>
</DropdownMenuItem>
)

View File

@ -11,7 +11,7 @@ describe('Dropdown Menu Components', () => {
beforeEach(() => {
wrapper = shallow(
<Menu className = {'Test Class'} isShowing = {true}/>
<Menu className="Test Class" isShowing={true}/>
)
})
@ -29,10 +29,10 @@ describe('Dropdown Menu Components', () => {
beforeEach(() => {
wrapper = shallow(
<Item
icon = {'test icon'}
text = {'test text'}
className = {'test className'}
onClick = {onClickSpy}
icon="test icon"
text="test text"
className="test className"
onClick={onClickSpy}
/>
)
})
@ -74,7 +74,7 @@ describe('Dropdown Menu Components', () => {
beforeEach(() => {
wrapper = shallow(<CloseArea
onClick = {onClickSpy}
onClick={onClickSpy}
/>)
})

View File

@ -8,10 +8,10 @@ describe('Network Dropdown Icon', () => {
beforeEach(() => {
wrapper = shallow(<NetworkDropdownIcon
backgroundColor = {'red'}
isSelected = {false}
innerBorder = {'none'}
diameter = {'12'}
backgroundColor="red"
isSelected={false}
innerBorder="none"
diameter="12"
/>)
})

View File

@ -21,10 +21,10 @@ describe('AdvancedTabContent Component', function () {
wrapper = shallow(<AdvancedTabContent
updateCustomGasPrice={propsMethodSpies.updateCustomGasPrice}
updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit}
customModalGasPriceInHex={'11'}
customModalGasLimitInHex={'23456'}
timeRemaining={'21500'}
transactionFee={'$0.25'}
customModalGasPriceInHex="11"
customModalGasLimitInHex="23456"
timeRemaining="21500"
transactionFee="$0.25"
insufficientBalance={false}
customPriceIsSafe={true}
isSpeedUp={false}

View File

@ -116,7 +116,7 @@ export default class GasModalPageContainer extends Component {
<span className="gas-modal-content__info-row__send-info__value">{sendAmount}</span>
</div>
<div className="gas-modal-content__info-row__transaction-info">
<span className={'gas-modal-content__info-row__transaction-info__label'}>{this.context.t('transactionFee')}</span>
<span className="gas-modal-content__info-row__transaction-info__label">{this.context.t('transactionFee')}</span>
<span className="gas-modal-content__info-row__transaction-info__value">{transactionFee}</span>
</div>
<div className="gas-modal-content__info-row__total-info">

View File

@ -74,9 +74,9 @@ describe('GasModalPageContainer Component', function () {
customGasLimit={54321}
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
infoRowProps={mockInfoRowProps}
currentTimeEstimate={'1 min 31 sec'}
customGasPriceInHex={'mockCustomGasPriceInHex'}
customGasLimitInHex={'mockCustomGasLimitInHex'}
currentTimeEstimate="1 min 31 sec"
customGasPriceInHex="mockCustomGasPriceInHex"
customGasLimitInHex="mockCustomGasLimitInHex"
insufficientBalance={false}
disableSave={false}
/>)
@ -195,9 +195,9 @@ describe('GasModalPageContainer Component', function () {
customGasLimit={54321}
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
infoRowProps={mockInfoRowProps}
currentTimeEstimate={'1 min 31 sec'}
customGasPriceInHex={'mockCustomGasPriceInHex'}
customGasLimitInHex={'mockCustomGasLimitInHex'}
currentTimeEstimate="1 min 31 sec"
customGasPriceInHex="mockCustomGasPriceInHex"
customGasLimitInHex="mockCustomGasLimitInHex"
insufficientBalance={false}
disableSave={false}
hideBasic={true}

View File

@ -8,7 +8,7 @@
background: rgba(36, 41, 46, 0.9);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
border-radius: 8px;
height: 116px;
min-height: 116px;
padding: 16px;
@media screen and (min-width: 576px) {
@ -29,6 +29,11 @@
justify-content: space-between;
}
&__icon {
height: 16px;
align-self: center;
}
&__text {
font-family: Roboto, 'sans-serif';
font-style: normal;
@ -95,6 +100,7 @@
&__buttons {
display: flex;
width: 100%;
margin-top: 10px;
justify-content: flex-start;
flex-direction: row-reverse;
}

View File

@ -84,4 +84,6 @@
@import 'home-notification/index';
@import 'multiple-notifications/index';
@import 'signature-request/index';

View File

@ -48,7 +48,7 @@ export default class ConfirmRemoveAccount extends Component {
<a
className=""
href={genAccountLink(identity.address, this.props.network)}
target={'_blank'}
target="_blank"
title={this.context.t('etherscanView')}
>
<img src="images/popout.svg" />

View File

@ -120,6 +120,7 @@ ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, address, h
type: 'secondary',
large: true,
className: 'export-private-key__button',
disabled: !this.state.password,
onClick: () => this.exportAccountAndGetPrivateKey(this.state.password, address),
}, this.context.t('confirm'))
)

View File

@ -12,7 +12,7 @@ const LoadingNetworkError = (props, context) => {
submitText={t('tryAgain')}
>
<ModalContent
description={'Oops! Something went wrong.'}
description="Oops! Something went wrong."
/>
</Modal>
)

View File

@ -102,7 +102,7 @@ export default class MetaMetricsOptInModal extends Component {
hideModal()
})
}}
cancelText={'No Thanks'}
cancelText="No Thanks"
hideCancel={false}
onSubmit={() => {
setParticipateInMetaMetrics(true)
@ -118,8 +118,8 @@ export default class MetaMetricsOptInModal extends Component {
hideModal()
})
}}
submitText={'I agree'}
submitButtonType={'confirm'}
submitText="I agree"
submitButtonType="confirm"
disabled={false}
/>
</div>

View File

@ -142,14 +142,14 @@ export default class QrScanner extends Component {
renderVideo () {
return (
<div className={'qr-scanner__content__video-wrapper'}>
<div className="qr-scanner__content__video-wrapper">
<video
id="video"
style={{
display: this.state.ready ? 'block' : 'none',
}}
/>
{ !this.state.ready ? <Spinner color={'#F7C06C'} /> : null}
{ !this.state.ready ? <Spinner color="#F7C06C" /> : null}
</div>
)
}
@ -172,12 +172,12 @@ export default class QrScanner extends Component {
<div className="qr-scanner__close" onClick={this.stopAndClose}></div>
<div className="qr-scanner__image">
<img src={'images/webcam.svg'} width={70} height={70} />
<img src="images/webcam.svg" width={70} height={70} />
</div>
<div className="qr-scanner__title">
{ title }
</div>
<div className={'qr-scanner__error'}>
<div className="qr-scanner__error">
{msg}
</div>
<PageContainerFooter
@ -207,7 +207,7 @@ export default class QrScanner extends Component {
<div className="qr-scanner__content">
{ this.renderVideo() }
</div>
<div className={'qr-scanner__status'}>
<div className="qr-scanner__status">
{this.state.msg}
</div>
</div>

View File

@ -3,6 +3,11 @@ import classnames from 'classnames'
import PropTypes from 'prop-types'
export default class MultipleNotifications extends PureComponent {
static defaultProps = {
children: [],
classNames: [],
}
static propTypes = {
children: PropTypes.array,
classNames: PropTypes.array,
@ -14,7 +19,7 @@ export default class MultipleNotifications extends PureComponent {
render () {
const { showAll } = this.state
const { children, classNames = [] } = this.props
const { children, classNames } = this.props
const childrenToRender = children.filter(child => child)
if (childrenToRender.length === 0) {

View File

@ -34,9 +34,9 @@ export default class Sidebar extends Component {
const { transaction = {} } = sidebarProps
switch (type) {
case WALLET_VIEW_SIDEBAR:
return <WalletView responsiveDisplayClassname={'sidebar-right' } />
return <WalletView responsiveDisplayClassname="sidebar-right" />
case 'customize-gas':
return <div className={'sidebar-left'}><CustomizeGas transaction={transaction} /></div>
return <div className="sidebar-left"><CustomizeGas transaction={transaction} /></div>
default:
return null
}

View File

@ -19,8 +19,8 @@ describe('Sidebar Component', function () {
wrapper = shallow(<Sidebar
sidebarOpen={false}
hideSidebar={propsMethodSpies.hideSidebar}
transitionName={'someTransition'}
type={'wallet-view'}
transitionName="someTransition"
type="wallet-view"
/>)
})

View File

@ -12,9 +12,9 @@ sinon.spy(ButtonGroup.prototype, 'handleButtonClick')
sinon.spy(ButtonGroup.prototype, 'renderButtons')
const mockButtons = [
<button onClick={childButtonSpies.onClick} key={'a'}><div className="mockClass" /></button>,
<button onClick={childButtonSpies.onClick} key={'b'}></button>,
<button onClick={childButtonSpies.onClick} key={'c'}></button>,
<button onClick={childButtonSpies.onClick} key="a"><div className="mockClass" /></button>,
<button onClick={childButtonSpies.onClick} key="b"></button>,
<button onClick={childButtonSpies.onClick} key="c"></button>,
]
describe('ButtonGroup Component', function () {

View File

@ -12,12 +12,12 @@ describe('Page Footer', () => {
beforeEach(() => {
wrapper = shallow(<PageFooter
onCancel = {onCancel}
onSubmit = {onSubmit}
cancelText = {'Cancel'}
submitText = {'Submit'}
disabled = {false}
submitButtonType = {'Test Type'}
onCancel={onCancel}
onSubmit={onSubmit}
cancelText="Cancel"
submitText="Submit"
disabled={false}
submitButtonType="Test Type"
/>)
})

View File

@ -13,13 +13,13 @@ describe('Page Container Header', () => {
onClose = sinon.spy()
wrapper = shallow(<PageContainerHeader
showBackButton = {true}
onBackButtonClick = {onBackButtonClick}
backButtonStyles = {style}
title = {'Test Title'}
subtitle = {'Test Subtitle'}
tabs = {'Test Tab'}
onClose = {onClose}
showBackButton={true}
onBackButtonClick={onBackButtonClick}
backButtonStyles={style}
title="Test Title"
subtitle="Test Subtitle"
tabs="Test Tab"
onClose={onClose}
/>)
})

View File

@ -7,7 +7,6 @@ export default class Tooltip extends PureComponent {
arrow: true,
children: null,
containerClassName: '',
hideOnClick: false,
html: null,
onHidden: null,
position: 'left',

View File

@ -56,7 +56,7 @@ export default class ConfirmDeployContract extends Component {
render () {
return (
<ConfirmTransactionBase
actionKey={'contractDeployment'}
actionKey="contractDeployment"
dataComponent={this.renderData()}
/>
)

View File

@ -30,7 +30,7 @@ export default class ConfirmSendEther extends Component {
return (
<ConfirmTransactionBase
actionKey={'confirm'}
actionKey="confirm"
hideData={hideData}
onEdit={confirmTransactionData => this.handleEdit(confirmTransactionData)}
/>

View File

@ -104,7 +104,7 @@ export default class MetaMetricsOptIn extends Component {
})
})
}}
cancelText={'No Thanks'}
cancelText="No Thanks"
hideCancel={false}
onSubmit={() => {
setParticipateInMetaMetrics(true)
@ -137,8 +137,8 @@ export default class MetaMetricsOptIn extends Component {
})
})
}}
submitText={'I agree'}
submitButtonType={'primary'}
submitText="I agree"
submitButtonType="primary"
disabled={false}
/>
<div className="metametrics-opt-in__bottom-text">

View File

@ -25,7 +25,6 @@ class DraggableSeed extends Component {
static defaultProps = {
className: '',
onClick () {},
}
componentWillReceiveProps (nextProps) {

View File

@ -4,6 +4,7 @@ import Media from 'react-media'
import { Redirect } from 'react-router-dom'
import { formatDate } from '../../helpers/utils/util'
import HomeNotification from '../../components/app/home-notification'
import DaiMigrationNotification from '../../components/app/dai-migration-component'
import MultipleNotifications from '../../components/app/multiple-notifications'
import WalletView from '../../components/app/wallet-view'
import TransactionView from '../../components/app/transaction-view'
@ -23,6 +24,7 @@ export default class Home extends PureComponent {
static defaultProps = {
unsetMigratedPrivacyMode: null,
hasDaiV1Token: false,
}
static propTypes = {
@ -43,6 +45,7 @@ export default class Home extends PureComponent {
restoreFromThreeBox: PropTypes.func,
setShowRestorePromptToFalse: PropTypes.func,
threeBoxLastUpdated: PropTypes.number,
hasDaiV1Token: PropTypes.bool,
}
componentWillMount () {
@ -86,6 +89,7 @@ export default class Home extends PureComponent {
forgottenPassword,
providerRequests,
history,
hasDaiV1Token,
showPrivacyModeNotification,
unsetMigratedPrivacyMode,
shouldShowSeedPhraseReminder,
@ -117,9 +121,7 @@ export default class Home extends PureComponent {
{ !history.location.pathname.match(/^\/confirm-transaction/)
? (
<TransactionView>
<MultipleNotifications
className
>
<MultipleNotifications>
{
showPrivacyModeNotification
? <HomeNotification
@ -174,6 +176,11 @@ export default class Home extends PureComponent {
/>
: null
}
{
hasDaiV1Token
? <DaiMigrationNotification />
: null
}
</MultipleNotifications>
</TransactionView>
)

View File

@ -3,7 +3,7 @@ import { compose } from 'recompose'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
import { getCurrentEthBalance } from '../../selectors/selectors'
import { getCurrentEthBalance, getDaiV1Token } from '../../selectors/selectors'
import {
unsetMigratedPrivacyMode,
restoreFromThreeBox,
@ -44,6 +44,7 @@ const mapStateToProps = state => {
showRestorePrompt,
selectedAddress,
threeBoxLastUpdated,
hasDaiV1Token: Boolean(getDaiV1Token(state)),
}
}

View File

@ -25,10 +25,10 @@ describe('AccountListItem Component', function () {
beforeEach(() => {
wrapper = shallow(<AccountListItem
account={ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' } }
className={'mockClassName'}
className="mockClassName"
conversionRate={4}
currentCurrency={'mockCurrentyCurrency'}
nativeCurrency={'ETH'}
currentCurrency="mockCurrentyCurrency"
nativeCurrency="ETH"
displayAddress={false}
displayBalance={false}
handleClick={propsMethodSpies.handleClick}

View File

@ -23,9 +23,9 @@ describe('AddRecipient Component', function () {
closeToDropdown={propsMethodSpies.closeToDropdown}
inError={false}
inWarning={false}
network={'mockNetwork'}
network="mockNetwork"
openToDropdown={propsMethodSpies.openToDropdown}
to={'mockTo'}
to="mockTo"
toAccounts={['mockAccount']}
toDropdownOpen={false}
updateGas={propsMethodSpies.updateGas}

View File

@ -64,7 +64,7 @@ export default class AmountMaxButton extends Component {
const { maxModeOn, buttonDataLoading, inError } = this.props
return (
<div className={'send-v2__amount-max'} onClick={buttonDataLoading || inError ? null : this.onMaxClick}>
<div className="send-v2__amount-max" onClick={buttonDataLoading || inError ? null : this.onMaxClick}>
<input type="checkbox" checked={maxModeOn} />
<div className={classnames('send-v2__amount-max__button', { 'send-v2__amount-max__button__disabled': buttonDataLoading || inError })}>
{this.context.t('max')}

View File

@ -19,13 +19,13 @@ describe('AmountMaxButton Component', function () {
beforeEach(() => {
wrapper = shallow(<AmountMaxButton
balance={'mockBalance'}
gasTotal={'mockGasTotal'}
balance="mockBalance"
gasTotal="mockGasTotal"
maxModeOn={false}
selectedToken={ { address: 'mockTokenAddress' } }
setAmountToMax={propsMethodSpies.setAmountToMax}
setMaxModeTo={propsMethodSpies.setMaxModeTo}
tokenBalance={'mockTokenBalance'}
tokenBalance="mockTokenBalance"
/>, {
context: {
t: str => str + '_t',

View File

@ -108,7 +108,7 @@ export default class SendAmountRow extends Component {
<SendRowWrapper
label={`${this.context.t('amount')}:`}
showError={inError}
errorType={'amount'}
errorType="amount"
>
{gasTotal && <AmountMaxButton inError={inError} />}
{ this.renderInput() }

View File

@ -26,17 +26,17 @@ describe('SendAmountRow Component', function () {
beforeEach(() => {
wrapper = shallow(<SendAmountRow
amount={'mockAmount'}
amountConversionRate={'mockAmountConversionRate'}
balance={'mockBalance'}
amount="mockAmount"
amountConversionRate="mockAmountConversionRate"
balance="mockBalance"
conversionRate={7}
convertedCurrency={'mockConvertedCurrency'}
gasTotal={'mockGasTotal'}
convertedCurrency="mockConvertedCurrency"
gasTotal="mockGasTotal"
inError={false}
primaryCurrency={'mockPrimaryCurrency'}
primaryCurrency="mockPrimaryCurrency"
selectedToken={ { address: 'mockTokenAddress' } }
setMaxModeTo={propsMethodSpies.setMaxModeTo}
tokenBalance={'mockTokenBalance'}
tokenBalance="mockTokenBalance"
updateGasFeeError={propsMethodSpies.updateGasFeeError}
updateSendAmount={propsMethodSpies.updateSendAmount}
updateSendAmountError={propsMethodSpies.updateSendAmountError}

View File

@ -17,7 +17,7 @@ export default class SendDropdownList extends Component {
getListItemIcon (accountAddress, activeAddress) {
return accountAddress === activeAddress
? <i className={`fa fa-check fa-lg`} style={ { color: '#02c9b1' } }/>
? <i className="fa fa-check fa-lg" style={ { color: '#02c9b1' } }/>
: null
}

View File

@ -25,7 +25,7 @@ describe('SendDropdownList Component', function () {
]}
closeDropdown={propsMethodSpies.closeDropdown}
onSelect={propsMethodSpies.onSelect}
activeAddress={'mockAddress2'}
activeAddress="mockAddress2"
/>, { context: { t: str => str + '_t' } })
})
@ -39,7 +39,7 @@ describe('SendDropdownList Component', function () {
it('should return check icon if the passed addresses are the same', () => {
assert.deepEqual(
wrapper.instance().getListItemIcon('mockAccount0', 'mockAccount0'),
<i className={`fa fa-check fa-lg`} style={ { color: '#02c9b1' } }/>
<i className="fa fa-check fa-lg" style={ { color: '#02c9b1' } }/>
)
})

View File

@ -17,9 +17,9 @@ describe('GasFeeDisplay Component', function () {
beforeEach(() => {
wrapper = shallow(<GasFeeDisplay
conversionRate={20}
gasTotal={'mockGasTotal'}
primaryCurrency={'mockPrimaryCurrency'}
convertedCurrency={'mockConvertedCurrency'}
gasTotal="mockGasTotal"
primaryCurrency="mockPrimaryCurrency"
convertedCurrency="mockConvertedCurrency"
showGasButtonGroup={propsMethodSpies.showCustomizeGasModal}
onReset={propsMethodSpies.onReset}
/>, {context: {t: str => str + '_t'}})

View File

@ -152,7 +152,7 @@ export default class SendGasRow extends Component {
<SendRowWrapper
label={`${this.context.t('transactionFee')}:`}
showError={gasFeeError}
errorType={'gasFee'}
errorType="gasFee"
>
{ this.renderContent() }
</SendRowWrapper>

View File

@ -19,10 +19,10 @@ describe('SendGasRow Component', function () {
beforeEach(() => {
wrapper = shallow(<SendGasRow
conversionRate={20}
convertedCurrency={'mockConvertedCurrency'}
gasFeeError={'mockGasFeeError'}
convertedCurrency="mockConvertedCurrency"
gasFeeError="mockGasFeeError"
gasLoadingError={false}
gasTotal={'mockGasTotal'}
gasTotal="mockGasTotal"
gasButtonGroupShown={false}
showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal}
resetGasButtons={propsMethodSpies.resetGasButtons}

View File

@ -29,7 +29,7 @@ export default class SendHexDataRow extends Component {
<SendRowWrapper
label={`${t('hexData')}:`}
showError={inError}
errorType={'amount'}
errorType="amount"
>
<textarea
onInput={this.onInput}

View File

@ -9,7 +9,7 @@ describe('SendRowErrorMessage Component', function () {
beforeEach(() => {
wrapper = shallow(<SendRowErrorMessage
errors={{ error1: 'abc', error2: 'def' }}
errorType={'error3'}
errorType="error3"
/>, { context: { t: str => str + '_t' } })
})

View File

@ -10,8 +10,8 @@ describe('SendContent Component', function () {
beforeEach(() => {
wrapper = shallow(<SendRowWrapper
errorType={'mockErrorType'}
label={'mockLabel'}
errorType="mockErrorType"
label="mockLabel"
showError={false}
>
<span>Mock Form Field</span>
@ -54,8 +54,8 @@ describe('SendContent Component', function () {
it('should render its second child as a child of the send-v2__form-field, if it has two children', () => {
wrapper = shallow(<SendRowWrapper
errorType={'mockErrorType'}
label={'mockLabel'}
errorType="mockErrorType"
label="mockLabel"
showError={false}
>
<span>Mock Custom Label Content</span>
@ -66,8 +66,8 @@ describe('SendContent Component', function () {
it('should render its first child as the last child of the send-v2__form-label, if it has two children', () => {
wrapper = shallow(<SendRowWrapper
errorType={'mockErrorType'}
label={'mockLabel'}
errorType="mockErrorType"
label="mockLabel"
showError={false}
>
<span>Mock Custom Label Content</span>

View File

@ -27,22 +27,22 @@ describe('SendFooter Component', function () {
beforeEach(() => {
wrapper = shallow(<SendFooter
addToAddressBookIfNew={propsMethodSpies.addToAddressBookIfNew}
amount={'mockAmount'}
amount="mockAmount"
clearSend={propsMethodSpies.clearSend}
disabled={true}
editingTransactionId={'mockEditingTransactionId'}
editingTransactionId="mockEditingTransactionId"
errors={{}}
from={ { address: 'mockAddress', balance: 'mockBalance' } }
gasLimit={'mockGasLimit'}
gasPrice={'mockGasPrice'}
gasTotal={'mockGasTotal'}
gasLimit="mockGasLimit"
gasPrice="mockGasPrice"
gasTotal="mockGasTotal"
history={historySpies}
inError={false}
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
sign={propsMethodSpies.sign}
to={'mockTo'}
to="mockTo"
toAccounts={['mockAccount']}
tokenBalance={'mockTokenBalance'}
tokenBalance="mockTokenBalance"
unapprovedTxs={['mockTx']}
update={propsMethodSpies.update}
sendErrors={{}}
@ -184,22 +184,22 @@ describe('SendFooter Component', function () {
sinon.stub(SendFooter.prototype, 'formShouldBeDisabled').returns('formShouldBeDisabledReturn')
wrapper = shallow(<SendFooter
addToAddressBookIfNew={propsMethodSpies.addToAddressBookIfNew}
amount={'mockAmount'}
amount="mockAmount"
clearSend={propsMethodSpies.clearSend}
disabled={true}
editingTransactionId={'mockEditingTransactionId'}
editingTransactionId="mockEditingTransactionId"
errors={{}}
from={ { address: 'mockAddress', balance: 'mockBalance' } }
gasLimit={'mockGasLimit'}
gasPrice={'mockGasPrice'}
gasTotal={'mockGasTotal'}
gasLimit="mockGasLimit"
gasPrice="mockGasPrice"
gasTotal="mockGasTotal"
history={historySpies}
inError={false}
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
sign={propsMethodSpies.sign}
to={'mockTo'}
to="mockTo"
toAccounts={['mockAccount']}
tokenBalance={'mockTokenBalance'}
tokenBalance="mockTokenBalance"
unapprovedTxs={['mockTx']}
update={propsMethodSpies.update}
/>, { context: { t: str => str, metricsEvent: () => ({}) } })

View File

@ -23,7 +23,7 @@ describe('SendHeader Component', function () {
wrapper = shallow(<SendHeader
clearSend={propsMethodSpies.clearSend}
history={historySpies}
titleKey={'mockTitleKey'}
titleKey="mockTitleKey"
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
})

View File

@ -41,26 +41,26 @@ describe('Send Component', function () {
beforeEach(() => {
wrapper = shallow(<SendTransactionScreen
amount={'mockAmount'}
amountConversionRate={'mockAmountConversionRate'}
blockGasLimit={'mockBlockGasLimit'}
amount="mockAmount"
amountConversionRate="mockAmountConversionRate"
blockGasLimit="mockBlockGasLimit"
conversionRate={10}
editingTransactionId={'mockEditingTransactionId'}
editingTransactionId="mockEditingTransactionId"
fetchBasicGasEstimates={propsMethodSpies.fetchBasicGasEstimates}
fetchGasEstimates={propsMethodSpies.fetchGasEstimates}
from={ { address: 'mockAddress', balance: 'mockBalance' } }
gasLimit={'mockGasLimit'}
gasPrice={'mockGasPrice'}
gasTotal={'mockGasTotal'}
gasLimit="mockGasLimit"
gasPrice="mockGasPrice"
gasTotal="mockGasTotal"
history={{ mockProp: 'history-abc'}}
network={'3'}
primaryCurrency={'mockPrimaryCurrency'}
network="3"
primaryCurrency="mockPrimaryCurrency"
recentBlocks={['mockBlock']}
selectedAddress={'mockSelectedAddress'}
selectedToken={'mockSelectedToken'}
selectedAddress="mockSelectedAddress"
selectedToken="mockSelectedToken"
showHexData={true}
tokenBalance={'mockTokenBalance'}
tokenContract={'mockTokenContract'}
tokenBalance="mockTokenBalance"
tokenContract="mockTokenContract"
updateAndSetGasLimit={propsMethodSpies.updateAndSetGasLimit}
updateSendErrors={propsMethodSpies.updateSendErrors}
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}

View File

@ -26,7 +26,7 @@ export default class ToAutoComplete extends Component {
getListItemIcon (listItemAddress, toAddress) {
return toAddress && listItemAddress === toAddress
? <i className={'fa fa-check fa-lg'}
? <i className="fa fa-check fa-lg"
style={{
color: '#02c9b1',
}}
@ -48,13 +48,13 @@ export default class ToAutoComplete extends Component {
return (
<div>
<div className={'send-v2__from-dropdown__close-area'} onClick={closeDropdown} />
<div className={'send-v2__from-dropdown__list'}>
<div className="send-v2__from-dropdown__close-area" onClick={closeDropdown} />
<div className="send-v2__from-dropdown__list">
{accountsToRender.map((account, i) => (
<AccountListItem
key={i}
account={account}
className={'account-list-item__dropdown'}
className="account-list-item__dropdown"
handleClick={() => {
onChange(account.address)
closeDropdown()
@ -106,7 +106,7 @@ export default class ToAutoComplete extends Component {
} = this.props
return (
<div className={'send-v2__to-autocomplete'}>
<div className="send-v2__to-autocomplete">
<input
className={classnames('send-v2__to-autocomplete__input', {
'send-v2__error-border': inError,
@ -122,7 +122,7 @@ export default class ToAutoComplete extends Component {
{
to
? null
: <i className={'fa fa-caret-down fa-lg send-v2__to-autocomplete__down-caret'}
: <i className="fa fa-caret-down fa-lg send-v2__to-autocomplete__down-caret"
onClick={() => this.handleInputEvent()}
style={{
style: {color: '#dedede'},

View File

@ -123,7 +123,7 @@ export default class AddContact extends PureComponent {
history.push(CONTACT_LIST_ROUTE)
}}
submitText={this.context.t('save')}
submitButtonType={'confirm'}
submitButtonType="confirm"
/>
</div>
)

View File

@ -133,7 +133,7 @@ export default class EditContact extends PureComponent {
history.push(`${viewRoute}/${address}`)
}}
submitText={this.context.t('save')}
submitButtonType={'confirm'}
submitButtonType="confirm"
/>
</div>
)

View File

@ -49,6 +49,7 @@ const selectors = {
getAccountType,
getNumberOfAccounts,
getNumberOfTokens,
getDaiV1Token,
isEthereumNetwork,
getMetaMetricState,
getRpcPrefsForCurrentProvider,
@ -225,6 +226,12 @@ function getAddressBookEntryName (state, address) {
return entry && entry.name !== '' ? entry.name : addressSlicer(address)
}
function getDaiV1Token (state) {
const OLD_DAI_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
const tokens = state.metamask.tokens || []
return tokens.find(({address}) => checksumAddress(address) === OLD_DAI_CONTRACT_ADDRESS)
}
function accountsWithSendEtherInfoSelector (state) {
const accounts = getMetaMaskAccounts(state)
const { identities } = state.metamask

View File

@ -10038,10 +10038,10 @@ eth-block-tracker@^4.4.2:
pify "^3.0.0"
safe-event-emitter "^1.0.1"
eth-contract-metadata@1.9.3, eth-contract-metadata@^1.9.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2"
integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw==
eth-contract-metadata@^1.11.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.11.0.tgz#4d23a8208d5d53be9d4c0696ed8492b505c6bca1"
integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA==
eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8:
version "2.0.8"
@ -12160,13 +12160,13 @@ fuse.js@^3.4.4:
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.5.tgz#8954fb43f9729bd5dbcb8c08f251db552595a7a6"
integrity sha512-s9PGTaQIkT69HaeoTVjwGsLfb8V8ScJLx5XGFcKHg0MqLUH/UZ4EKOtqtXX9k7AFqCGxD1aJmYb8Q5VYDibVRQ==
gaba@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/gaba/-/gaba-1.8.0.tgz#5370e5d662de6aa8e4e41de791da0996a7e12dbe"
integrity sha512-M20fZ6yKRefxgxb82l5Of0VutFxvc1Uxg8LSncaiq5kWQZO1UNe5pkxQc4EQT9rGAcBm6ASv7FG0B04syIELRA==
gaba@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/gaba/-/gaba-1.9.0.tgz#ccd9f99c56687b5acd39f9e3ceb435b2a59b6aa1"
integrity sha512-HoVreAdZssL0jNHuzZ7WP+YKZ0riu44jVDWxhQ9hsgPuzxbVEsz9fO/HDxqAdNZS1Cswayq6+ciZ3HSCFWMKbQ==
dependencies:
await-semaphore "^0.1.3"
eth-contract-metadata "^1.9.1"
eth-contract-metadata "^1.11.0"
eth-ens-namehash "^2.0.8"
eth-json-rpc-infura "^4.0.1"
eth-keyring-controller "^5.3.0"