aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/lib/is-popup-or-notification.js3
-rw-r--r--mascara/src/app/first-time/confirm-seed-screen.js133
-rw-r--r--mascara/src/app/first-time/create-password-screen.js61
-rw-r--r--mascara/src/app/first-time/index.js2
-rw-r--r--mascara/src/app/first-time/notice-screen.js87
-rw-r--r--mascara/src/app/first-time/seed-screen.js (renamed from mascara/src/app/first-time/backup-phrase-screen.js)168
-rw-r--r--package.json2
-rw-r--r--ui/app/account-detail.js4
-rw-r--r--ui/app/accounts/new-account/index.js81
-rw-r--r--ui/app/actions.js216
-rw-r--r--ui/app/app.js1042
-rw-r--r--ui/app/components/account-menu/index.js51
-rw-r--r--ui/app/components/notice.js132
-rw-r--r--ui/app/components/pages/add-token.js (renamed from ui/app/add-token.js)19
-rw-r--r--ui/app/components/pages/authenticated.js34
-rw-r--r--ui/app/components/pages/create-account/import-account/index.js (renamed from ui/app/accounts/import/index.js)0
-rw-r--r--ui/app/components/pages/create-account/import-account/json.js (renamed from ui/app/accounts/import/json.js)14
-rw-r--r--ui/app/components/pages/create-account/import-account/private-key.js (renamed from ui/app/accounts/import/private-key.js)23
-rw-r--r--ui/app/components/pages/create-account/import-account/seed.js (renamed from ui/app/accounts/import/seed.js)0
-rw-r--r--ui/app/components/pages/create-account/index.js81
-rw-r--r--ui/app/components/pages/create-account/new-account.js (renamed from ui/app/accounts/new-account/create-form.js)30
-rw-r--r--ui/app/components/pages/initialized.js25
-rw-r--r--ui/app/components/pages/keychains/restore-vault.js170
-rw-r--r--ui/app/components/pages/keychains/reveal-seed.js195
-rw-r--r--ui/app/components/pages/metamask-route.js28
-rw-r--r--ui/app/components/pages/notice.js203
-rw-r--r--ui/app/components/pages/settings/index.js59
-rw-r--r--ui/app/components/pages/settings/info.js107
-rw-r--r--ui/app/components/pages/settings/settings.js (renamed from ui/app/settings.js)161
-rw-r--r--ui/app/components/pages/signature-request.js321
-rw-r--r--ui/app/components/pages/unlock.js175
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js21
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js15
-rw-r--r--ui/app/components/send/send-v2-container.js8
-rw-r--r--ui/app/components/signature-request.js253
-rw-r--r--ui/app/components/tab-bar.js26
-rw-r--r--ui/app/components/tx-list.js12
-rw-r--r--ui/app/components/tx-view.js14
-rw-r--r--ui/app/components/wallet-view.js15
-rw-r--r--ui/app/conf-tx.js63
-rw-r--r--ui/app/css/index.scss6
-rw-r--r--ui/app/css/itcss/components/index.scss2
-rw-r--r--ui/app/css/itcss/components/new-account.scss5
-rw-r--r--ui/app/css/itcss/components/pages/index.scss1
-rw-r--r--ui/app/css/itcss/components/pages/unlock.scss9
-rw-r--r--ui/app/css/itcss/components/sections.scss6
-rw-r--r--ui/app/first-time/init-menu.js293
-rw-r--r--ui/app/info.js200
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js91
-rw-r--r--ui/app/keychains/hd/recover-seed/confirmation.js121
-rw-r--r--ui/app/main-container.js4
-rw-r--r--ui/app/root.js33
-rw-r--r--ui/app/routes.js33
-rw-r--r--ui/app/select-app.js10
-rw-r--r--ui/app/send-v2.js10
-rw-r--r--yarn.lock893
56 files changed, 3484 insertions, 2287 deletions
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
index e2999411f..ad3e825c0 100644
--- a/app/scripts/lib/is-popup-or-notification.js
+++ b/app/scripts/lib/is-popup-or-notification.js
@@ -3,7 +3,8 @@ module.exports = function isPopupOrNotification () {
// if (url.match(/popup.html$/) || url.match(/home.html$/)) {
// Below regexes needed for feature toggles (e.g. see line ~340 in ui/app/app.js)
// Revert below regexes to above commented out regexes before merge to master
- if (url.match(/popup.html(?:\?.+)*$/) || url.match(/home.html(?:\?.+)*$/)) {
+ if (url.match(/popup.html(?:\?.+)*$/) ||
+ url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
return 'popup'
} else {
return 'notification'
diff --git a/mascara/src/app/first-time/confirm-seed-screen.js b/mascara/src/app/first-time/confirm-seed-screen.js
new file mode 100644
index 000000000..c9382689e
--- /dev/null
+++ b/mascara/src/app/first-time/confirm-seed-screen.js
@@ -0,0 +1,133 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import classnames from 'classnames'
+import shuffle from 'lodash.shuffle'
+import { compose, onlyUpdateForPropTypes } from 'recompose'
+import Identicon from '../../../../ui/app/components/identicon'
+import { confirmSeedWords } from '../../../../ui/app/actions'
+import Breadcrumbs from './breadcrumbs'
+import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
+
+class ConfirmSeedScreen extends Component {
+ static propTypes = {
+ isLoading: PropTypes.bool,
+ address: PropTypes.string,
+ seedWords: PropTypes.string,
+ confirmSeedWords: PropTypes.func,
+ history: PropTypes.object,
+ };
+
+ static defaultProps = {
+ seedWords: '',
+ }
+
+ constructor (props) {
+ super(props)
+ const { seedWords } = props
+ this.state = {
+ selectedSeeds: [],
+ shuffledSeeds: seedWords && shuffle(seedWords.split(' ')) || [],
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ render () {
+ const { seedWords, confirmSeedWords, history } = this.props
+ const { selectedSeeds, shuffledSeeds } = this.state
+ const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
+
+ return (
+ <div className="first-time-flow">
+ {
+ this.props.isLoading
+ ? <LoadingScreen loadingMessage="Creating your new account" />
+ : (
+ <div className="backup-phrase">
+ <Identicon address={this.props.address} diameter={70} />
+ <div className="backup-phrase__content-wrapper">
+ <div>
+ <div className="backup-phrase__title">
+ Confirm your Secret Backup Phrase
+ </div>
+ <div className="backup-phrase__body-text">
+ Please select each phrase in order to make sure it is correct.
+ </div>
+ <div className="backup-phrase__confirm-secret">
+ {selectedSeeds.map(([_, word], i) => (
+ <button
+ key={i}
+ className="backup-phrase__confirm-seed-option"
+ >
+ {word}
+ </button>
+ ))}
+ </div>
+ <div className="backup-phrase__confirm-seed-options">
+ {shuffledSeeds.map((word, i) => {
+ const isSelected = selectedSeeds
+ .filter(([index, seed]) => seed === word && index === i)
+ .length
+
+ return (
+ <button
+ key={i}
+ className={classnames('backup-phrase__confirm-seed-option', {
+ 'backup-phrase__confirm-seed-option--selected': isSelected,
+ })}
+ onClick={() => {
+ if (!isSelected) {
+ this.setState({
+ selectedSeeds: [...selectedSeeds, [i, word]],
+ })
+ } else {
+ this.setState({
+ selectedSeeds: selectedSeeds
+ .filter(([index, seed]) => !(seed === word && index === i)),
+ })
+ }
+ }}
+ >
+ {word}
+ </button>
+ )
+ })}
+ </div>
+ <button
+ className="first-time-flow__button"
+ onClick={() => isValid && confirmSeedWords().then(() => history.push(DEFAULT_ROUTE))}
+ disabled={!isValid}
+ >
+ Confirm
+ </button>
+ </div>
+ </div>
+ <Breadcrumbs total={3} currentIndex={1} />
+ </div>
+ )
+ }
+ </div>
+ )
+ }
+}
+
+export default compose(
+ onlyUpdateForPropTypes,
+ connect(
+ ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
+ seedWords,
+ isLoading,
+ address: selectedAddress,
+ }),
+ dispatch => ({
+ confirmSeedWords: () => dispatch(confirmSeedWords()),
+ })
+ )
+)(ConfirmSeedScreen)
diff --git a/mascara/src/app/first-time/create-password-screen.js b/mascara/src/app/first-time/create-password-screen.js
index 0b36c6815..c490d8831 100644
--- a/mascara/src/app/first-time/create-password-screen.js
+++ b/mascara/src/app/first-time/create-password-screen.js
@@ -1,23 +1,25 @@
-import EventEmitter from 'events'
-import React, {Component, PropTypes} from 'react'
-import {connect} from 'react-redux';
-import {createNewVaultAndKeychain} from '../../../../ui/app/actions'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
+import { createNewVaultAndKeychain } from '../../../../ui/app/actions'
import LoadingScreen from './loading-screen'
import Breadcrumbs from './breadcrumbs'
+import { DEFAULT_ROUTE, IMPORT_ACCOUNT_ROUTE } from '../../../../ui/app/routes'
+import EventEmitter from 'events'
import Mascot from '../../../../ui/app/components/mascot'
class CreatePasswordScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
createAccount: PropTypes.func.isRequired,
- goToImportWithSeedPhrase: PropTypes.func.isRequired,
- goToImportAccount: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired
+ history: PropTypes.object.isRequired,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
}
state = {
password: '',
- confirmPassword: ''
+ confirmPassword: '',
}
constructor () {
@@ -25,34 +27,41 @@ class CreatePasswordScreen extends Component {
this.animationEventEmitter = new EventEmitter()
}
- isValid() {
- const {password, confirmPassword} = this.state;
+ componentWillMount () {
+ const { isInitialized, isUnlocked, history } = this.props
+ if (isInitialized || isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ isValid () {
+ const { password, confirmPassword } = this.state
if (!password || !confirmPassword) {
- return false;
+ return false
}
if (password.length < 8) {
- return false;
+ return false
}
- return password === confirmPassword;
+ return password === confirmPassword
}
createAccount = () => {
if (!this.isValid()) {
- return;
+ return
}
- const {password} = this.state;
- const {createAccount, next} = this.props;
+ const { password } = this.state
+ const { createAccount, history } = this.props
createAccount(password)
- .then(next);
+ .then(() => history.push(DEFAULT_ROUTE))
}
- render() {
- const { isLoading, goToImportAccount, goToImportWithSeedPhrase } = this.props
+ render () {
+ const { isLoading } = this.props
return isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
@@ -101,7 +110,7 @@ class CreatePasswordScreen extends Component {
className="first-time-flow__link create-password__import-link"
onClick={e => {
e.preventDefault()
- goToImportWithSeedPhrase()
+ history.push(IMPORT_ACCOUNT_ROUTE)
}}
>
Import with seed phrase
@@ -126,8 +135,18 @@ class CreatePasswordScreen extends Component {
}
}
+const mapStateToProps = state => {
+ const { metamask: { isInitialized, isUnlocked }, appState: { isLoading } } = state
+
+ return {
+ isLoading,
+ isInitialized,
+ isUnlocked,
+ }
+}
+
export default connect(
- ({ appState: { isLoading } }) => ({ isLoading }),
+ mapStateToProps,
dispatch => ({
createAccount: password => dispatch(createNewVaultAndKeychain(password)),
})
diff --git a/mascara/src/app/first-time/index.js b/mascara/src/app/first-time/index.js
index 66b591bd8..eec830ad2 100644
--- a/mascara/src/app/first-time/index.js
+++ b/mascara/src/app/first-time/index.js
@@ -3,7 +3,7 @@ import {connect} from 'react-redux'
import CreatePasswordScreen from './create-password-screen'
import UniqueImageScreen from './unique-image-screen'
import NoticeScreen from './notice-screen'
-import BackupPhraseScreen from './backup-phrase-screen'
+import BackupPhraseScreen from './seed-screen'
import ImportAccountScreen from './import-account-screen'
import ImportSeedPhraseScreen from './import-seed-phrase-screen'
import {onboardingBuyEthView} from '../../../../ui/app/actions'
diff --git a/mascara/src/app/first-time/notice-screen.js b/mascara/src/app/first-time/notice-screen.js
index d09070a95..be54b9fc0 100644
--- a/mascara/src/app/first-time/notice-screen.js
+++ b/mascara/src/app/first-time/notice-screen.js
@@ -1,10 +1,12 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import Markdown from 'react-markdown'
-import {connect} from 'react-redux'
+import { connect } from 'react-redux'
import debounce from 'lodash.debounce'
-import {markNoticeRead} from '../../../../ui/app/actions'
+import { markNoticeRead } from '../../../../ui/app/actions'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
class NoticeScreen extends Component {
static propTypes = {
@@ -12,70 +14,77 @@ class NoticeScreen extends Component {
lastUnreadNotice: PropTypes.shape({
title: PropTypes.string,
date: PropTypes.string,
- body: PropTypes.string
+ body: PropTypes.string,
}),
- next: PropTypes.func.isRequired
+ location: PropTypes.shape({
+ state: PropTypes.shape({
+ next: PropTypes.func.isRequired,
+ }),
+ }),
+ markNoticeRead: PropTypes.func,
+ history: PropTypes.object,
};
static defaultProps = {
- lastUnreadNotice: {}
+ lastUnreadNotice: {},
};
state = {
atBottom: false,
}
- componentDidMount() {
+ componentDidMount () {
this.onScroll()
}
acceptTerms = () => {
- const { markNoticeRead, lastUnreadNotice, next } = this.props;
- const defer = markNoticeRead(lastUnreadNotice)
- .then(() => this.setState({ atBottom: false }))
-
- if ((/terms/gi).test(lastUnreadNotice.title)) {
- defer.then(next)
- }
+ const { markNoticeRead, lastUnreadNotice, history } = this.props
+ markNoticeRead(lastUnreadNotice)
+ .then(() => {
+ history.push(DEFAULT_ROUTE)
+ this.setState({ atBottom: false })
+ })
}
onScroll = debounce(() => {
if (this.state.atBottom) return
const target = document.querySelector('.tou__body')
- const {scrollTop, offsetHeight, scrollHeight} = target;
- const atBottom = scrollTop + offsetHeight >= scrollHeight;
+ const {scrollTop, offsetHeight, scrollHeight} = target
+ const atBottom = scrollTop + offsetHeight >= scrollHeight
this.setState({atBottom: atBottom})
}, 25)
- render() {
+ render () {
const {
address,
- lastUnreadNotice: { title, body }
- } = this.props;
+ lastUnreadNotice: { title, body },
+ } = this.props
const { atBottom } = this.state
return (
- <div
- className="tou"
- onScroll={this.onScroll}
- >
- <Identicon address={address} diameter={70} />
- <div className="tou__title">{title}</div>
- <Markdown
- className="tou__body markdown"
- source={body}
- skipHtml
- />
- <button
- className="first-time-flow__button"
- onClick={atBottom && this.acceptTerms}
- disabled={!atBottom}
+ <div className="first-time-flow">
+ <div
+ className="tou"
+ onScroll={this.onScroll}
>
- Accept
- </button>
- <Breadcrumbs total={3} currentIndex={2} />
+ <Identicon address={address} diameter={70} />
+ <div className="tou__title">{title}</div>
+ <Markdown
+ className="tou__body markdown"
+ source={body}
+ skipHtml
+ />
+ <button
+ className="first-time-flow__button"
+ onClick={atBottom && this.acceptTerms}
+ disabled={!atBottom}
+ >
+ Accept
+ </button>
+ <Breadcrumbs total={3} currentIndex={2} />
+ </div>
</div>
)
}
@@ -84,9 +93,9 @@ class NoticeScreen extends Component {
export default connect(
({ metamask: { selectedAddress, lastUnreadNotice } }) => ({
lastUnreadNotice,
- address: selectedAddress
+ address: selectedAddress,
}),
dispatch => ({
- markNoticeRead: notice => dispatch(markNoticeRead(notice))
+ markNoticeRead: notice => dispatch(markNoticeRead(notice)),
})
)(NoticeScreen)
diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/seed-screen.js
index c68dacea2..dc1da851c 100644
--- a/mascara/src/app/first-time/backup-phrase-screen.js
+++ b/mascara/src/app/first-time/seed-screen.js
@@ -1,12 +1,12 @@
-import React, {Component, PropTypes} from 'react'
-import {connect} from 'react-redux';
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
import classnames from 'classnames'
-import shuffle from 'lodash.shuffle'
-import {compose, onlyUpdateForPropTypes} from 'recompose'
+import { compose, onlyUpdateForPropTypes } from 'recompose'
import Identicon from '../../../../ui/app/components/identicon'
-import {confirmSeedWords} from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE, CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes'
const LockIcon = props => (
<svg
@@ -35,34 +35,31 @@ const LockIcon = props => (
/>
</g>
</svg>
-);
+)
class BackupPhraseScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
address: PropTypes.string.isRequired,
- seedWords: PropTypes.string.isRequired,
- next: PropTypes.func.isRequired,
- confirmSeedWords: PropTypes.func.isRequired,
+ seedWords: PropTypes.string,
+ history: PropTypes.object,
};
static defaultProps = {
- seedWords: ''
- };
-
- static PAGE = {
- SECRET: 'secret',
- CONFIRM: 'confirm'
- };
+ seedWords: '',
+ }
- constructor(props) {
- const {seedWords} = props
+ constructor (props) {
super(props)
this.state = {
isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.SECRET,
- selectedSeeds: [],
- shuffledSeeds: seedWords && shuffle(seedWords.split(' ')),
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
}
}
@@ -72,7 +69,7 @@ class BackupPhraseScreen extends Component {
return (
<div className="backup-phrase__secret">
<div className={classnames('backup-phrase__secret-words', {
- 'backup-phrase__secret-words--hidden': !isShowingSecret
+ 'backup-phrase__secret-words--hidden': !isShowingSecret,
})}>
{this.props.seedWords}
</div>
@@ -88,11 +85,12 @@ class BackupPhraseScreen extends Component {
</div>
)}
</div>
- );
+ )
}
- renderSecretScreen() {
+ renderSecretScreen () {
const { isShowingSecret } = this.state
+ const { history } = this.props
return (
<div className="backup-phrase__content-wrapper">
@@ -107,10 +105,7 @@ class BackupPhraseScreen extends Component {
{this.renderSecretWordsContainer()}
<button
className="first-time-flow__button"
- onClick={() => isShowingSecret && this.setState({
- isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.CONFIRM
- })}
+ onClick={() => isShowingSecret && history.push(CONFIRM_SEED_ROUTE)}
disabled={!isShowingSecret}
>
Next
@@ -133,109 +128,21 @@ class BackupPhraseScreen extends Component {
)
}
- renderConfirmationScreen() {
- const { seedWords, confirmSeedWords, next } = this.props;
- const { selectedSeeds, shuffledSeeds } = this.state;
- const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
-
+ render () {
return (
- <div className="backup-phrase__content-wrapper">
- <div>
- <div className="backup-phrase__title">Confirm your Secret Backup Phrase</div>
- <div className="backup-phrase__body-text">
- Please select each phrase in order to make sure it is correct.
- </div>
- <div className="backup-phrase__confirm-secret">
- {selectedSeeds.map(([_, word], i) => (
- <button
- key={i}
- className="backup-phrase__confirm-seed-option"
- >
- {word}
- </button>
- ))}
- </div>
- <div className="backup-phrase__confirm-seed-options">
- {shuffledSeeds.map((word, i) => {
- const isSelected = selectedSeeds
- .filter(([index, seed]) => seed === word && index === i)
- .length
-
- return (
- <button
- key={i}
- className={classnames('backup-phrase__confirm-seed-option', {
- 'backup-phrase__confirm-seed-option--selected': isSelected
- })}
- onClick={() => {
- if (!isSelected) {
- this.setState({
- selectedSeeds: [...selectedSeeds, [i, word]]
- })
- } else {
- this.setState({
- selectedSeeds: selectedSeeds
- .filter(([index, seed]) => !(seed === word && index === i))
- })
- }
- }}
- >
- {word}
- </button>
- )
- })}
- </div>
- <button
- className="first-time-flow__button"
- onClick={() => isValid && confirmSeedWords().then(next)}
- disabled={!isValid}
- >
- Confirm
- </button>
- </div>
+ <div className="first-time-flow">
+ {
+ this.props.isLoading
+ ? <LoadingScreen loadingMessage="Creating your new account" />
+ : (
+ <div className="backup-phrase">
+ <Identicon address={this.props.address} diameter={70} />
+ {this.renderSecretScreen()}
+ </div>
+ )
+ }
</div>
- )
- }
-
- renderBack () {
- return this.state.page === BackupPhraseScreen.PAGE.CONFIRM
- ? (
- <a
- className="backup-phrase__back-button"
- onClick={e => {
- e.preventDefault()
- this.setState({
- page: BackupPhraseScreen.PAGE.SECRET
- })
- }}
- href="#"
- >
- {`< Back`}
- </a>
- )
- : null
- }
-
- renderContent () {
- switch (this.state.page) {
- case BackupPhraseScreen.PAGE.CONFIRM:
- return this.renderConfirmationScreen()
- case BackupPhraseScreen.PAGE.SECRET:
- default:
- return this.renderSecretScreen()
- }
- }
-
- render () {
- return this.props.isLoading
- ? <LoadingScreen loadingMessage="Creating your new account" />
- : (
- <div className="backup-phrase">
- {this.renderBack()}
- <Identicon address={this.props.address} diameter={70} />
- {this.renderContent()}
- </div>
- )
+ )
}
}
@@ -246,9 +153,6 @@ export default compose(
seedWords,
isLoading,
address: selectedAddress,
- }),
- dispatch => ({
- confirmSeedWords: () => dispatch(confirmSeedWords()),
})
)
)(BackupPhraseScreen)
diff --git a/package.json b/package.json
index c5223c333..576862426 100644
--- a/package.json
+++ b/package.json
@@ -136,6 +136,7 @@
"post-message-stream": "^3.0.0",
"promise-filter": "^1.1.0",
"promise-to-callback": "^1.0.0",
+ "prop-types": "^15.6.0",
"pump": "^1.0.2",
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
@@ -146,6 +147,7 @@
"react-hyperscript": "^3.0.0",
"react-markdown": "^3.0.0",
"react-redux": "^5.0.5",
+ "react-router-dom": "^4.2.2",
"react-select": "^1.0.0",
"react-simple-file-input": "^2.0.0",
"react-tippy": "^1.2.2",
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index 0da435298..85951f512 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -71,8 +71,8 @@ AccountDetailScreen.prototype.tabSections = function () {
{ content: 'Sent', key: 'history' },
{ content: 'Tokens', key: 'tokens' },
],
- defaultTab: currentAccountTab || 'history',
- tabSelected: (key) => {
+ selectedTab: currentAccountTab || 'history',
+ onSelect: key => {
this.props.dispatch(actions.setCurrentAccountTab(key))
},
}),
diff --git a/ui/app/accounts/new-account/index.js b/ui/app/accounts/new-account/index.js
deleted file mode 100644
index acf0dc6e4..000000000
--- a/ui/app/accounts/new-account/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../../actions')
-const { getCurrentViewContext } = require('../../selectors')
-const classnames = require('classnames')
-
-const NewAccountCreateForm = require('./create-form')
-const NewAccountImportForm = require('../import')
-
-function mapStateToProps (state) {
- return {
- displayedForm: getCurrentViewContext(state),
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- displayForm: form => dispatch(actions.setNewAccountForm(form)),
- showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
- showExportPrivateKeyModal: () => {
- dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
- },
- hideModal: () => dispatch(actions.hideModal()),
- saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
- }
-}
-
-inherits(AccountDetailsModal, Component)
-function AccountDetailsModal (props) {
- Component.call(this)
-
- this.state = {
- displayedForm: props.displayedForm,
- }
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
-
-AccountDetailsModal.prototype.render = function () {
- const { displayedForm, displayForm } = this.props
-
- return h('div.new-account', {}, [
-
- h('div.new-account__header', [
-
- h('div.new-account__title', 'New Account'),
-
- h('div.new-account__tabs', [
-
- h('div.new-account__tabs__tab', {
- className: classnames('new-account__tabs__tab', {
- 'new-account__tabs__selected': displayedForm === 'CREATE',
- 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'CREATE',
- }),
- onClick: () => displayForm('CREATE'),
- }, 'Create'),
-
- h('div.new-account__tabs__tab', {
- className: classnames('new-account__tabs__tab', {
- 'new-account__tabs__selected': displayedForm === 'IMPORT',
- 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'IMPORT',
- }),
- onClick: () => displayForm('IMPORT'),
- }, 'Import'),
-
- ]),
-
- ]),
-
- h('div.new-account__form', [
-
- displayedForm === 'CREATE'
- ? h(NewAccountCreateForm)
- : h(NewAccountImportForm),
-
- ]),
-
- ])
-}
diff --git a/ui/app/actions.js b/ui/app/actions.js
index f930a93c1..138479ca4 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -285,15 +285,20 @@ function tryUnlockMetamask (password) {
dispatch(actions.showLoadingIndication())
dispatch(actions.unlockInProgress())
log.debug(`background.submitPassword`)
- background.submitPassword(password, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.unlockFailed(err.message))
- } else {
- dispatch(actions.unlockSucceeded())
- dispatch(actions.transitionForward())
- forceUpdateMetamaskState(dispatch)
- }
+
+ return new Promise((resolve, reject) => {
+ background.submitPassword(password, (err) => {
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ dispatch(actions.unlockFailed(err.message))
+ reject(err)
+ } else {
+ dispatch(actions.unlockSucceeded())
+ dispatch(actions.transitionForward())
+ return forceUpdateMetamaskState(dispatch).then(resolve)
+ }
+ })
})
}
}
@@ -311,7 +316,7 @@ function transitionBackward () {
}
function confirmSeedWords () {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
log.debug(`background.clearSeedWordCache`)
return new Promise((resolve, reject) => {
@@ -319,7 +324,7 @@ function confirmSeedWords () {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.displayWarning(err.message))
- reject(err)
+ return reject(err)
}
log.info('Seed word cache cleared. ' + account)
@@ -364,14 +369,14 @@ function createNewVaultAndKeychain (password) {
return reject(err)
}
log.debug(`background.placeSeedWords`)
+
background.placeSeedWords((err) => {
if (err) {
dispatch(actions.displayWarning(err.message))
return reject(err)
}
dispatch(actions.hideLoadingIndication())
- forceUpdateMetamaskState(dispatch)
- resolve()
+ forceUpdateMetamaskState(dispatch).then(resolve)
})
})
})
@@ -519,35 +524,47 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signMessage`)
- background.signMessage(msgData, (err, newState) => {
- log.debug('signMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signMessage`)
+ background.signMessage(msgData, (err, newState) => {
+ log.debug('signMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
function signPersonalMsg (msgData) {
log.debug('action - signPersonalMsg')
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signPersonalMessage`)
- background.signPersonalMessage(msgData, (err, newState) => {
- log.debug('signPersonalMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signPersonalMessage`)
+ background.signPersonalMessage(msgData, (err, newState) => {
+ log.debug('signPersonalMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -557,16 +574,22 @@ function signTypedMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signTypedMessage`)
- background.signTypedMessage(msgData, (err, newState) => {
- log.debug('signTypedMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signTypedMessage`)
+ background.signTypedMessage(msgData, (err, newState) => {
+ log.debug('signTypedMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -747,16 +770,23 @@ function updateAndApproveTx (txData) {
log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData))
return (dispatch) => {
log.debug(`actions calling background.updateAndApproveTx`)
- background.updateAndApproveTransaction(txData, (err) => {
- dispatch(actions.hideLoadingIndication())
- dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
- dispatch(actions.clearSend())
- if (err) {
- dispatch(actions.txError(err))
- dispatch(actions.goHome())
- return log.error(err.message)
- }
- dispatch(actions.completedTx(txData.id))
+
+ return new Promise((resolve, reject) => {
+ background.updateAndApproveTransaction(txData, err => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
+ dispatch(actions.clearSend())
+
+ if (err) {
+ dispatch(actions.txError(err))
+ dispatch(actions.goHome())
+ log.error(err.message)
+ reject(err)
+ }
+
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -784,29 +814,77 @@ function txError (err) {
}
function cancelMsg (msgData) {
- log.debug(`background.cancelMessage`)
- background.cancelMessage(msgData.id)
- return actions.completedTx(msgData.id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ log.debug(`background.cancelMessage`)
+ background.cancelMessage(msgData.id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(msgData.id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelPersonalMsg (msgData) {
- const id = msgData.id
- background.cancelPersonalMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelPersonalMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTypedMsg (msgData) {
- const id = msgData.id
- background.cancelTypedMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelTypedMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTx (txData) {
- return (dispatch) => {
+ return dispatch => {
log.debug(`background.cancelTransaction`)
- background.cancelTransaction(txData.id, () => {
- dispatch(actions.clearSend())
- dispatch(actions.completedTx(txData.id))
+ return new Promise((resolve, reject) => {
+ background.cancelTransaction(txData.id, () => {
+ dispatch(actions.clearSend())
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -1695,11 +1773,17 @@ function callBackgroundThenUpdate (method, ...args) {
function forceUpdateMetamaskState (dispatch) {
log.debug(`background.getState`)
- background.getState((err, newState) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch(actions.updateMetamaskState(newState))
+
+ return new Promise((resolve, reject) => {
+ background.getState((err, newState) => {
+ if (err) {
+ reject(err)
+ return dispatch(actions.displayWarning(err.message))
+ }
+
+ dispatch(actions.updateMetamaskState(newState))
+ resolve(newState)
+ })
})
}
diff --git a/ui/app/app.js b/ui/app/app.js
index 20dc65df3..0ecfd0dde 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -1,13 +1,18 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const connect = require('react-redux').connect
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const { connect } = require('react-redux')
+const { Switch, Redirect, withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const h = require('react-hyperscript')
const actions = require('./actions')
const classnames = require('classnames')
// mascara
-const MascaraFirstTime = require('../../mascara/src/app/first-time').default
+const MascaraCreatePassword = require('../../mascara/src/app/first-time/create-password-screen').default
const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
+const MascaraNoticeScreen = require('../../mascara/src/app/first-time/notice-screen').default
+const MascaraSeedScreen = require('../../mascara/src/app/first-time/seed-screen').default
+const MascaraConfirmSeedScreen = require('../../mascara/src/app/first-time/confirm-seed-screen').default
// init
const InitializeMenuScreen = require('./first-time/init-menu')
const NewKeyChainScreen = require('./new-keychain')
@@ -15,25 +20,27 @@ const NewKeyChainScreen = require('./new-keychain')
const MainContainer = require('./main-container')
const SendTransactionScreen2 = require('./components/send/send-v2-container')
const ConfirmTxScreen = require('./conf-tx')
-// notice
-const NoticeScreen = require('./components/notice')
-const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
// slideout menu
const WalletView = require('./components/wallet-view')
// other views
-const Settings = require('./settings')
-const AddTokenScreen = require('./add-token')
-const Import = require('./accounts/import')
-const NewAccount = require('./accounts/new-account')
+const Authenticated = require('./components/pages/authenticated')
+const Initialized = require('./components/pages/initialized')
+const MetamaskRoute = require('./components/pages/metamask-route')
+const Settings = require('./components/pages/settings')
+const UnlockPage = require('./components/pages/unlock')
+const RestoreVaultPage = require('./components/pages/keychains/restore-vault')
+const RevealSeedPage = require('./components/pages/keychains/reveal-seed')
+const AddTokenPage = require('./components/pages/add-token')
+const CreateAccountPage = require('./components/pages/create-account')
+const NoticeScreen = require('./components/pages/notice')
+const SignatureRequestPage = require('./components/pages/signature-request')
+
const Loading = require('./components/loading')
const NetworkIndicator = require('./components/network')
const Identicon = require('./components/identicon')
const BuyView = require('./components/buy-button-subview')
-const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
-const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
-const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const NetworkDropdown = require('./components/dropdowns/network-dropdown')
const AccountMenu = require('./components/account-menu')
@@ -42,474 +49,653 @@ const QrView = require('./components/qr-code')
// Global Modals
const Modal = require('./components/modals/index').Modal
-module.exports = connect(mapStateToProps, mapDispatchToProps)(App)
-
-inherits(App, Component)
-function App () { Component.call(this) }
+// Routes
+const {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ REVEAL_SEED_ROUTE,
+ CONFIRM_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ INITIALIZE_ROUTE,
+ NOTICE_ROUTE,
+ SIGNATURE_REQUEST_ROUTE,
+} = require('./routes')
+
+class App extends Component {
+ constructor (props) {
+ super(props)
+
+ this.renderPrimary = this.renderPrimary.bind(this)
+ }
-function mapStateToProps (state) {
- const {
- identities,
- accounts,
- address,
- keyrings,
- isInitialized,
- noActiveNotices,
- seedWords,
- } = state.metamask
- const selected = address || Object.keys(accounts)[0]
+ componentWillMount () {
+ const { currentCurrency, setCurrentCurrencyToUSD } = this.props
- return {
- // state from plugin
- networkDropdownOpen: state.appState.networkDropdownOpen,
- sidebarOpen: state.appState.sidebarOpen,
- isLoading: state.appState.isLoading,
- loadingMessage: state.appState.loadingMessage,
- noActiveNotices: state.metamask.noActiveNotices,
- isInitialized: state.metamask.isInitialized,
- isUnlocked: state.metamask.isUnlocked,
- selectedAddress: state.metamask.selectedAddress,
- currentView: state.appState.currentView,
- activeAddress: state.appState.activeAddress,
- transForward: state.appState.transForward,
- isMascara: state.metamask.isMascara,
- isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
- seedWords: state.metamask.seedWords,
- unapprovedTxs: state.metamask.unapprovedTxs,
- unapprovedMsgs: state.metamask.unapprovedMsgs,
- menuOpen: state.appState.menuOpen,
- network: state.metamask.network,
- provider: state.metamask.provider,
- forgottenPassword: state.metamask.forgottenPassword,
- lastUnreadNotice: state.metamask.lastUnreadNotice,
- lostAccounts: state.metamask.lostAccounts,
- frequentRpcList: state.metamask.frequentRpcList || [],
- currentCurrency: state.metamask.currentCurrency,
-
- // state needed to get account dropdown temporarily rendering from app bar
- identities,
- selected,
- keyrings,
+ if (!currentCurrency) {
+ setCurrentCurrencyToUSD()
+ }
}
-}
-function mapDispatchToProps (dispatch, ownProps) {
- return {
- dispatch,
- hideSidebar: () => dispatch(actions.hideSidebar()),
- showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
- hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
- setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
- toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
- }
-}
+ renderRoutes () {
+ const exact = true
-App.prototype.componentWillMount = function () {
- if (!this.props.currentCurrency) {
- this.props.setCurrentCurrencyToUSD()
+ return (
+ h(Switch, [
+ h(MetamaskRoute, {
+ path: INITIALIZE_ROUTE,
+ exact,
+ component: InitializeMenuScreen,
+ mascaraComponent: MascaraCreatePassword,
+ }),
+ h(Initialized, {
+ path: REVEAL_SEED_ROUTE,
+ exact,
+ component: RevealSeedPage,
+ mascaraComponent: MascaraSeedScreen,
+ }),
+ h(Initialized, {
+ path: CONFIRM_SEED_ROUTE,
+ exact,
+ mascaraComponent: MascaraConfirmSeedScreen,
+ }),
+ h(Initialized, { path: UNLOCK_ROUTE, exact, component: UnlockPage }),
+ h(Initialized, { path: SETTINGS_ROUTE, component: Settings }),
+ h(Initialized, { path: RESTORE_VAULT_ROUTE, exact, component: RestoreVaultPage }),
+ h(Initialized, {
+ path: NOTICE_ROUTE,
+ exact,
+ component: NoticeScreen,
+ mascaraComponent: MascaraNoticeScreen,
+ }),
+ h(Authenticated, { path: CONFIRM_TRANSACTION_ROUTE, exact, component: ConfirmTxScreen }),
+ h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen2 }),
+ h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
+ h(Authenticated, { path: NEW_ACCOUNT_ROUTE, component: CreateAccountPage }),
+ h(Authenticated, { path: SIGNATURE_REQUEST_ROUTE, exact, component: SignatureRequestPage }),
+ h(Authenticated, { path: DEFAULT_ROUTE, exact, component: this.renderPrimary }),
+ ])
+ )
}
-}
-
-App.prototype.render = function () {
- var props = this.props
- const { isLoading, loadingMessage, network } = props
- const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
- const loadMessage = loadingMessage || isLoadingNetwork ?
- `Connecting to ${this.getNetworkName()}` : null
- log.debug('Main ui render function')
-
- return (
- h('.flex-column.full-height', {
- style: {
- overflowX: 'hidden',
- position: 'relative',
- alignItems: 'center',
- },
- }, [
- // global modal
- h(Modal, {}, []),
+ render () {
+ const {
+ isLoading,
+ loadingMessage,
+ network,
+ provider,
+ frequentRpcList,
+ currentView,
+ } = this.props
+ const isLoadingNetwork = network === 'loading' && currentView.name !== 'config'
+ const loadMessage = loadingMessage || isLoadingNetwork ?
+ `Connecting to ${this.getNetworkName()}` : null
+ log.debug('Main ui render function')
+
+ return (
+ h('.flex-column.full-height', {
+ style: {
+ overflowX: 'hidden',
+ position: 'relative',
+ alignItems: 'center',
+ },
+ }, [
- // app bar
- this.renderAppBar(),
+ // global modal
+ h(Modal, {}, []),
- // sidebar
- this.renderSidebar(),
+ // app bar
+ this.renderAppBar(),
- // network dropdown
- h(NetworkDropdown, {
- provider: this.props.provider,
- frequentRpcList: this.props.frequentRpcList,
- }, []),
+ // sidebar
+ this.renderSidebar(),
- h(AccountMenu),
+ // network dropdown
+ h(NetworkDropdown, {
+ provider,
+ frequentRpcList,
+ }, []),
- (isLoading || isLoadingNetwork) && h(Loading, {
- loadingMessage: loadMessage,
- }),
+ h(AccountMenu),
- // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
+ (isLoading || isLoadingNetwork) && h(Loading, {
+ loadingMessage: loadMessage,
+ }),
- // content
- this.renderPrimary(),
- ])
- )
-}
+ // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
-App.prototype.renderGlobalModal = function () {
- return h(Modal, {
- ref: 'modalRef',
- }, [
- // h(BuyOptions, {}, []),
- ])
-}
+ // content
+ this.renderRoutes(),
+ ])
+ )
+ }
-App.prototype.renderSidebar = function () {
-
- return h('div', {
- }, [
- h('style', `
- .sidebar-enter {
- transition: transform 300ms ease-in-out;
- transform: translateX(-100%);
- }
- .sidebar-enter.sidebar-enter-active {
- transition: transform 300ms ease-in-out;
- transform: translateX(0%);
- }
- .sidebar-leave {
- transition: transform 200ms ease-out;
- transform: translateX(0%);
- }
- .sidebar-leave.sidebar-leave-active {
- transition: transform 200ms ease-out;
- transform: translateX(-100%);
- }
- `),
-
- h(ReactCSSTransitionGroup, {
- transitionName: 'sidebar',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 200,
+ renderGlobalModal () {
+ return h(Modal, {
+ ref: 'modalRef',
}, [
- // A second instance of Walletview is used for non-mobile viewports
- this.props.sidebarOpen ? h(WalletView, {
- responsiveDisplayClassname: '.sidebar',
- style: {},
- }) : undefined,
-
- ]),
-
- // overlay
- // TODO: add onClick for overlay to close sidebar
- this.props.sidebarOpen ? h('div.sidebar-overlay', {
- style: {},
- onClick: () => {
- this.props.hideSidebar()
- },
- }, []) : undefined,
- ])
-}
-
-App.prototype.renderAppBar = function () {
- const {
- isUnlocked,
- network,
- provider,
- networkDropdownOpen,
- showNetworkDropdown,
- hideNetworkDropdown,
- currentView,
- } = this.props
-
- if (window.METAMASK_UI_TYPE === 'notification') {
- return null
+ // h(BuyOptions, {}, []),
+ ])
}
- const props = this.props
- const {isMascara, isOnboarding} = props
+ renderSidebar () {
+ return h('div', [
+ h('style', `
+ .sidebar-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(-100%);
+ }
+ .sidebar-enter.sidebar-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave.sidebar-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(-100%);
+ }
+ `),
+
+ h(ReactCSSTransitionGroup, {
+ transitionName: 'sidebar',
+ transitionEnterTimeout: 300,
+ transitionLeaveTimeout: 200,
+ }, [
+ // A second instance of Walletview is used for non-mobile viewports
+ this.props.sidebarOpen ? h(WalletView, {
+ responsiveDisplayClassname: '.sidebar',
+ style: {},
+ }) : undefined,
- // Do not render header if user is in mascara onboarding
- if (isMascara && isOnboarding) {
- return null
- }
+ ]),
- // Do not render header if user is in mascara buy ether
- if (isMascara && props.currentView.name === 'buyEth') {
- return null
+ // overlay
+ // TODO: add onClick for overlay to close sidebar
+ this.props.sidebarOpen ? h('div.sidebar-overlay', {
+ style: {},
+ onClick: () => {
+ this.props.hideSidebar()
+ },
+ }, []) : undefined,
+ ])
}
- return (
-
- h('.full-width', {
- style: {},
- }, [
-
- h('.app-header.flex-row.flex-space-between', {
- className: classnames({
- 'app-header--initialized': !isOnboarding,
- }),
+ renderAppBar () {
+ const {
+ isUnlocked,
+ network,
+ provider,
+ networkDropdownOpen,
+ showNetworkDropdown,
+ hideNetworkDropdown,
+ currentView,
+ } = this.props
+
+ if (window.METAMASK_UI_TYPE === 'notification') {
+ return null
+ }
+
+ const props = this.props
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
+ return (
+
+ h('.full-width', {
+ style: {},
}, [
- h('div.app-header-contents', {}, [
- h('div.left-menu-wrapper', {
- onClick: () => {
- props.dispatch(actions.backToAccountDetail(props.activeAddress))
- },
- }, [
- // mini logo
- h('img.metafox-icon', {
- height: 42,
- width: 42,
- src: '/images/metamask-fox.svg',
- }),
-
- // metamask name
- h('h1', 'MetaMask'),
-
- ]),
- h('div.header__right-actions', [
- h('div.network-component-wrapper', {
- style: {},
+ h('.app-header.flex-row.flex-space-between', {
+ className: classnames({
+ 'app-header--initialized': !isOnboarding,
+ }),
+ }, [
+ h('div.app-header-contents', {}, [
+ h('div.left-menu-wrapper', {
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
- // Network Indicator
- h(NetworkIndicator, {
- network,
- provider,
- disabled: currentView.name === 'confTx',
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- return networkDropdownOpen === false
- ? showNetworkDropdown()
- : hideNetworkDropdown()
- },
+ // mini logo
+ h('img.metafox-icon', {
+ height: 42,
+ width: 42,
+ src: '/images/metamask-fox.svg',
}),
+ // metamask name
+ h('h1', 'MetaMask'),
+
]),
- isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
- h(Identicon, {
- address: this.props.selectedAddress,
- diameter: 32,
- }),
+ h('div.header__right-actions', [
+ h('div.network-component-wrapper', {
+ style: {},
+ }, [
+ // Network Indicator
+ h(NetworkIndicator, {
+ network,
+ provider,
+ disabled: currentView.name === 'confTx',
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ return networkDropdownOpen === false
+ ? showNetworkDropdown()
+ : hideNetworkDropdown()
+ },
+ }),
+
+ ]),
+
+ isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
+ h(Identicon, {
+ address: this.props.selectedAddress,
+ diameter: 32,
+ }),
+ ]),
]),
]),
]),
- ]),
-
- ])
- )
-}
-App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
- const { isMascara } = this.props
+ ])
+ )
+ }
- return isMascara
- ? null
- : h(Loading, {
- isLoading: isLoading || isLoadingNetwork,
- loadingMessage: loadMessage,
- })
-}
+ renderLoadingIndicator ({ isLoading, isLoadingNetwork, loadMessage }) {
+ const { isMascara } = this.props
-App.prototype.renderBackButton = function (style, justArrow = false) {
- var props = this.props
- return (
- h('.flex-row', {
- key: 'leftArrow',
- style: style,
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, [
- h('i.fa.fa-arrow-left.cursor-pointer'),
- justArrow ? null : h('div.cursor-pointer', {
- style: {
- marginLeft: '3px',
- },
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, 'BACK'),
- ])
- )
-}
+ return isMascara
+ ? null
+ : h(Loading, {
+ isLoading: isLoading || isLoadingNetwork,
+ loadingMessage: loadMessage,
+ })
+ }
-App.prototype.renderPrimary = function () {
- log.debug('rendering primary')
- var props = this.props
- const {isMascara, isOnboarding} = props
+ renderBackButton (style, justArrow = false) {
+ const { dispatch } = this.props
- if (isMascara && isOnboarding) {
- return h(MascaraFirstTime)
+ return (
+ h('.flex-row', {
+ key: 'leftArrow',
+ style: style,
+ onClick: () => dispatch(actions.goBackToInitView()),
+ }, [
+ h('i.fa.fa-arrow-left.cursor-pointer'),
+ justArrow ? null : h('div.cursor-pointer', {
+ style: {
+ marginLeft: '3px',
+ },
+ onClick: () => dispatch(actions.goBackToInitView()),
+ }, 'BACK'),
+ ])
+ )
}
- // notices
- if (!props.noActiveNotices) {
- log.debug('rendering notice screen for unread notices.')
- return h(NoticeScreen, {
- notice: props.lastUnreadNotice,
- key: 'NoticeScreen',
- onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
- })
- } else if (props.lostAccounts && props.lostAccounts.length > 0) {
- log.debug('rendering notice screen for lost accounts view.')
- return h(NoticeScreen, {
- notice: generateLostAccountsNotice(props.lostAccounts),
- key: 'LostAccountsNotice',
- onConfirm: () => props.dispatch(actions.markAccountsFound()),
- })
- }
+ renderPrimary () {
+ log.debug('rendering primary')
+ const {
+ noActiveNotices,
+ lostAccounts,
+ forgottenPassword,
+ currentView,
+ activeAddress,
+ unapprovedTxs = {},
+ seedWords,
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ // seed words
+ if (seedWords) {
+ log.debug('rendering seed words')
+ return h(Redirect, {
+ to: {
+ pathname: REVEAL_SEED_ROUTE,
+ },
+ })
+ }
+
+ if (forgottenPassword) {
+ log.debug('rendering restore vault screen')
+ return h(Redirect, {
+ to: {
+ pathname: RESTORE_VAULT_ROUTE,
+ },
+ })
+ }
+
+ // notices
+ if (!noActiveNotices || (lostAccounts && lostAccounts.length > 0)) {
+ return h(Redirect, {
+ to: {
+ pathname: NOTICE_ROUTE,
+ },
+ })
+ }
+
+ // unapprovedTxs
+ if (Object.keys(unapprovedTxs).length) {
+ return h(Redirect, {
+ to: {
+ pathname: CONFIRM_TRANSACTION_ROUTE,
+ },
+ })
+ }
+
+ // unapproved messages
+ if (unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount > 0) {
+ return h(Redirect, {
+ to: {
+ pathname: SIGNATURE_REQUEST_ROUTE,
+ },
+ })
+ }
+
+ // if (!props.noActiveNotices) {
+ // log.debug('rendering notice screen for unread notices.')
+ // return h(NoticeScreen, {
+ // notice: props.lastUnreadNotice,
+ // key: 'NoticeScreen',
+ // onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ // })
+ // } else if (props.lostAccounts && props.lostAccounts.length > 0) {
+ // log.debug('rendering notice screen for lost accounts view.')
+ // return h(NoticeScreen, {
+ // notice: generateLostAccountsNotice(props.lostAccounts),
+ // key: 'LostAccountsNotice',
+ // onConfirm: () => props.dispatch(actions.markAccountsFound()),
+ // })
+ // }
+
+ // if (props.seedWords) {
+ // log.debug('rendering seed words')
+ // return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
+ // }
+
+ // show initialize screen
+ // if (!isInitialized || forgottenPassword) {
+ // // show current view
+ // log.debug('rendering an initialize screen')
+ // // switch (props.currentView.name) {
+
+ // // case 'restoreVault':
+ // // log.debug('rendering restore vault screen')
+ // // return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ // // default:
+ // // log.debug('rendering menu screen')
+ // // return h(InitializeMenuScreen, {key: 'menuScreenInit'})
+ // // }
+ // }
+
+ // // show unlock screen
+ // if (!props.isUnlocked) {
+ // return h(MainContainer, {
+ // currentViewName: props.currentView.name,
+ // isUnlocked: props.isUnlocked,
+ // })
+ // }
+
+ // show current view
+ switch (currentView.name) {
+
+ case 'accountDetail':
+ log.debug('rendering main container')
+ return h(MainContainer, {key: 'account-detail'})
+
+ // case 'sendTransaction':
+ // log.debug('rendering send tx screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTransactionScreen
+
+ // return h(SendTransactionScreen2, {key: 'send-transaction'})
+
+ // case 'sendToken':
+ // log.debug('rendering send token screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTokenScreen
+
+ // return h(SendTransactionScreen2, {key: 'sendToken'})
+
+ case 'newKeychain':
+ log.debug('rendering new keychain screen')
+ return h(NewKeyChainScreen, {key: 'new-keychain'})
+
+ // case 'confTx':
+ // log.debug('rendering confirm tx screen')
+ // return h(Redirect, {
+ // to: {
+ // pathname: CONFIRM_TRANSACTION_ROUTE,
+ // },
+ // })
+ // return h(ConfirmTxScreen, {key: 'confirm-tx'})
+
+ // case 'add-token':
+ // log.debug('rendering add-token screen from unlock screen.')
+ // return h(AddTokenScreen, {key: 'add-token'})
+
+ // case 'config':
+ // log.debug('rendering config screen')
+ // return h(Settings, {key: 'config'})
+
+ // case 'import-menu':
+ // log.debug('rendering import screen')
+ // return h(Import, {key: 'import-menu'})
+
+ // case 'reveal-seed-conf':
+ // log.debug('rendering reveal seed confirmation screen')
+ // return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
+
+ // case 'info':
+ // log.debug('rendering info screen')
+ // return h(Settings, {key: 'info', tab: 'info'})
+
+ case 'buyEth':
+ log.debug('rendering buy ether screen')
+ return h(BuyView, {key: 'buyEthView'})
+
+ case 'onboardingBuyEth':
+ log.debug('rendering onboarding buy ether screen')
+ return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+
+ case 'qr':
+ log.debug('rendering show qr screen')
+ return h('div', {
+ style: {
+ position: 'absolute',
+ height: '100%',
+ top: '0px',
+ left: '0px',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: () => this.props.dispatch(actions.backToAccountDetail(activeAddress)),
+ style: {
+ marginLeft: '10px',
+ marginTop: '50px',
+ },
+ }),
+ h('div', {
+ style: {
+ position: 'absolute',
+ left: '44px',
+ width: '285px',
+ },
+ }, [
+ h(QrView, {key: 'qr'}),
+ ]),
+ ])
- if (props.isInitialized && props.forgottenPassword) {
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
- } else if (!props.isInitialized) {
- log.debug('rendering menu screen')
- return h(InitializeMenuScreen, {key: 'menuScreenInit'})
+ default:
+ log.debug('rendering default, account detail screen')
+ return h(MainContainer, {key: 'account-detail'})
+ }
}
- // show unlock screen
- if (!props.isUnlocked) {
- return h(MainContainer, {
- currentViewName: props.currentView.name,
- isUnlocked: props.isUnlocked,
- })
+ toggleMetamaskActive () {
+ if (!this.props.isUnlocked) {
+ // currently inactive: redirect to password box
+ var passwordBox = document.querySelector('input[type=password]')
+ if (!passwordBox) return
+ passwordBox.focus()
+ } else {
+ // currently active: deactivate
+ this.props.dispatch(actions.lockMetamask(false))
+ }
}
- // show seed words screen
- if (props.seedWords) {
- log.debug('rendering seed words')
- return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
+ getNetworkName () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = 'Main Ethereum Network'
+ } else if (providerName === 'ropsten') {
+ name = 'Ropsten Test Network'
+ } else if (providerName === 'kovan') {
+ name = 'Kovan Test Network'
+ } else if (providerName === 'rinkeby') {
+ name = 'Rinkeby Test Network'
+ } else {
+ name = 'Unknown Private Network'
+ }
+
+ return name
}
+}
- // show current view
- switch (props.currentView.name) {
-
- case 'accountDetail':
- log.debug('rendering main container')
- return h(MainContainer, {key: 'account-detail'})
-
- case 'sendTransaction':
- log.debug('rendering send tx screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTransactionScreen
-
- return h(SendTransactionScreen2, {key: 'send-transaction'})
-
- case 'sendToken':
- log.debug('rendering send token screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTokenScreen
-
- return h(SendTransactionScreen2, {key: 'sendToken'})
-
- case 'newKeychain':
- log.debug('rendering new keychain screen')
- return h(NewKeyChainScreen, {key: 'new-keychain'})
-
- case 'confTx':
- log.debug('rendering confirm tx screen')
- return h(ConfirmTxScreen, {key: 'confirm-tx'})
-
- case 'add-token':
- log.debug('rendering add-token screen from unlock screen.')
- return h(AddTokenScreen, {key: 'add-token'})
-
- case 'config':
- log.debug('rendering config screen')
- return h(Settings, {key: 'config'})
-
- case 'import-menu':
- log.debug('rendering import screen')
- return h(Import, {key: 'import-menu'})
-
- case 'new-account-page':
- log.debug('rendering new account screen')
- return h(NewAccount, {key: 'new-account'})
-
- case 'reveal-seed-conf':
- log.debug('rendering reveal seed confirmation screen')
- return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
-
- case 'info':
- log.debug('rendering info screen')
- return h(Settings, {key: 'info', tab: 'info'})
+App.propTypes = {
+ currentCurrency: PropTypes.string,
+ setCurrentCurrencyToUSD: PropTypes.func,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcList: PropTypes.array,
+ currentView: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ hideSidebar: PropTypes.func,
+ isMascara: PropTypes.bool,
+ isOnboarding: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ networkDropdownOpen: PropTypes.bool,
+ showNetworkDropdown: PropTypes.func,
+ hideNetworkDropdown: PropTypes.func,
+ history: PropTypes.object,
+ dispatch: PropTypes.func,
+ toggleAccountMenu: PropTypes.func,
+ selectedAddress: PropTypes.string,
+ noActiveNotices: PropTypes.bool,
+ lostAccounts: PropTypes.array,
+ isInitialized: PropTypes.bool,
+ forgottenPassword: PropTypes.bool,
+ activeAddress: PropTypes.string,
+ unapprovedTxs: PropTypes.object,
+ seedWords: PropTypes.string,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+}
- case 'buyEth':
- log.debug('rendering buy ether screen')
- return h(BuyView, {key: 'buyEthView'})
+function mapStateToProps (state) {
+ const { appState, metamask } = state
+ const {
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ } = appState
- case 'onboardingBuyEth':
- log.debug('rendering onboarding buy ether screen')
- return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+ const {
+ identities,
+ accounts,
+ address,
+ keyrings,
+ isInitialized,
+ noActiveNotices,
+ seedWords,
+ unapprovedTxs,
+ lastUnreadNotice,
+ lostAccounts,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+ const selected = address || Object.keys(accounts)[0]
- case 'qr':
- log.debug('rendering show qr screen')
- return h('div', {
- style: {
- position: 'absolute',
- height: '100%',
- top: '0px',
- left: '0px',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
- style: {
- marginLeft: '10px',
- marginTop: '50px',
- },
- }),
- h('div', {
- style: {
- position: 'absolute',
- left: '44px',
- width: '285px',
- },
- }, [
- h(QrView, {key: 'qr'}),
- ]),
- ])
+ return {
+ // state from plugin
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ noActiveNotices,
+ isInitialized,
+ isUnlocked: state.metamask.isUnlocked,
+ selectedAddress: state.metamask.selectedAddress,
+ currentView: state.appState.currentView,
+ activeAddress: state.appState.activeAddress,
+ transForward: state.appState.transForward,
+ isMascara: state.metamask.isMascara,
+ isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ seedWords: state.metamask.seedWords,
+ unapprovedTxs,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ menuOpen: state.appState.menuOpen,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice,
+ lostAccounts,
+ frequentRpcList: state.metamask.frequentRpcList || [],
+ currentCurrency: state.metamask.currentCurrency,
- default:
- log.debug('rendering default, account detail screen')
- return h(MainContainer, {key: 'account-detail'})
+ // state needed to get account dropdown temporarily rendering from app bar
+ identities,
+ selected,
+ keyrings,
}
}
-App.prototype.toggleMetamaskActive = function () {
- if (!this.props.isUnlocked) {
- // currently inactive: redirect to password box
- var passwordBox = document.querySelector('input[type=password]')
- if (!passwordBox) return
- passwordBox.focus()
- } else {
- // currently active: deactivate
- this.props.dispatch(actions.lockMetamask(false))
+function mapDispatchToProps (dispatch, ownProps) {
+ return {
+ dispatch,
+ hideSidebar: () => dispatch(actions.hideSidebar()),
+ showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
+ hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
+ setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
+ toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
}
}
-App.prototype.getNetworkName = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = 'Main Ethereum Network'
- } else if (providerName === 'ropsten') {
- name = 'Ropsten Test Network'
- } else if (providerName === 'kovan') {
- name = 'Kovan Test Network'
- } else if (providerName === 'rinkeby') {
- name = 'Rinkeby Test Network'
- } else {
- name = 'Unknown Private Network'
- }
-
- return name
-}
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(App)
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
index 1a0103d4f..2b371eedf 100644
--- a/ui/app/components/account-menu/index.js
+++ b/ui/app/components/account-menu/index.js
@@ -1,13 +1,25 @@
const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
+const { compose } = require('recompose')
+const { withRouter } = require('react-router-dom')
const h = require('react-hyperscript')
const actions = require('../../actions')
const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
const Identicon = require('../identicon')
const { formatBalance } = require('../../util')
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountMenu)
+const {
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ DEFAULT_ROUTE,
+} = require('../../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(AccountMenu)
inherits(AccountMenu, Component)
function AccountMenu () { Component.call(this) }
@@ -19,7 +31,6 @@ function mapStateToProps (state) {
keyrings: state.metamask.keyrings,
identities: state.metamask.identities,
accounts: state.metamask.accounts,
-
}
}
@@ -42,11 +53,6 @@ function mapDispatchToProps (dispatch) {
dispatch(actions.hideSidebar())
dispatch(actions.toggleAccountMenu())
},
- showNewAccountPage: (formToSelect) => {
- dispatch(actions.showNewAccountPage(formToSelect))
- dispatch(actions.hideSidebar())
- dispatch(actions.toggleAccountMenu())
- },
showInfoPage: () => {
dispatch(actions.showInfoPage())
dispatch(actions.hideSidebar())
@@ -59,10 +65,8 @@ AccountMenu.prototype.render = function () {
const {
isAccountMenuOpen,
toggleAccountMenu,
- showNewAccountPage,
lockMetamask,
- showConfigPage,
- showInfoPage,
+ history,
} = this.props
return h(Menu, { className: 'account-menu', isShowing: isAccountMenuOpen }, [
@@ -72,30 +76,45 @@ AccountMenu.prototype.render = function () {
}, [
'My Accounts',
h('button.account-menu__logout-button', {
- onClick: lockMetamask,
+ onClick: () => {
+ lockMetamask()
+ history.push(DEFAULT_ROUTE)
+ },
}, 'Log out'),
]),
h(Divider),
h('div.account-menu__accounts', this.renderAccounts()),
h(Divider),
h(Item, {
- onClick: () => showNewAccountPage('CREATE'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(NEW_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }),
text: 'Create Account',
}),
h(Item, {
- onClick: () => showNewAccountPage('IMPORT'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(IMPORT_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }),
text: 'Import Account',
}),
h(Divider),
h(Item, {
- onClick: showInfoPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(INFO_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/mm-info-icon.svg' }),
text: 'Info & Help',
}),
h(Item, {
- onClick: showConfigPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(SETTINGS_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
text: 'Settings',
}),
diff --git a/ui/app/components/notice.js b/ui/app/components/notice.js
deleted file mode 100644
index 941ac33e6..000000000
--- a/ui/app/components/notice.js
+++ /dev/null
@@ -1,132 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const ReactMarkdown = require('react-markdown')
-const linker = require('extension-link-enabler')
-const findDOMNode = require('react-dom').findDOMNode
-
-module.exports = Notice
-
-inherits(Notice, Component)
-function Notice () {
- Component.call(this)
-}
-
-Notice.prototype.render = function () {
- const { notice, onConfirm } = this.props
- const { title, date, body } = notice
- const state = this.state || { disclaimerDisabled: true }
- const disabled = state.disclaimerDisabled
-
- return (
- h('.flex-column.flex-center.flex-grow', {
- style: {
- width: '100%',
- },
- }, [
- h('h3.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- title,
- ]),
-
- h('h5.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- date,
- ]),
-
- h('style', `
-
- .markdown {
- overflow-x: hidden;
- }
-
- .markdown h1, .markdown h2, .markdown h3 {
- margin: 10px 0;
- font-weight: bold;
- }
-
- .markdown strong {
- font-weight: bold;
- }
- .markdown em {
- font-style: italic;
- }
-
- .markdown p {
- margin: 10px 0;
- }
-
- .markdown a {
- color: #df6b0e;
- }
-
- `),
-
- h('div.markdown', {
- onScroll: (e) => {
- var object = e.currentTarget
- if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
- this.setState({disclaimerDisabled: false})
- }
- },
- style: {
- background: 'rgb(235, 235, 235)',
- height: '310px',
- padding: '6px',
- width: '90%',
- overflowY: 'scroll',
- scroll: 'auto',
- },
- }, [
- h(ReactMarkdown, {
- className: 'notice-box',
- source: body,
- skipHtml: true,
- }),
- ]),
-
- h('button.primary', {
- disabled,
- onClick: () => {
- this.setState({disclaimerDisabled: true})
- onConfirm()
- },
- style: {
- marginTop: '18px',
- },
- }, 'Accept'),
- ])
- )
-}
-
-Notice.prototype.componentDidMount = function () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.setupListener(node)
- if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
- this.setState({disclaimerDisabled: false})
- }
-}
-
-Notice.prototype.componentWillUnmount = function () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.teardownListener(node)
-}
diff --git a/ui/app/add-token.js b/ui/app/components/pages/add-token.js
index 3a806d34b..40cfedafd 100644
--- a/ui/app/add-token.js
+++ b/ui/app/components/pages/add-token.js
@@ -6,8 +6,8 @@ const connect = require('react-redux').connect
const R = require('ramda')
const Fuse = require('fuse.js')
const contractMap = require('eth-contract-metadata')
-const TokenBalance = require('./components/token-balance')
-const Identicon = require('./components/identicon')
+const TokenBalance = require('../../components/token-balance')
+const Identicon = require('../../components/identicon')
const contractList = Object.entries(contractMap)
.map(([ _, tokenData]) => tokenData)
.filter(tokenData => Boolean(tokenData.erc20))
@@ -23,9 +23,11 @@ const fuse = new Fuse(contractList, {
{ name: 'symbol', weight: 0.5 },
],
})
-const actions = require('./actions')
+// const actions = require('./actions')
+const actions = require('../../actions')
const ethUtil = require('ethereumjs-util')
-const { tokenInfoGetter } = require('./token-util')
+const { tokenInfoGetter } = require('../../token-util')
+const { DEFAULT_ROUTE } = require('../../routes')
const emptyAddr = '0x0000000000000000000000000000000000000000'
@@ -41,7 +43,6 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
addTokens: tokens => dispatch(actions.addTokens(tokens)),
}
}
@@ -263,7 +264,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
selectedTokens,
} = this.state
- const { addTokens, goHome } = this.props
+ const { addTokens, history } = this.props
const customToken = {
address,
@@ -304,7 +305,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
onClick: () => this.setState({ isShowingConfirmation: false }),
}, 'Back'),
h('button.btn-clear.add-token__button', {
- onClick: () => addTokens(tokens).then(goHome),
+ onClick: () => addTokens(tokens).then(() => history.push(DEFAULT_ROUTE)),
}, 'Add Tokens'),
]),
])
@@ -313,7 +314,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
AddTokenScreen.prototype.render = function () {
const { isCollapsed, errors, isShowingConfirmation } = this.state
- const { goHome } = this.props
+ const { history } = this.props
return isShowingConfirmation
? this.renderConfirmation()
@@ -351,7 +352,7 @@ AddTokenScreen.prototype.render = function () {
]),
h('div.add-token__buttons', [
h('button.btn-cancel.add-token__button', {
- onClick: goHome,
+ onClick: () => history.goBack(),
}, 'Cancel'),
h('button.btn-clear.add-token__button', {
onClick: this.onNext,
diff --git a/ui/app/components/pages/authenticated.js b/ui/app/components/pages/authenticated.js
new file mode 100644
index 000000000..1f6b0be49
--- /dev/null
+++ b/ui/app/components/pages/authenticated.js
@@ -0,0 +1,34 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const MetamaskRoute = require('./metamask-route')
+const { UNLOCK_ROUTE, INITIALIZE_ROUTE } = require('../../routes')
+
+const Authenticated = props => {
+ const { isUnlocked, isInitialized } = props
+
+ switch (true) {
+ case isUnlocked && isInitialized:
+ return h(MetamaskRoute, { ...props })
+ case !isInitialized:
+ return h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+ default:
+ return h(Redirect, { to: { pathname: UNLOCK_ROUTE } })
+ }
+}
+
+Authenticated.propTypes = {
+ isUnlocked: PropTypes.bool,
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked, isInitialized } } = state
+ return {
+ isUnlocked,
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Authenticated)
diff --git a/ui/app/accounts/import/index.js b/ui/app/components/pages/create-account/import-account/index.js
index 71eb9ae23..71eb9ae23 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/components/pages/create-account/import-account/index.js
diff --git a/ui/app/accounts/import/json.js b/ui/app/components/pages/create-account/import-account/json.js
index dd5dfad22..703dbc1f4 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/components/pages/create-account/import-account/json.js
@@ -1,13 +1,19 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../../actions')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { connect } = require('react-redux')
+const actions = require('../../../../actions')
const FileInput = require('react-simple-file-input').default
+const { DEFAULT_ROUTE } = require('../../../../routes')
const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
-module.exports = connect(mapStateToProps)(JsonImportSubview)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(JsonImportSubview)
function mapStateToProps (state) {
return {
@@ -50,7 +56,7 @@ JsonImportSubview.prototype.render = function () {
h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel', {
- onClick: () => this.props.goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
'CANCEL',
]),
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js
index 12f3a6430..fb10bdb48 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/components/pages/create-account/import-account/private-key.js
@@ -1,10 +1,16 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../../actions')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { connect } = require('react-redux')
+const actions = require('../../../../actions')
+const { DEFAULT_ROUTE } = require('../../../../routes')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(PrivateKeyImportView)
function mapStateToProps (state) {
return {
@@ -14,9 +20,8 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
importNewAccount: (strategy, [ privateKey ]) => {
- dispatch(actions.importNewAccount(strategy, [ privateKey ]))
+ return dispatch(actions.importNewAccount(strategy, [ privateKey ]))
},
displayWarning: () => dispatch(actions.displayWarning(null)),
}
@@ -28,7 +33,7 @@ function PrivateKeyImportView () {
}
PrivateKeyImportView.prototype.render = function () {
- const { error, goHome } = this.props
+ const { error } = this.props
return (
h('div.new-account-import-form__private-key', [
@@ -48,7 +53,7 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [
h('button.new-account-create-form__button-cancel', {
- onClick: () => goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
'CANCEL',
]),
@@ -76,6 +81,8 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
+ const { importNewAccount, history } = this.props
- this.props.importNewAccount('Private Key', [ privateKey ])
+ importNewAccount('Private Key', [ privateKey ])
+ .then(() => history.push(DEFAULT_ROUTE))
}
diff --git a/ui/app/accounts/import/seed.js b/ui/app/components/pages/create-account/import-account/seed.js
index b4a7c0afa..b4a7c0afa 100644
--- a/ui/app/accounts/import/seed.js
+++ b/ui/app/components/pages/create-account/import-account/seed.js
diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js
new file mode 100644
index 000000000..0962477d8
--- /dev/null
+++ b/ui/app/components/pages/create-account/index.js
@@ -0,0 +1,81 @@
+const Component = require('react').Component
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../actions')
+const { getCurrentViewContext } = require('../../../selectors')
+const classnames = require('classnames')
+const NewAccountCreateForm = require('./new-account')
+const NewAccountImportForm = require('./import-account')
+const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE } = require('../../../routes')
+
+class CreateAccountPage extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.new-account__tabs', [
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: NEW_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(NEW_ACCOUNT_ROUTE),
+ }, 'Create'),
+
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: IMPORT_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(IMPORT_ACCOUNT_ROUTE),
+ }, 'Import'),
+ ])
+ }
+
+ render () {
+ return h('div.new-account', {}, [
+ h('div.new-account__header', [
+ h('div.new-account__title', 'New Account'),
+ this.renderTabs(),
+ ]),
+ h('div.new-account__form', [
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: NEW_ACCOUNT_ROUTE,
+ component: NewAccountCreateForm,
+ }),
+ h(Route, {
+ exact: true,
+ path: IMPORT_ACCOUNT_ROUTE,
+ component: NewAccountImportForm,
+ }),
+ ]),
+ ]),
+ ])
+ }
+}
+
+CreateAccountPage.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => ({
+ displayedForm: getCurrentViewContext(state),
+})
+
+const mapDispatchToProps = dispatch => ({
+ displayForm: form => dispatch(actions.setNewAccountForm(form)),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
+})
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(CreateAccountPage)
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/components/pages/create-account/new-account.js
index a6b3bba4b..fbd456a75 100644
--- a/ui/app/accounts/new-account/create-form.js
+++ b/ui/app/components/pages/create-account/new-account.js
@@ -2,7 +2,8 @@ const { Component } = require('react')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const { connect } = require('react-redux')
-const actions = require('../../actions')
+const actions = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
class NewAccountCreateForm extends Component {
constructor (props) {
@@ -19,7 +20,7 @@ class NewAccountCreateForm extends Component {
render () {
const { newAccountName, defaultAccountName } = this.state
-
+ const { history, createAccount } = this.props
return h('div.new-account-create-form', [
@@ -38,13 +39,16 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel', {
- onClick: () => this.props.goHome(),
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
'CANCEL',
]),
h('button.new-account-create-form__button-create', {
- onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
+ onClick: () => {
+ createAccount(newAccountName || defaultAccountName)
+ .then(() => history.push(DEFAULT_ROUTE))
+ },
}, [
'CREATE',
]),
@@ -59,8 +63,8 @@ NewAccountCreateForm.propTypes = {
hideModal: PropTypes.func,
showImportPage: PropTypes.func,
createAccount: PropTypes.func,
- goHome: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
+ history: PropTypes.object,
}
const mapStateToProps = state => {
@@ -76,23 +80,17 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- toCoinbase: (address) => {
- dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
- },
- hideModal: () => {
- dispatch(actions.hideModal())
- },
- createAccount: (newAccountName) => {
- dispatch(actions.addNewAccount())
- .then((newAccountAddress) => {
+ toCoinbase: address => dispatch(actions.buyEth({ network: '1', address, amount: 0 })),
+ hideModal: () => dispatch(actions.hideModal()),
+ createAccount: newAccountName => {
+ return dispatch(actions.addNewAccount())
+ .then(newAccountAddress => {
if (newAccountName) {
dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName))
}
- dispatch(actions.goHome())
})
},
showImportPage: () => dispatch(actions.showImportPage()),
- goHome: () => dispatch(actions.goHome()),
}
}
diff --git a/ui/app/components/pages/initialized.js b/ui/app/components/pages/initialized.js
new file mode 100644
index 000000000..3adf67b28
--- /dev/null
+++ b/ui/app/components/pages/initialized.js
@@ -0,0 +1,25 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const { INITIALIZE_ROUTE } = require('../../routes')
+const MetamaskRoute = require('./metamask-route')
+
+const Initialized = props => {
+ return props.isInitialized
+ ? h(MetamaskRoute, { ...props })
+ : h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+}
+
+Initialized.propTypes = {
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isInitialized } } = state
+ return {
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Initialized)
diff --git a/ui/app/components/pages/keychains/restore-vault.js b/ui/app/components/pages/keychains/restore-vault.js
new file mode 100644
index 000000000..749da9758
--- /dev/null
+++ b/ui/app/components/pages/keychains/restore-vault.js
@@ -0,0 +1,170 @@
+const { withRouter } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const { compose } = require('recompose')
+const PersistentForm = require('../../../../lib/persistent-form')
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const { createNewVaultAndRestore } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+
+class RestoreVaultPage extends PersistentForm {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+ }
+
+ createOnEnter (event) {
+ if (event.key === 'Enter') {
+ this.createNewVaultAndRestore()
+ }
+ }
+
+ createNewVaultAndRestore () {
+ this.setState({ error: null })
+
+ // check password
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ if (password.length < 8) {
+ this.setState({ error: 'Password not long enough' })
+ return
+ }
+
+ if (password !== passwordConfirm) {
+ this.setState({ error: 'Passwords don\'t match' })
+ return
+ }
+
+ // check seed
+ var seedBox = document.querySelector('textarea.twelve-word-phrase')
+ var seed = seedBox.value.trim()
+ if (seed.split(' ').length !== 12) {
+ this.setState({ error: 'Seed phrases are 12 words long' })
+ return
+ }
+
+ // submit
+ this.props.createNewVaultAndRestore(password, seed)
+ .then(() => history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => {
+ this.setState({ error: message })
+ log.error(message)
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ const { history } = this.props
+ this.persistentFormParentId = 'restore-vault-form'
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Restore Vault',
+ ]),
+
+ // wallet seed entry
+ h('h3', 'Wallet Seed'),
+ h('textarea.twelve-word-phrase.letter-spacey', {
+ dataset: {
+ persistentFormId: 'wallet-seed',
+ },
+ placeholder: 'Enter your secret twelve word phrase here to restore your vault.',
+ }),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'New Password (min 8 chars)',
+ dataset: {
+ persistentFormId: 'password',
+ },
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: 'Confirm Password',
+ onKeyPress: this.createOnEnter.bind(this),
+ dataset: {
+ persistentFormId: 'password-confirmation',
+ },
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
+
+ error && (
+ h('span.error.in-progress-notification', error)
+ ),
+
+ // submit
+ h('.flex-row.flex-space-between', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+
+ // cancel
+ h('button.primary', { onClick: () => history.goBack() }, 'CANCEL'),
+
+ // submit
+ h('button.primary', {
+ onClick: this.createNewVaultAndRestore.bind(this),
+ }, 'OK'),
+
+ ]),
+ ])
+ )
+ }
+}
+
+RestoreVaultPage.propTypes = {
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => {
+ const { appState: { warning, forgottenPassword } } = state
+
+ return {
+ warning,
+ forgottenPassword,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndRestore: (password, seed) => {
+ return dispatch(createNewVaultAndRestore(password, seed))
+ },
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(RestoreVaultPage)
diff --git a/ui/app/components/pages/keychains/reveal-seed.js b/ui/app/components/pages/keychains/reveal-seed.js
new file mode 100644
index 000000000..029eb7d8e
--- /dev/null
+++ b/ui/app/components/pages/keychains/reveal-seed.js
@@ -0,0 +1,195 @@
+const { Component } = require('react')
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { exportAsFile } = require('../../../util')
+const { requestRevealSeed, confirmSeedWords } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+
+class RevealSeedPage extends Component {
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ checkConfirmation (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.revealSeedWords()
+ }
+ }
+
+ revealSeedWords () {
+ const password = document.getElementById('password-box').value
+ this.props.requestRevealSeed(password)
+ }
+
+ renderSeed () {
+ const { seedWords, confirmSeedWords, history } = this.props
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginTop: 36,
+ marginBottom: 8,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Vault Created',
+ ]),
+
+ h('div', {
+ style: {
+ fontSize: '1em',
+ marginTop: '10px',
+ textAlign: 'center',
+ },
+ }, [
+ h('span.error', 'These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret.'),
+ ]),
+
+ h('textarea.twelve-word-phrase', {
+ readOnly: true,
+ value: seedWords,
+ }),
+
+ h('button.primary', {
+ onClick: () => confirmSeedWords().then(() => history.push(DEFAULT_ROUTE)),
+ style: {
+ margin: '24px',
+ fontSize: '0.9em',
+ marginBottom: '10px',
+ },
+ }, 'I\'ve copied it somewhere safe'),
+
+ h('button.primary', {
+ onClick: () => exportAsFile(`MetaMask Seed Words`, seedWords),
+ style: {
+ margin: '10px',
+ fontSize: '0.9em',
+ },
+ }, 'Save Seed Words As File'),
+ ])
+ )
+ }
+
+ renderConfirmation () {
+ const { history, warning, inProgress } = this.props
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', {
+ style: { maxWidth: '420px' },
+ }, [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Reveal Seed Words',
+ ]),
+
+ h('.div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ padding: '20px',
+ justifyContent: 'center',
+ },
+ }, [
+
+ h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
+
+ // confirmation
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'Enter your password to confirm',
+ onKeyPress: this.checkConfirmation.bind(this),
+ style: {
+ width: 260,
+ marginTop: '12px',
+ },
+ }),
+
+ h('.flex-row.flex-start', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+ // cancel
+ h('button.primary', {
+ onClick: () => history.goBack(),
+ }, 'CANCEL'),
+
+ // submit
+ h('button.primary', {
+ style: { marginLeft: '10px' },
+ onClick: this.revealSeedWords.bind(this),
+ }, 'OK'),
+
+ ]),
+
+ warning && (
+ h('span.error', {
+ style: {
+ margin: '20px',
+ },
+ }, warning.split('-'))
+ ),
+
+ inProgress && (
+ h('span.in-progress-notification', 'Generating Seed...')
+ ),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ return this.props.seedWords
+ ? this.renderSeed()
+ : this.renderConfirmation()
+ }
+}
+
+RevealSeedPage.propTypes = {
+ requestRevealSeed: PropTypes.func,
+ confirmSeedWords: PropTypes.func,
+ seedWords: PropTypes.string,
+ inProgress: PropTypes.bool,
+ history: PropTypes.object,
+ warning: PropTypes.string,
+}
+
+const mapStateToProps = state => {
+ const { appState: { warning }, metamask: { seedWords } } = state
+
+ return {
+ warning,
+ seedWords,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ requestRevealSeed: password => dispatch(requestRevealSeed(password)),
+ confirmSeedWords: () => dispatch(confirmSeedWords()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(RevealSeedPage)
diff --git a/ui/app/components/pages/metamask-route.js b/ui/app/components/pages/metamask-route.js
new file mode 100644
index 000000000..23c5b5199
--- /dev/null
+++ b/ui/app/components/pages/metamask-route.js
@@ -0,0 +1,28 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Route } = require('react-router-dom')
+const h = require('react-hyperscript')
+
+const MetamaskRoute = ({ component, mascaraComponent, isMascara, ...props }) => {
+ return (
+ h(Route, {
+ ...props,
+ component: isMascara && mascaraComponent ? mascaraComponent : component,
+ })
+ )
+}
+
+MetamaskRoute.propTypes = {
+ component: PropTypes.func,
+ mascaraComponent: PropTypes.func,
+ isMascara: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isMascara } } = state
+ return {
+ isMascara,
+ }
+}
+
+module.exports = connect(mapStateToProps)(MetamaskRoute)
diff --git a/ui/app/components/pages/notice.js b/ui/app/components/pages/notice.js
new file mode 100644
index 000000000..2329a9147
--- /dev/null
+++ b/ui/app/components/pages/notice.js
@@ -0,0 +1,203 @@
+const { Component } = require('react')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const ReactMarkdown = require('react-markdown')
+const linker = require('extension-link-enabler')
+const generateLostAccountsNotice = require('../../../lib/lost-accounts-notice')
+const findDOMNode = require('react-dom').findDOMNode
+const actions = require('../../actions')
+const { DEFAULT_ROUTE } = require('../../routes')
+
+class Notice extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ disclaimerDisabled: true,
+ }
+ }
+
+ componentWillMount () {
+ if (!this.props.notice) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentDidMount () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+ if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
+ this.setState({ disclaimerDisabled: false })
+ }
+ }
+
+ componentWillReceiveProps (nextProps) {
+ if (!nextProps.notice) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentWillUnmount () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+ }
+
+ handleAccept () {
+ this.setState({ disclaimerDisabled: true })
+ this.props.onConfirm()
+ }
+
+ render () {
+ const { notice = {} } = this.props
+ const { title, date, body } = notice
+ const { disclaimerDisabled } = this.state
+
+ return (
+ h('.flex-column.flex-center.flex-grow', {
+ style: {
+ width: '100%',
+ },
+ }, [
+ h('h3.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ title,
+ ]),
+
+ h('h5.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ date,
+ ]),
+
+ h('style', `
+
+ .markdown {
+ overflow-x: hidden;
+ }
+
+ .markdown h1, .markdown h2, .markdown h3 {
+ margin: 10px 0;
+ font-weight: bold;
+ }
+
+ .markdown strong {
+ font-weight: bold;
+ }
+ .markdown em {
+ font-style: italic;
+ }
+
+ .markdown p {
+ margin: 10px 0;
+ }
+
+ .markdown a {
+ color: #df6b0e;
+ }
+
+ `),
+
+ h('div.markdown', {
+ onScroll: (e) => {
+ var object = e.currentTarget
+ if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
+ this.setState({ disclaimerDisabled: false })
+ }
+ },
+ style: {
+ background: 'rgb(235, 235, 235)',
+ height: '310px',
+ padding: '6px',
+ width: '90%',
+ overflowY: 'scroll',
+ scroll: 'auto',
+ },
+ }, [
+ h(ReactMarkdown, {
+ className: 'notice-box',
+ source: body,
+ skipHtml: true,
+ }),
+ ]),
+
+ h('button.primary', {
+ disabled: disclaimerDisabled,
+ onClick: () => this.handleAccept(),
+ style: {
+ marginTop: '18px',
+ },
+ }, 'Accept'),
+ ])
+ )
+ }
+
+}
+
+const mapStateToProps = state => {
+ const { metamask } = state
+ const { noActiveNotices, lastUnreadNotice, lostAccounts } = metamask
+
+ return {
+ noActiveNotices,
+ lastUnreadNotice,
+ lostAccounts,
+ }
+}
+
+Notice.propTypes = {
+ notice: PropTypes.object,
+ onConfirm: PropTypes.func,
+ history: PropTypes.object,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ markNoticeRead: lastUnreadNotice => dispatch(actions.markNoticeRead(lastUnreadNotice)),
+ markAccountsFound: () => dispatch(actions.markAccountsFound()),
+ }
+}
+
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const { noActiveNotices, lastUnreadNotice, lostAccounts } = stateProps
+ const { markNoticeRead, markAccountsFound } = dispatchProps
+
+ let notice
+ let onConfirm
+
+ if (!noActiveNotices) {
+ notice = lastUnreadNotice
+ onConfirm = () => markNoticeRead(lastUnreadNotice)
+ } else if (lostAccounts && lostAccounts.length > 0) {
+ notice = generateLostAccountsNotice(lostAccounts)
+ onConfirm = () => markAccountsFound()
+ }
+
+ return {
+ ...stateProps,
+ ...dispatchProps,
+ ...ownProps,
+ notice,
+ onConfirm,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notice)
diff --git a/ui/app/components/pages/settings/index.js b/ui/app/components/pages/settings/index.js
new file mode 100644
index 000000000..384ae4b41
--- /dev/null
+++ b/ui/app/components/pages/settings/index.js
@@ -0,0 +1,59 @@
+const { Component } = require('react')
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const TabBar = require('../../tab-bar')
+const Settings = require('./settings')
+const Info = require('./info')
+const { DEFAULT_ROUTE, SETTINGS_ROUTE, INFO_ROUTE } = require('../../../routes')
+
+class Config extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.settings__tabs', [
+ h(TabBar, {
+ tabs: [
+ { content: 'Settings', key: SETTINGS_ROUTE },
+ { content: 'Info', key: INFO_ROUTE },
+ ],
+ isActive: key => matchPath(location.pathname, { path: key, exact: true }),
+ onSelect: key => history.push(key),
+ }),
+ ])
+ }
+
+ render () {
+ const { history } = this.props
+
+ return (
+ h('.main-container.settings', {}, [
+ h('.settings__header', [
+ h('div.settings__close-button', {
+ onClick: () => history.push(DEFAULT_ROUTE),
+ }),
+ this.renderTabs(),
+ ]),
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: INFO_ROUTE,
+ component: Info,
+ }),
+ h(Route, {
+ exact: true,
+ path: SETTINGS_ROUTE,
+ component: Settings,
+ }),
+ ]),
+ ])
+ )
+ }
+}
+
+Config.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+module.exports = Config
diff --git a/ui/app/components/pages/settings/info.js b/ui/app/components/pages/settings/info.js
new file mode 100644
index 000000000..87479c84e
--- /dev/null
+++ b/ui/app/components/pages/settings/info.js
@@ -0,0 +1,107 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+
+class Info extends Component {
+ renderLogo () {
+ return (
+ h('div.settings__info-logo-wrapper', [
+ h('img.settings__info-logo', { src: 'images/info-logo.png' }),
+ ])
+ )
+ }
+
+ renderInfoLinks () {
+ return (
+ h('div.settings__content-item.settings__content-item--without-height', [
+ h('div.settings__info-link-header', 'Links'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Privacy Policy'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Terms of Use'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Attributions'),
+ ]),
+ ]),
+ h('hr.settings__info-separator'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our Support Center'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our web site'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ target: '_blank',
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, [
+ h('span.settings__info-link', 'Email us!'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ return (
+ h('div.settings__content', [
+ h('div.settings__content-row', [
+ h('div.settings__content-item.settings__content-item--without-height', [
+ this.renderLogo(),
+ h('div.settings__info-item', [
+ h('div.settings__info-version-header', 'MetaMask Version'),
+ h('div.settings__info-version-number', '4.0.0'),
+ ]),
+ h('div.settings__info-item', [
+ h(
+ 'div.settings__info-about',
+ 'MetaMask is designed and built in California.'
+ ),
+ ]),
+ ]),
+ this.renderInfoLinks(),
+ ]),
+ ])
+ )
+ }
+}
+
+Info.propTypes = {
+ tab: PropTypes.string,
+ metamask: PropTypes.object,
+ setCurrentCurrency: PropTypes.func,
+ setRpcTarget: PropTypes.func,
+ displayWarning: PropTypes.func,
+ revealSeedConfirmation: PropTypes.func,
+ warning: PropTypes.string,
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+module.exports = Info
diff --git a/ui/app/settings.js b/ui/app/components/pages/settings/settings.js
index 476bad296..5506df1ae 100644
--- a/ui/app/settings.js
+++ b/ui/app/components/pages/settings/settings.js
@@ -1,15 +1,17 @@
const { Component } = require('react')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const { connect } = require('react-redux')
-const actions = require('./actions')
-const infuraCurrencies = require('./infura-conversion.json')
+const actions = require('../../../actions')
+const infuraCurrencies = require('../../../infura-conversion.json')
const validUrl = require('valid-url')
-const { exportAsFile } = require('./util')
-const TabBar = require('./components/tab-bar')
-const SimpleDropdown = require('./components/dropdowns/simple-dropdown')
+const { exportAsFile } = require('../../../util')
+const SimpleDropdown = require('../../dropdowns/simple-dropdown')
const ToggleButton = require('react-toggle-button')
-const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const { REVEAL_SEED_ROUTE } = require('../../../routes')
+const { OLD_UI_NETWORK_TYPE } = require('../../../../../app/scripts/config').enums
const getInfuraCurrencyOptions = () => {
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
@@ -29,30 +31,11 @@ class Settings extends Component {
constructor (props) {
super(props)
- const { tab } = props
- const activeTab = tab === 'info' ? 'info' : 'settings'
-
this.state = {
- activeTab,
newRpc: '',
}
}
- renderTabs () {
- const { activeTab } = this.state
-
- return h('div.settings__tabs', [
- h(TabBar, {
- tabs: [
- { content: 'Settings', key: 'settings' },
- { content: 'Info', key: 'info' },
- ],
- defaultTab: activeTab,
- tabSelected: key => this.setState({ activeTab: key }),
- }),
- ])
- }
-
renderBlockieOptIn () {
const { metamask: { useBlockie }, setUseBlockie } = this.props
@@ -211,7 +194,7 @@ class Settings extends Component {
}
renderSeedWords () {
- const { revealSeedConfirmation } = this.props
+ const { history } = this.props
return (
h('div.settings__content-row', [
@@ -219,10 +202,7 @@ class Settings extends Component {
h('div.settings__content-item', [
h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--red', {
- onClick (event) {
- event.preventDefault()
- revealSeedConfirmation()
- },
+ onClick: () => history.push(REVEAL_SEED_ROUTE),
}, 'Reveal Seed Words'),
]),
]),
@@ -250,7 +230,7 @@ class Settings extends Component {
)
}
- renderSettingsContent () {
+ render () {
const { warning, isMascara } = this.props
return (
@@ -266,120 +246,9 @@ class Settings extends Component {
])
)
}
-
- renderLogo () {
- return (
- h('div.settings__info-logo-wrapper', [
- h('img.settings__info-logo', { src: 'images/info-logo.png' }),
- ])
- )
- }
-
- renderInfoLinks () {
- return (
- h('div.settings__content-item.settings__content-item--without-height', [
- h('div.settings__info-link-header', 'Links'),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', 'Privacy Policy'),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', 'Terms of Use'),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', 'Attributions'),
- ]),
- ]),
- h('hr.settings__info-separator'),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://support.metamask.io',
- target: '_blank',
- }, [
- h('span.settings__info-link', 'Visit our Support Center'),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('span.settings__info-link', 'Visit our web site'),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- target: '_blank',
- href: 'mailto:help@metamask.io?subject=Feedback',
- }, [
- h('span.settings__info-link', 'Email us!'),
- ]),
- ]),
- ])
- )
- }
-
- renderInfoContent () {
- const version = global.platform.getVersion()
-
- return (
- h('div.settings__content', [
- h('div.settings__content-row', [
- h('div.settings__content-item.settings__content-item--without-height', [
- this.renderLogo(),
- h('div.settings__info-item', [
- h('div.settings__info-version-header', 'MetaMask Version'),
- h('div.settings__info-version-number', `${version}`),
- ]),
- h('div.settings__info-item', [
- h(
- 'div.settings__info-about',
- 'MetaMask is designed and built in California.'
- ),
- ]),
- ]),
- this.renderInfoLinks(),
- ]),
- ])
- )
- }
-
- render () {
- const { goHome } = this.props
- const { activeTab } = this.state
-
- return (
- h('.main-container.settings', {}, [
- h('.settings__header', [
- h('div.settings__close-button', {
- onClick: goHome,
- }),
- this.renderTabs(),
- ]),
-
- activeTab === 'settings'
- ? this.renderSettingsContent()
- : this.renderInfoContent(),
- ])
- )
- }
}
Settings.propTypes = {
- tab: PropTypes.string,
metamask: PropTypes.object,
setUseBlockie: PropTypes.func,
setCurrentCurrency: PropTypes.func,
@@ -388,7 +257,7 @@ Settings.propTypes = {
revealSeedConfirmation: PropTypes.func,
setFeatureFlagToBeta: PropTypes.func,
warning: PropTypes.string,
- goHome: PropTypes.func,
+ history: PropTypes.object,
isMascara: PropTypes.bool,
}
@@ -402,7 +271,6 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- goHome: () => dispatch(actions.goHome()),
setCurrentCurrency: currency => dispatch(actions.setCurrentCurrency(currency)),
setRpcTarget: newRpc => dispatch(actions.setRpcTarget(newRpc)),
displayWarning: warning => dispatch(actions.displayWarning(warning)),
@@ -415,4 +283,7 @@ const mapDispatchToProps = dispatch => {
}
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(Settings)
diff --git a/ui/app/components/pages/signature-request.js b/ui/app/components/pages/signature-request.js
new file mode 100644
index 000000000..0c9f4a091
--- /dev/null
+++ b/ui/app/components/pages/signature-request.js
@@ -0,0 +1,321 @@
+const { Component } = require('react')
+const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
+const Identicon = require('../identicon')
+const { connect } = require('react-redux')
+const ethUtil = require('ethereumjs-util')
+const classnames = require('classnames')
+
+const AccountDropdownMini = require('../dropdowns/account-dropdown-mini')
+
+const actions = require('../../actions')
+const { conversionUtil } = require('../../conversion-util')
+const txHelper = require('../../../lib/tx-helper')
+const { DEFAULT_ROUTE } = require('../../routes')
+
+const {
+ getSelectedAccount,
+ getCurrentAccountWithSendEtherInfo,
+ getSelectedAddress,
+ accountsWithSendEtherInfoSelector,
+ conversionRateSelector,
+} = require('../../selectors.js')
+
+class SignatureRequest extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ selectedAccount: props.selectedAccount,
+ accountDropdownOpen: false,
+ }
+ }
+
+ componentWillMount () {
+ const {
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ if (unapprovedMsgCount + unapprovedPersonalMsgCount + unapprovedTypedMessagesCount < 1) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ renderHeader () {
+ return h('div.request-signature__header', [
+
+ h('div.request-signature__header-background'),
+
+ h('div.request-signature__header__text', 'Signature Request'),
+
+ h('div.request-signature__header__tip-container', [
+ h('div.request-signature__header__tip'),
+ ]),
+
+ ])
+ }
+
+ renderAccountDropdown () {
+ const {
+ selectedAccount,
+ accountDropdownOpen,
+ } = this.state
+
+ const { accounts } = this.props
+
+ return h('div.request-signature__account', [
+
+ h('div.request-signature__account-text', ['Account:']),
+
+ h(AccountDropdownMini, {
+ selectedAccount,
+ accounts,
+ onSelect: selectedAccount => this.setState({ selectedAccount }),
+ dropdownOpen: accountDropdownOpen,
+ openDropdown: () => this.setState({ accountDropdownOpen: true }),
+ closeDropdown: () => this.setState({ accountDropdownOpen: false }),
+ }),
+
+ ])
+ }
+
+ renderBalance () {
+ const { balance, conversionRate } = this.props
+
+ const balanceInEther = conversionUtil(balance, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ return h('div.request-signature__balance', [
+
+ h('div.request-signature__balance-text', ['Balance:']),
+
+ h('div.request-signature__balance-value', `${balanceInEther} ETH`),
+
+ ])
+ }
+
+ renderAccountInfo () {
+ return h('div.request-signature__account-info', [
+
+ this.renderAccountDropdown(),
+
+ this.renderRequestIcon(),
+
+ this.renderBalance(),
+
+ ])
+ }
+
+ renderRequestIcon () {
+ const { requesterAddress } = this.props
+
+ return h('div.request-signature__request-icon', [
+ h(Identicon, {
+ diameter: 40,
+ address: requesterAddress,
+ }),
+ ])
+ }
+
+ renderRequestInfo () {
+ return h('div.request-signature__request-info', [
+
+ h('div.request-signature__headline', [
+ `Your signature is being requested`,
+ ]),
+
+ ])
+ }
+
+ msgHexToText (hex) {
+ try {
+ const stripped = ethUtil.stripHexPrefix(hex)
+ const buff = Buffer.from(stripped, 'hex')
+ return buff.toString('utf8')
+ } catch (e) {
+ return hex
+ }
+ }
+
+ renderBody () {
+ let rows = []
+ let notice = 'You are signing:'
+
+ const { txData = {} } = this.props
+ const { type, msgParams = {} } = txData
+ const { data } = msgParams
+
+ if (type === 'personal_sign') {
+ rows = [{ name: 'Message', value: this.msgHexToText(data) }]
+ } else if (type === 'eth_signTypedData') {
+ rows = data
+ } else if (type === 'eth_sign') {
+ rows = [{ name: 'Message', value: data }]
+ notice = `Signing this message can have
+ dangerous side effects. Only sign messages from
+ sites you fully trust with your entire account.
+ This dangerous method will be removed in a future version. `
+ }
+
+ return h('div.request-signature__body', {}, [
+
+ this.renderAccountInfo(),
+
+ this.renderRequestInfo(),
+
+ h('div.request-signature__notice', {
+ className: classnames({
+ 'request-signature__notice': type === 'personal_sign' || type === 'eth_signTypedData',
+ 'request-signature__warning': type === 'eth_sign',
+ }),
+ }, [notice]),
+
+ h('div.request-signature__rows', [
+
+ ...rows.map(({ name, value }) => {
+ return h('div.request-signature__row', [
+ h('div.request-signature__row-title', [`${name}:`]),
+ h('div.request-signature__row-value', value),
+ ])
+ }),
+
+ ]),
+
+ ])
+ }
+
+ renderFooter () {
+ const {
+ txData = {},
+ signPersonalMessage,
+ signTypedMessage,
+ cancelPersonalMessage,
+ cancelTypedMessage,
+ signMessage,
+ cancelMessage,
+ history,
+ } = this.props
+
+ const { type } = txData
+
+ let cancel = () => Promise.resolve()
+ let sign = () => Promise.resolve()
+ const { msgParams: params = {}, id } = txData
+ params.id = id
+ params.metamaskId = id
+
+ switch (type) {
+ case 'personal_sign':
+ cancel = () => cancelPersonalMessage(params)
+ sign = () => signPersonalMessage(params)
+ break
+ case 'eth_signTypedData':
+ cancel = () => cancelTypedMessage(params)
+ sign = () => signTypedMessage(params)
+ break
+ case 'eth_sign':
+ cancel = () => cancelMessage(params)
+ sign = () => signMessage(params)
+ break
+ }
+
+ return h('div.request-signature__footer', [
+ h('button.request-signature__footer__cancel-button', {
+ onClick: () => {
+ cancel().then(() => history.push(DEFAULT_ROUTE))
+ },
+ }, 'CANCEL'),
+ h('button.request-signature__footer__sign-button', {
+ onClick: () => {
+ sign().then(() => history.push(DEFAULT_ROUTE))
+ },
+ }, 'SIGN'),
+ ])
+ }
+
+ render () {
+ return (
+ h('div.request-signature__container', [
+
+ this.renderHeader(),
+
+ this.renderBody(),
+
+ this.renderFooter(),
+
+ ])
+ )
+ }
+}
+
+SignatureRequest.propTypes = {
+ txData: PropTypes.object,
+ signPersonalMessage: PropTypes.func,
+ cancelPersonalMessage: PropTypes.func,
+ signTypedMessage: PropTypes.func,
+ cancelTypedMessage: PropTypes.func,
+ signMessage: PropTypes.func,
+ cancelMessage: PropTypes.func,
+ requesterAddress: PropTypes.string,
+ accounts: PropTypes.array,
+ conversionRate: PropTypes.number,
+ balance: PropTypes.string,
+ selectedAccount: PropTypes.object,
+ history: PropTypes.object,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+}
+
+const mapStateToProps = state => {
+ const { metamask } = state
+ const {
+ unapprovedTxs,
+ unapprovedMsgs,
+ unapprovedPersonalMsgs,
+ unapprovedTypedMessages,
+ network,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+ const unconfTxList = txHelper(
+ unapprovedTxs,
+ unapprovedMsgs,
+ unapprovedPersonalMsgs,
+ unapprovedTypedMessages,
+ network
+ ) || []
+
+ return {
+ balance: getSelectedAccount(state).balance,
+ selectedAccount: getCurrentAccountWithSendEtherInfo(state),
+ selectedAddress: getSelectedAddress(state),
+ accounts: accountsWithSendEtherInfoSelector(state),
+ conversionRate: conversionRateSelector(state),
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ txData: unconfTxList[0] || {},
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ signPersonalMessage: params => dispatch(actions.signPersonalMsg(params)),
+ cancelPersonalMessage: params => dispatch(actions.cancelPersonalMsg(params)),
+ signTypedMessage: params => dispatch(actions.signTypedMsg(params)),
+ cancelTypedMessage: params => dispatch(actions.cancelTypedMsg(params)),
+ signMessage: params => dispatch(actions.signMsg(params)),
+ cancelMessage: params => dispatch(actions.cancelMsg(params)),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest)
diff --git a/ui/app/components/pages/unlock.js b/ui/app/components/pages/unlock.js
new file mode 100644
index 000000000..3d7a9091c
--- /dev/null
+++ b/ui/app/components/pages/unlock.js
@@ -0,0 +1,175 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { tryUnlockMetamask, forgotPassword, markPasswordForgotten } = require('../../actions')
+const getCaretCoordinates = require('textarea-caret')
+const EventEmitter = require('events').EventEmitter
+const Mascot = require('../mascot')
+const { DEFAULT_ROUTE } = require('../../routes')
+
+class UnlockScreen extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+
+ this.animationEventEmitter = new EventEmitter()
+ }
+
+ componentWillMount () {
+ const { isUnlocked, history } = this.props
+
+ if (isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ tryUnlockMetamask (password) {
+ const { tryUnlockMetamask, history } = this.props
+ tryUnlockMetamask(password)
+ .then(() => history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => this.setState({ error: message }))
+ }
+
+ onSubmit (event) {
+ const input = document.getElementById('password-box')
+ const password = input.value
+ this.tryUnlockMetamask(password)
+ }
+
+ onKeyPress (event) {
+ if (event.key === 'Enter') {
+ this.submitPassword(event)
+ }
+ }
+
+ submitPassword (event) {
+ var element = event.target
+ var password = element.value
+ // reset input
+ element.value = ''
+ this.tryUnlockMetamask(password)
+ }
+
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ const { markPasswordForgotten } = this.props
+
+ return (
+ h('.unlock-page.main-container', [
+ h('.flex-column', {
+ style: {
+ width: 'inherit',
+ },
+ }, [
+ h('.unlock-screen.flex-column.flex-center.flex-grow', [
+
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
+
+ h('h1', {
+ style: {
+ fontSize: '1.4em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ },
+ }, 'MetaMask'),
+
+ h('input.large-input', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'enter password',
+ style: {
+ background: 'white',
+ },
+ onKeyPress: this.onKeyPress.bind(this),
+ onInput: this.inputChanged.bind(this),
+ }),
+
+ h('.error', {
+ style: {
+ display: error ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, error),
+
+ h('button.primary.cursor-pointer', {
+ onClick: this.onSubmit.bind(this),
+ style: {
+ margin: 10,
+ },
+ }, 'Unlock'),
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => {
+ markPasswordForgotten()
+ global.platform.openExtensionInBrowser()
+ },
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'Restore from seed phrase'),
+ ]),
+ ]),
+ ]),
+ ])
+ )
+ }
+}
+
+UnlockScreen.propTypes = {
+ forgotPassword: PropTypes.func,
+ tryUnlockMetamask: PropTypes.func,
+ markPasswordForgotten: PropTypes.func,
+ history: PropTypes.object,
+ isUnlocked: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked } } = state
+ return {
+ isUnlocked,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ forgotPassword: () => dispatch(forgotPassword()),
+ tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)),
+ markPasswordForgotten: () => dispatch(markPasswordForgotten()),
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(UnlockScreen)
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index 652300c94..a2d6adcd0 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -1,5 +1,7 @@
const Component = require('react').Component
const { connect } = require('react-redux')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const h = require('react-hyperscript')
const inherits = require('util').inherits
const actions = require('../../actions')
@@ -11,8 +13,12 @@ const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
const { conversionUtil, addCurrencies } = require('../../conversion-util')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendEther)
function mapStateToProps (state) {
const {
@@ -43,6 +49,7 @@ function mapDispatchToProps (dispatch) {
to,
value: amount,
} = txParams
+
dispatch(actions.updateSend({
gasLimit,
gasPrice,
@@ -52,7 +59,6 @@ function mapDispatchToProps (dispatch) {
errors: { to: null, amount: null },
editingTransactionId: id,
}))
- dispatch(actions.showSendPage())
},
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
}
@@ -177,8 +183,14 @@ ConfirmSendEther.prototype.getData = function () {
}
}
+ConfirmSendEther.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendEther.prototype.render = function () {
- const { editTransaction, currentCurrency, clearSend } = this.props
+ const { currentCurrency, clearSend } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
@@ -220,7 +232,7 @@ ConfirmSendEther.prototype.render = function () {
h('div.confirm-screen-wrapper.flex-column.flex-grow', [
h('h3.flex-center.confirm-screen-header', [
h('button.btn-clear.confirm-screen-back-button', {
- onClick: () => editTransaction(txMeta),
+ onClick: () => this.editTransaction(txMeta),
}, 'EDIT'),
h('div.confirm-screen-title', 'Confirm Transaction'),
h('div.confirm-screen-header-tip'),
@@ -424,6 +436,7 @@ ConfirmSendEther.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendEther.prototype.checkValidity = function () {
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index ad489c3e9..da3a92fa8 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -1,5 +1,7 @@
const Component = require('react').Component
const { connect } = require('react-redux')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const h = require('react-hyperscript')
const inherits = require('util').inherits
const tokenAbi = require('human-standard-token-abi')
@@ -26,8 +28,12 @@ const {
getSelectedAddress,
getSelectedTokenContract,
} = require('../../selectors')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendToken)
function mapStateToProps (state, ownProps) {
const { token: { symbol }, txData } = ownProps
@@ -98,6 +104,12 @@ function ConfirmSendToken () {
this.onSubmit = this.onSubmit.bind(this)
}
+ConfirmSendToken.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendToken.prototype.componentWillMount = function () {
const { tokenContract, selectedAddress } = this.props
tokenContract && tokenContract
@@ -417,6 +429,7 @@ ConfirmSendToken.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendToken.prototype.checkValidity = function () {
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index 1106902b7..b3c73f9b6 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -2,6 +2,8 @@ const connect = require('react-redux').connect
const actions = require('../../actions')
const abi = require('ethereumjs-abi')
const SendEther = require('../../send-v2')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const {
accountsWithSendEtherInfoSelector,
@@ -16,7 +18,10 @@ const {
getSelectedTokenContract,
} = require('../../selectors')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(SendEther)
function mapStateToProps (state) {
const fromAccounts = accountsWithSendEtherInfoSelector(state)
@@ -78,7 +83,6 @@ function mapDispatchToProps (dispatch) {
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
- goHome: () => dispatch(actions.goHome()),
clearSend: () => dispatch(actions.clearSend()),
setMaxModeTo: bool => dispatch(actions.setMaxModeTo(bool)),
}
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
deleted file mode 100644
index c5cc23aa8..000000000
--- a/ui/app/components/signature-request.js
+++ /dev/null
@@ -1,253 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const Identicon = require('./identicon')
-const connect = require('react-redux').connect
-const ethUtil = require('ethereumjs-util')
-const classnames = require('classnames')
-
-const AccountDropdownMini = require('./dropdowns/account-dropdown-mini')
-
-const actions = require('../actions')
-const { conversionUtil } = require('../conversion-util')
-
-const {
- getSelectedAccount,
- getCurrentAccountWithSendEtherInfo,
- getSelectedAddress,
- accountsWithSendEtherInfoSelector,
- conversionRateSelector,
-} = require('../selectors.js')
-
-function mapStateToProps (state) {
- return {
- balance: getSelectedAccount(state).balance,
- selectedAccount: getCurrentAccountWithSendEtherInfo(state),
- selectedAddress: getSelectedAddress(state),
- requester: null,
- requesterAddress: null,
- accounts: accountsWithSendEtherInfoSelector(state),
- conversionRate: conversionRateSelector(state),
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- goHome: () => dispatch(actions.goHome()),
- }
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest)
-
-inherits(SignatureRequest, Component)
-function SignatureRequest (props) {
- Component.call(this)
-
- this.state = {
- selectedAccount: props.selectedAccount,
- accountDropdownOpen: false,
- }
-}
-
-SignatureRequest.prototype.renderHeader = function () {
- return h('div.request-signature__header', [
-
- h('div.request-signature__header-background'),
-
- h('div.request-signature__header__text', 'Signature Request'),
-
- h('div.request-signature__header__tip-container', [
- h('div.request-signature__header__tip'),
- ]),
-
- ])
-}
-
-SignatureRequest.prototype.renderAccountDropdown = function () {
- const {
- selectedAccount,
- accountDropdownOpen,
- } = this.state
-
- const {
- accounts,
- } = this.props
-
- return h('div.request-signature__account', [
-
- h('div.request-signature__account-text', ['Account:']),
-
- h(AccountDropdownMini, {
- selectedAccount,
- accounts,
- onSelect: selectedAccount => this.setState({ selectedAccount }),
- dropdownOpen: accountDropdownOpen,
- openDropdown: () => this.setState({ accountDropdownOpen: true }),
- closeDropdown: () => this.setState({ accountDropdownOpen: false }),
- }),
-
- ])
-}
-
-SignatureRequest.prototype.renderBalance = function () {
- const { balance, conversionRate } = this.props
-
- const balanceInEther = conversionUtil(balance, {
- fromNumericBase: 'hex',
- toNumericBase: 'dec',
- fromDenomination: 'WEI',
- numberOfDecimals: 6,
- conversionRate,
- })
-
- return h('div.request-signature__balance', [
-
- h('div.request-signature__balance-text', ['Balance:']),
-
- h('div.request-signature__balance-value', `${balanceInEther} ETH`),
-
- ])
-}
-
-SignatureRequest.prototype.renderAccountInfo = function () {
- return h('div.request-signature__account-info', [
-
- this.renderAccountDropdown(),
-
- this.renderRequestIcon(),
-
- this.renderBalance(),
-
- ])
-}
-
-SignatureRequest.prototype.renderRequestIcon = function () {
- const { requesterAddress } = this.props
-
- return h('div.request-signature__request-icon', [
- h(Identicon, {
- diameter: 40,
- address: requesterAddress,
- }),
- ])
-}
-
-SignatureRequest.prototype.renderRequestInfo = function () {
- return h('div.request-signature__request-info', [
-
- h('div.request-signature__headline', [
- `Your signature is being requested`,
- ]),
-
- ])
-}
-
-SignatureRequest.prototype.msgHexToText = function (hex) {
- try {
- const stripped = ethUtil.stripHexPrefix(hex)
- const buff = Buffer.from(stripped, 'hex')
- return buff.toString('utf8')
- } catch (e) {
- return hex
- }
-}
-
-SignatureRequest.prototype.renderBody = function () {
- let rows
- let notice = 'You are signing:'
-
- const { txData } = this.props
- const { type, msgParams: { data } } = txData
-
- if (type === 'personal_sign') {
- rows = [{ name: 'Message', value: this.msgHexToText(data) }]
- } else if (type === 'eth_signTypedData') {
- rows = data
- } else if (type === 'eth_sign') {
- rows = [{ name: 'Message', value: data }]
- notice = `Signing this message can have
- dangerous side effects. Only sign messages from
- sites you fully trust with your entire account.
- This dangerous method will be removed in a future version. `
- }
-
- return h('div.request-signature__body', {}, [
-
- this.renderAccountInfo(),
-
- this.renderRequestInfo(),
-
- h('div.request-signature__notice', {
- className: classnames({
- 'request-signature__notice': type === 'personal_sign' || type === 'eth_signTypedData',
- 'request-signature__warning': type === 'eth_sign',
- }),
- }, [notice]),
-
- h('div.request-signature__rows', [
-
- ...rows.map(({ name, value }) => {
- return h('div.request-signature__row', [
- h('div.request-signature__row-title', [`${name}:`]),
- h('div.request-signature__row-value', value),
- ])
- }),
-
- ]),
-
- ])
-}
-
-SignatureRequest.prototype.renderFooter = function () {
- const {
- signPersonalMessage,
- signTypedMessage,
- cancelPersonalMessage,
- cancelTypedMessage,
- signMessage,
- cancelMessage,
- } = this.props
-
- const { txData } = this.props
- const { type } = txData
-
- let cancel
- let sign
- if (type === 'personal_sign') {
- cancel = cancelPersonalMessage
- sign = signPersonalMessage
- } else if (type === 'eth_signTypedData') {
- cancel = cancelTypedMessage
- sign = signTypedMessage
- } else if (type === 'eth_sign') {
- cancel = cancelMessage
- sign = signMessage
- }
-
- return h('div.request-signature__footer', [
- h('button.request-signature__footer__cancel-button', {
- onClick: cancel,
- }, 'CANCEL'),
- h('button.request-signature__footer__sign-button', {
- onClick: sign,
- }, 'SIGN'),
- ])
-}
-
-SignatureRequest.prototype.render = function () {
- return (
-
- h('div.request-signature__container', [
-
- this.renderHeader(),
-
- this.renderBody(),
-
- this.renderFooter(),
-
- ])
-
- )
-
-}
-
diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js
index 0edced119..32c9e4f24 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -4,31 +4,17 @@ const PropTypes = require('react').PropTypes
const classnames = require('classnames')
class TabBar extends Component {
- constructor (props) {
- super(props)
- const { defaultTab, tabs } = props
-
- this.state = {
- subview: defaultTab || tabs[0].key,
- }
- }
-
render () {
- const { tabs = [], tabSelected } = this.props
- const { subview } = this.state
+ const { tabs = [], onSelect, isActive } = this.props
return (
h('.tab-bar', {}, [
- tabs.map((tab) => {
- const { key, content } = tab
+ tabs.map(({ key, content }) => {
return h('div', {
className: classnames('tab-bar__tab pointer', {
- 'tab-bar__tab--active': subview === key,
+ 'tab-bar__tab--active': isActive(key, content),
}),
- onClick: () => {
- this.setState({ subview: key })
- tabSelected(key)
- },
+ onClick: () => onSelect(key),
key,
}, content)
}),
@@ -39,9 +25,9 @@ class TabBar extends Component {
}
TabBar.propTypes = {
- defaultTab: PropTypes.string,
+ isActive: PropTypes.func.isRequired,
tabs: PropTypes.array,
- tabSelected: PropTypes.func,
+ onSelect: PropTypes.func,
}
module.exports = TabBar
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index 84cd0f093..ca4fd81d6 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -10,8 +10,14 @@ const { formatDate } = require('../util')
const { showConfTxPage } = require('../actions')
const classnames = require('classnames')
const { tokenInfoGetter } = require('../token-util')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { CONFIRM_TRANSACTION_ROUTE } = require('../routes')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxList)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxList)
function mapStateToProps (state) {
return {
@@ -91,7 +97,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
transactionHash,
transactionNetworkId,
} = props
- const { showConfTxPage } = this.props
+ const { history } = this.props
const opts = {
key: transActionId || transactionHash,
@@ -109,7 +115,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
const isUnapproved = transactionStatus === 'unapproved'
if (isUnapproved) {
- opts.onClick = () => showConfTxPage({id: transActionId})
+ opts.onClick = () => history.push(CONFIRM_TRANSACTION_ROUTE)
opts.transactionStatus = 'Not Started'
} else if (transactionHash) {
opts.onClick = () => this.view(transactionHash, transactionNetworkId)
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
index b25d8e0f9..60c108c36 100644
--- a/ui/app/components/tx-view.js
+++ b/ui/app/components/tx-view.js
@@ -3,14 +3,20 @@ const connect = require('react-redux').connect
const h = require('react-hyperscript')
const ethUtil = require('ethereumjs-util')
const inherits = require('util').inherits
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('../actions')
const selectors = require('../selectors')
+const { SEND_ROUTE } = require('../routes')
const BalanceComponent = require('./balance-component')
const TxList = require('./tx-list')
const Identicon = require('./identicon')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxView)
function mapStateToProps (state) {
const sidebarOpen = state.appState.sidebarOpen
@@ -63,7 +69,7 @@ TxView.prototype.renderHeroBalance = function () {
}
TxView.prototype.renderButtons = function () {
- const {selectedToken, showModal, showSendPage, showSendTokenPage } = this.props
+ const {selectedToken, showModal, history } = this.props
return !selectedToken
? (
@@ -78,14 +84,14 @@ TxView.prototype.renderButtons = function () {
style: {
marginLeft: '0.8em',
},
- onClick: showSendPage,
+ onClick: () => history.push(SEND_ROUTE),
}, 'SEND'),
])
)
: (
h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-clear.hero-balance-button', {
- onClick: showSendTokenPage,
+ onClick: () => history.push(SEND_ROUTE),
}, 'SEND'),
])
)
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index 34f27ca2a..ce0902a91 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -1,6 +1,8 @@
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const inherits = require('util').inherits
const classnames = require('classnames')
const Identicon = require('./identicon')
@@ -11,8 +13,12 @@ const actions = require('../actions')
const BalanceComponent = require('./balance-component')
const TokenList = require('./token-list')
const selectors = require('../selectors')
+const { ADD_TOKEN_ROUTE } = require('../routes')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(WalletView)
function mapStateToProps (state) {
@@ -91,7 +97,7 @@ WalletView.prototype.render = function () {
keyrings,
showAccountDetailModal,
hideSidebar,
- showAddTokenPage,
+ history,
} = this.props
// temporary logs + fake extra wallets
// console.log('walletview, selectedAccount:', selectedAccount)
@@ -168,10 +174,7 @@ WalletView.prototype.render = function () {
h(TokenList),
h('button.btn-clear.wallet-view__add-token-button', {
- onClick: () => {
- showAddTokenPage()
- hideSidebar()
- },
+ onClick: () => history.push(ADD_TOKEN_ROUTE),
}, 'Add Token'),
])
}
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index b4ffc48b7..9a323e6c2 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -2,28 +2,30 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('./actions')
const txHelper = require('../lib/tx-helper')
const PendingTx = require('./components/pending-tx')
-const SignatureRequest = require('./components/signature-request')
// const PendingMsg = require('./components/pending-msg')
// const PendingPersonalMsg = require('./components/pending-personal-msg')
// const PendingTypedMsg = require('./components/pending-typed-msg')
const Loading = require('./components/loading')
+const { DEFAULT_ROUTE } = require('./routes')
-// const contentDivider = h('div', {
-// style: {
-// marginLeft: '16px',
-// marginRight: '16px',
-// height:'1px',
-// background:'#E7E7E7',
-// },
-// })
-
-module.exports = connect(mapStateToProps)(ConfirmTxScreen)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(ConfirmTxScreen)
function mapStateToProps (state) {
+ const { metamask } = state
+ const {
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ } = metamask
+
return {
identities: state.metamask.identities,
accounts: state.metamask.accounts,
@@ -40,6 +42,9 @@ function mapStateToProps (state) {
currentCurrency: state.metamask.currentCurrency,
blockGasLimit: state.metamask.currentBlockGasLimit,
computedBalances: state.metamask.computedBalances,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ send: state.metamask.send,
}
}
@@ -48,6 +53,23 @@ function ConfirmTxScreen () {
Component.call(this)
}
+ConfirmTxScreen.prototype.componentWillMount = function () {
+ const { unapprovedTxs = {}, send } = this.props
+ const { to } = send
+ if (Object.keys(unapprovedTxs).length === 0 && !to) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+}
+
+ConfirmTxScreen.prototype.componentWillReceiveProps = function (nextProps) {
+ const { send } = this.props
+ const { to } = send
+ const { unapprovedTxs = {} } = nextProps
+ if (Object.keys(unapprovedTxs).length === 0 && !to) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+}
+
ConfirmTxScreen.prototype.render = function () {
const props = this.props
const {
@@ -113,27 +135,13 @@ ConfirmTxScreen.prototype.render = function () {
function currentTxView (opts) {
log.info('rendering current tx view')
const { txData } = opts
- const { txParams, msgParams } = txData
+ const { txParams } = txData
if (txParams) {
log.debug('txParams detected, rendering pending tx')
return h(PendingTx, opts)
- } else if (msgParams) {
- log.debug('msgParams detected, rendering pending msg')
-
- return h(SignatureRequest, opts)
-
- // if (type === 'eth_sign') {
- // log.debug('rendering eth_sign message')
- // return h(PendingMsg, opts)
- // } else if (type === 'personal_sign') {
- // log.debug('rendering personal_sign message')
- // return h(PendingPersonalMsg, opts)
- // } else if (type === 'eth_signTypedData') {
- // log.debug('rendering eth_signTypedData message')
- // return h(PendingTypedMsg, opts)
- // }
}
+
return h(Loading)
}
@@ -145,6 +153,7 @@ ConfirmTxScreen.prototype.buyEth = function (address, event) {
ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
this.stopPropagation(event)
this.props.dispatch(actions.updateAndApproveTx(txData))
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss
index 445c819ff..c068028f8 100644
--- a/ui/app/css/index.scss
+++ b/ui/app/css/index.scss
@@ -6,9 +6,15 @@
*/
@import './itcss/settings/index.scss';
+
@import './itcss/tools/index.scss';
+
@import './itcss/generic/index.scss';
+
@import './itcss/base/index.scss';
+
@import './itcss/objects/index.scss';
+
@import './itcss/components/index.scss';
+
@import './itcss/trumps/index.scss';
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index 0219f9fb2..a1a716b9a 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -52,6 +52,8 @@
@import './editable-label.scss';
+@import './pages/index.scss';
+
@import './new-account.scss';
@import './tooltip.scss';
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index 81f919df3..119d5c479 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -35,13 +35,14 @@
font-size: 18px;
line-height: 24px;
text-align: center;
+ cursor: pointer;
}
&__tab:first-of-type {
margin-right: 20px;
}
- &__unselected:hover {
+ &__tab:hover {
color: $black;
border-bottom: none;
}
@@ -49,9 +50,9 @@
&__selected {
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
+ cursor: initial;
}
}
-
}
.new-account-import-form {
diff --git a/ui/app/css/itcss/components/pages/index.scss b/ui/app/css/itcss/components/pages/index.scss
new file mode 100644
index 000000000..82446fd7a
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/index.scss
@@ -0,0 +1 @@
+@import './unlock.scss';
diff --git a/ui/app/css/itcss/components/pages/unlock.scss b/ui/app/css/itcss/components/pages/unlock.scss
new file mode 100644
index 000000000..5d438377b
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/unlock.scss
@@ -0,0 +1,9 @@
+.unlock-page {
+ box-shadow: none;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background: rgb(247, 247, 247);
+ width: 100%;
+}
diff --git a/ui/app/css/itcss/components/sections.scss b/ui/app/css/itcss/components/sections.scss
index 388aea175..ace46bd8a 100644
--- a/ui/app/css/itcss/components/sections.scss
+++ b/ui/app/css/itcss/components/sections.scss
@@ -17,6 +17,12 @@ textarea.twelve-word-phrase {
resize: none;
}
+.initialize-screen {
+ width: 100%;
+ z-index: $main-container-z-index;
+ background: #f7f7f7;
+}
+
.initialize-screen hr {
width: 60px;
margin: 12px;
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index b4587f1ee..addcedc77 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -1,184 +1,191 @@
-const inherits = require('util').inherits
-const EventEmitter = require('events').EventEmitter
-const Component = require('react').Component
-const connect = require('react-redux').connect
+const { EventEmitter } = require('events')
+const { Component } = require('react')
+const { connect } = require('react-redux')
const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
const Mascot = require('../components/mascot')
const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const getCaretCoordinates = require('textarea-caret')
+const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes')
-let isSubmitting = false
+class InitializeMenuScreen extends Component {
+ constructor (props) {
+ super(props)
-module.exports = connect(mapStateToProps)(InitializeMenuScreen)
-
-inherits(InitializeMenuScreen, Component)
-function InitializeMenuScreen () {
- Component.call(this)
- this.animationEventEmitter = new EventEmitter()
-}
+ this.animationEventEmitter = new EventEmitter()
+ this.state = {
+ warning: null,
+ }
+ }
-function mapStateToProps (state) {
- return {
- // state from plugin
- currentView: state.appState.currentView,
- warning: state.appState.warning,
+ componentWillMount () {
+ const { isInitialized, isUnlocked, history } = this.props
+ if (isInitialized || isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
}
-}
-InitializeMenuScreen.prototype.render = function () {
- var state = this.props
+ componentDidMount () {
+ document.getElementById('password-box').focus()
+ }
- switch (state.currentView.name) {
+ render () {
+ const { history } = this.props
+ const { warning } = this.state
- default:
- return this.renderMenu(state)
+ return (
+ h('.initialize-screen.flex-column.flex-center', [
- }
-}
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
-// InitializeMenuScreen.prototype.componentDidMount = function(){
-// document.getElementById('password-box').focus()
-// }
+ h('h1', {
+ style: {
+ fontSize: '1.3em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ marginBottom: 10,
+ },
+ }, 'MetaMask'),
-InitializeMenuScreen.prototype.renderMenu = function (state) {
- return (
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
+ h('div', [
+ h('h3', {
+ style: {
+ fontSize: '0.8em',
+ color: '#7F8082',
+ display: 'inline',
+ },
+ }, 'Encrypt your new DEN'),
+
+ h(Tooltip, {
+ title: 'Your DEN is your password-encrypted storage within MetaMask.',
+ }, [
+ h('i.fa.fa-question-circle.pointer', {
+ style: {
+ fontSize: '18px',
+ position: 'relative',
+ color: 'rgb(247, 134, 28)',
+ top: '2px',
+ marginLeft: '4px',
+ },
+ }),
+ ]),
+ ]),
- h(Mascot, {
- animationEventEmitter: this.animationEventEmitter,
- }),
+ h('span.error.in-progress-notification', warning),
- h('h1', {
- style: {
- fontSize: '1.3em',
- textTransform: 'uppercase',
- color: '#7F8082',
- marginBottom: 10,
- },
- }, 'MetaMask'),
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'New Password (min 8 chars)',
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: 'Confirm Password',
+ onKeyPress: this.createVaultOnEnter.bind(this),
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
- h('div', [
- h('h3', {
+ h('button.primary', {
+ onClick: this.createNewVaultAndKeychain.bind(this),
style: {
- fontSize: '0.8em',
- color: '#7F8082',
- display: 'inline',
+ margin: 12,
},
- }, 'Encrypt your new DEN'),
+ }, 'Create'),
- h(Tooltip, {
- title: 'Your DEN is your password-encrypted storage within MetaMask.',
- }, [
- h('i.fa.fa-question-circle.pointer', {
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => history.push(RESTORE_VAULT_ROUTE),
style: {
- fontSize: '18px',
- position: 'relative',
+ fontSize: '0.8em',
color: 'rgb(247, 134, 28)',
- top: '2px',
- marginLeft: '4px',
+ textDecoration: 'underline',
},
- }),
+ }, 'Import Existing DEN'),
]),
- ]),
-
- h('span.in-progress-notification', state.warning),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'New Password (min 8 chars)',
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: 'Confirm Password',
- onKeyPress: this.createVaultOnEnter.bind(this),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
-
- h('button.primary', {
- onClick: this.createNewVaultAndKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Create'),
-
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showRestoreVault.bind(this),
- style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
- },
- }, 'Import Existing DEN'),
- ]),
- ])
- )
-}
+ ])
+ )
+ }
-InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewVaultAndKeychain()
+ createVaultOnEnter (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewVaultAndKeychain()
+ }
}
-}
-InitializeMenuScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
+ createNewVaultAndKeychain () {
+ const { history } = this.props
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ this.setState({ warning: null })
+
+ if (password.length < 8) {
+ this.setState({ warning: 'password not long enough' })
+ return
+ }
+ if (password !== passwordConfirm) {
+ this.setState({ warning: 'passwords don\'t match' })
+ return
+ }
+
+ this.props.createNewVaultAndKeychain(password)
+ .then(() => history.push(DEFAULT_ROUTE))
+ }
+
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
}
-InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.showRestoreVault())
+InitializeMenuScreen.propTypes = {
+ history: PropTypes.object,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ createNewVaultAndKeychain: PropTypes.func,
}
-InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
+const mapStateToProps = state => {
+ const { metamask: { isInitialized, isUnlocked } } = state
- if (password.length < 8) {
- this.warning = 'password not long enough'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- if (password !== passwordConfirm) {
- this.warning = 'passwords don\'t match'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
+ return {
+ isInitialized,
+ isUnlocked,
}
+}
- if (!isSubmitting) {
- isSubmitting = true
- this.props.dispatch(actions.createNewVaultAndKeychain(password))
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndKeychain: password => dispatch(actions.createNewVaultAndKeychain(password)),
}
}
-InitializeMenuScreen.prototype.inputChanged = function (event) {
- // tell mascot to look at page action
- var element = event.target
- var boundingRect = element.getBoundingClientRect()
- var coordinates = getCaretCoordinates(element, element.selectionEnd)
- this.animationEventEmitter.emit('point', {
- x: boundingRect.left + coordinates.left - element.scrollLeft,
- y: boundingRect.top + coordinates.top - element.scrollTop,
- })
-}
+module.exports = connect(mapStateToProps, mapDispatchToProps)(InitializeMenuScreen)
diff --git a/ui/app/info.js b/ui/app/info.js
index 49ff9f24a..17e1ecbb4 100644
--- a/ui/app/info.js
+++ b/ui/app/info.js
@@ -2,7 +2,6 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('./actions')
module.exports = connect(mapStateToProps)(InfoScreen)
@@ -15,134 +14,91 @@ function InfoScreen () {
Component.call(this)
}
-InfoScreen.prototype.render = function () {
- const state = this.props
- const version = global.platform.getVersion()
-
+InfoScreen.prototype.renderLogo = function () {
return (
- h('.flex-column.flex-grow', {
- style: {
- maxWidth: '400px',
- },
- }, [
+ h('div.settings__info-logo-wrapper', [
+ h('img.settings__info-logo', { src: 'images/info-logo.png' }),
+ ])
+ )
+}
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- state.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Info'),
+InfoScreen.prototype.renderInfoLinks = function () {
+ return (
+ h('div.settings__content-item.settings__content-item--without-height', [
+ h('div.settings__info-link-header', 'Links'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Privacy Policy'),
+ ]),
]),
-
- // main view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
}, [
- // current version number
-
- h('.info.info-gray', [
- h('div', 'Metamask'),
- h('div', {
- style: {
- marginBottom: '10px',
- },
- }, `Version: ${version}`),
- ]),
-
- h('div', {
- style: {
- marginBottom: '5px',
- }},
- [
- h('div', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Privacy Policy'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Terms of Use'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Attributions'),
- ]),
- ]),
- ]
- ),
-
- h('hr', {
- style: {
- margin: '10px 0 ',
- width: '7em',
- },
- }),
-
- h('div', {
- style: {
- paddingLeft: '30px',
- }},
- [
- h('div.fa.fa-support', [
- h('a.info', {
- href: 'https://metamask.helpscoutdocs.com/',
- target: '_blank',
- }, 'Visit our Knowledge Base'),
- ]),
-
- h('div', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('img.icon-size', {
- src: 'images/icon-128.png',
- style: {
- // IE6-9
- filter: 'grayscale(100%)',
- // Microsoft Edge and Firefox 35+
- WebkitFilter: 'grayscale(100%)',
- },
- }),
- h('div.info', 'Visit our web site'),
- ]),
- ]),
+ h('span.settings__info-link', 'Terms of Use'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Attributions'),
+ ]),
+ ]),
+ h('hr.settings__info-separator'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our Support Center'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our web site'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ target: '_blank',
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, [
+ h('span.settings__info-link', 'Email us!'),
+ ]),
+ ]),
+ ])
+ )
+}
- h('div', [
- h('.fa.fa-twitter', [
- h('a.info', {
- href: 'https://twitter.com/metamask_io',
- target: '_blank',
- }, 'Follow us on Twitter'),
- ]),
- ]),
+InfoScreen.prototype.render = function () {
+ const version = global.platform.getVersion()
- h('div.fa.fa-envelope', [
- h('a.info', {
- target: '_blank',
- href: 'mailto:support@metamask.io?subject=MetaMask Support',
- }, 'Email us!'),
- ]),
- ]),
+ return (
+ h('div.settings__content', [
+ h('div.settings__content-row', [
+ h('div.settings__content-item.settings__content-item--without-height', [
+ this.renderLogo(),
+ h('div.settings__info-item', [
+ h('div.settings__info-version-header', 'MetaMask Version'),
+ h('div.settings__info-version-number', `${version}`),
+ ]),
+ h('div.settings__info-item', [
+ h(
+ 'div.settings__info-about',
+ 'MetaMask is designed and built in California.'
+ ),
+ ]),
]),
+ this.renderInfoLinks(),
]),
])
)
diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js
deleted file mode 100644
index 5ab5d4c33..000000000
--- a/ui/app/keychains/hd/create-vault-complete.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../actions')
-const exportAsFile = require('../../util').exportAsFile
-
-module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
-
-inherits(CreateVaultCompleteScreen, Component)
-function CreateVaultCompleteScreen () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- seed: state.appState.currentView.seedWords,
- cachedSeed: state.metamask.seedWords,
- }
-}
-
-CreateVaultCompleteScreen.prototype.render = function () {
- var state = this.props
- var seed = state.seed || state.cachedSeed || ''
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- // // subtitle and nav
- // h('.section-title.flex-row.flex-center', [
- // h('h2.page-subtitle', 'Vault Created'),
- // ]),
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: 36,
- marginBottom: 8,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Vault Created',
- ]),
-
- h('div', {
- style: {
- fontSize: '1em',
- marginTop: '10px',
- textAlign: 'center',
- },
- }, [
- h('span.error', 'These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret.'),
- ]),
-
- h('textarea.twelve-word-phrase', {
- readOnly: true,
- value: seed,
- }),
-
- h('button.primary', {
- onClick: () => this.confirmSeedWords()
- .then(account => this.showAccountDetail(account)),
- style: {
- margin: '24px',
- fontSize: '0.9em',
- marginBottom: '10px',
- },
- }, 'I\'ve copied it somewhere safe'),
-
- h('button.primary', {
- onClick: () => exportAsFile(`MetaMask Seed Words`, seed),
- style: {
- margin: '10px',
- fontSize: '0.9em',
- },
- }, 'Save Seed Words As File'),
- ])
- )
-}
-
-CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
- return this.props.dispatch(actions.confirmSeedWords())
-}
-
-CreateVaultCompleteScreen.prototype.showAccountDetail = function (account) {
- return this.props.dispatch(actions.showAccountDetail(account))
-}
diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js
deleted file mode 100644
index 4335186a5..000000000
--- a/ui/app/keychains/hd/recover-seed/confirmation.js
+++ /dev/null
@@ -1,121 +0,0 @@
-const inherits = require('util').inherits
-
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../../actions')
-
-module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
-
-inherits(RevealSeedConfirmation, Component)
-function RevealSeedConfirmation () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-RevealSeedConfirmation.prototype.render = function () {
- const props = this.props
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', {
- style: { maxWidth: '420px' },
- }, [
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Reveal Seed Words',
- ]),
-
- h('.div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- padding: '20px',
- justifyContent: 'center',
- },
- }, [
-
- h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
-
- // confirmation
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'Enter your password to confirm',
- onKeyPress: this.checkConfirmation.bind(this),
- style: {
- width: 260,
- marginTop: '12px',
- },
- }),
-
- h('.flex-row.flex-start', {
- style: {
- marginTop: 30,
- width: '50%',
- },
- }, [
- // cancel
- h('button.primary', {
- onClick: this.goHome.bind(this),
- }, 'CANCEL'),
-
- // submit
- h('button.primary', {
- style: { marginLeft: '10px' },
- onClick: this.revealSeedWords.bind(this),
- }, 'OK'),
-
- ]),
-
- (props.warning) && (
- h('span.error', {
- style: {
- margin: '20px',
- },
- }, props.warning.split('-'))
- ),
-
- props.inProgress && (
- h('span.in-progress-notification', 'Generating Seed...')
- ),
- ]),
- ])
- )
-}
-
-RevealSeedConfirmation.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-RevealSeedConfirmation.prototype.goHome = function () {
- this.props.dispatch(actions.showConfigPage(false))
-}
-
-// create vault
-
-RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.revealSeedWords()
- }
-}
-
-RevealSeedConfirmation.prototype.revealSeedWords = function () {
- var password = document.getElementById('password-box').value
- this.props.dispatch(actions.requestRevealSeed(password))
-}
diff --git a/ui/app/main-container.js b/ui/app/main-container.js
index 292abcc3d..4fea3a6d1 100644
--- a/ui/app/main-container.js
+++ b/ui/app/main-container.js
@@ -2,8 +2,8 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountAndTransactionDetails = require('./account-and-transaction-details')
-const Settings = require('./settings')
-const UnlockScreen = require('./unlock')
+const Settings = require('./components/pages/settings')
+const UnlockScreen = require('./components/pages/unlock')
module.exports = MainContainer
diff --git a/ui/app/root.js b/ui/app/root.js
index 21d6d1829..09deae1b1 100644
--- a/ui/app/root.js
+++ b/ui/app/root.js
@@ -1,22 +1,23 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const Provider = require('react-redux').Provider
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const { Provider } = require('react-redux')
const h = require('react-hyperscript')
const SelectedApp = require('./select-app')
-module.exports = Root
-
-inherits(Root, Component)
-function Root () { Component.call(this) }
-
-Root.prototype.render = function () {
- return (
+class Root extends Component {
+ render () {
+ const { store } = this.props
- h(Provider, {
- store: this.props.store,
- }, [
- h(SelectedApp),
- ])
+ return (
+ h(Provider, { store }, [
+ h(SelectedApp),
+ ])
+ )
+ }
+}
- )
+Root.propTypes = {
+ store: PropTypes.object,
}
+
+module.exports = Root
diff --git a/ui/app/routes.js b/ui/app/routes.js
new file mode 100644
index 000000000..8b4501fe3
--- /dev/null
+++ b/ui/app/routes.js
@@ -0,0 +1,33 @@
+const DEFAULT_ROUTE = '/'
+const UNLOCK_ROUTE = '/unlock'
+const SETTINGS_ROUTE = '/settings'
+const INFO_ROUTE = '/settings/info'
+const REVEAL_SEED_ROUTE = '/seed'
+const CONFIRM_SEED_ROUTE = '/confirm-seed'
+const RESTORE_VAULT_ROUTE = '/restore-vault'
+const ADD_TOKEN_ROUTE = '/add-token'
+const NEW_ACCOUNT_ROUTE = '/new-account'
+const IMPORT_ACCOUNT_ROUTE = '/new-account/import'
+const SEND_ROUTE = '/send'
+const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction'
+const INITIALIZE_ROUTE = '/initialize'
+const NOTICE_ROUTE = '/notice'
+const SIGNATURE_REQUEST_ROUTE = '/signature-request'
+
+module.exports = {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ REVEAL_SEED_ROUTE,
+ CONFIRM_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ INITIALIZE_ROUTE,
+ NOTICE_ROUTE,
+ SIGNATURE_REQUEST_ROUTE,
+}
diff --git a/ui/app/select-app.js b/ui/app/select-app.js
index 193c98353..c6ef1abda 100644
--- a/ui/app/select-app.js
+++ b/ui/app/select-app.js
@@ -2,6 +2,7 @@ const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { HashRouter } = require('react-router-dom')
const App = require('./app')
const OldApp = require('../../old-ui/app/app')
const { autoAddToBetaUI } = require('./selectors')
@@ -62,7 +63,12 @@ SelectedApp.prototype.render = function () {
// const Selected = betaUI || isMascara || firstTime ? App : OldApp
const { betaUI, isMascara } = this.props
- const Selected = betaUI || isMascara ? App : OldApp
- return h(Selected)
+ return betaUI || isMascara
+ ? h(HashRouter, {
+ hashType: 'noslash',
+ }, [
+ h(App),
+ ])
+ : h(OldApp)
}
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index d4e15dfa8..4230e8a22 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -28,6 +28,7 @@ const {
isTokenBalanceSufficient,
} = require('./components/send/send-utils')
const { isValidAddress } = require('./util')
+const { CONFIRM_TRANSACTION_ROUTE } = require('./routes')
module.exports = SendTransactionScreen
@@ -485,10 +486,10 @@ SendTransactionScreen.prototype.renderForm = function () {
SendTransactionScreen.prototype.renderFooter = function () {
const {
- goHome,
clearSend,
gasTotal,
errors: { amount: amountError, to: toError },
+ history,
} = this.props
const noErrors = !amountError && toError === null
@@ -497,7 +498,7 @@ SendTransactionScreen.prototype.renderFooter = function () {
h('button.btn-cancel.page-container__footer-button', {
onClick: () => {
clearSend()
- goHome()
+ history.goBack()
},
}, 'Cancel'),
h('button.btn-clear.page-container__footer-button', {
@@ -575,7 +576,7 @@ SendTransactionScreen.prototype.getEditedTx = function () {
SendTransactionScreen.prototype.onSubmit = function (event) {
event.preventDefault()
const {
- from: {address: from},
+ from: { address: from },
to,
amount,
gasLimit: gas,
@@ -598,7 +599,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
if (editingTransactionId) {
const editedTx = this.getEditedTx()
-
updateTx(editedTx)
} else {
@@ -618,4 +618,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
? signTokenTx(selectedToken.address, to, amount, txParams)
: signTx(txParams)
}
+
+ this.props.history.push(CONFIRM_TRANSACTION_ROUTE)
}
diff --git a/yarn.lock b/yarn.lock
index a24806923..78bf2ac58 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,59 +2,64 @@
# yarn lockfile v1
-"@babel/code-frame@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz#473d021ecc573a2cce1c07d5b509d5215f46ba35"
+"@babel/code-frame@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz#2349d7ec04b3a06945ae173280ef8579b63728e4"
dependencies:
chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
-"@babel/helper-function-name@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz#afe63ad799209989348b1109b44feb66aa245f57"
+"@babel/helper-function-name@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz#366e3bc35147721b69009f803907c4d53212e88d"
dependencies:
- "@babel/helper-get-function-arity" "7.0.0-beta.31"
- "@babel/template" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
+ "@babel/helper-get-function-arity" "7.0.0-beta.36"
+ "@babel/template" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
-"@babel/helper-get-function-arity@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz#1176d79252741218e0aec872ada07efb2b37a493"
+"@babel/helper-get-function-arity@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz#f5383bac9a96b274828b10d98900e84ee43e32b8"
dependencies:
- "@babel/types" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.36"
-"@babel/template@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
+"@babel/template@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.36.tgz#02e903de5d68bd7899bce3c5b5447e59529abb00"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
lodash "^4.2.0"
-"@babel/traverse@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.31.tgz#db399499ad74aefda014f0c10321ab255134b1df"
+"@babel/traverse@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.36.tgz#1dc6f8750e89b6b979de5fe44aa993b1a2192261"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/helper-function-name" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/helper-function-name" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
debug "^3.0.1"
- globals "^10.0.0"
+ globals "^11.1.0"
invariant "^2.2.0"
lodash "^4.2.0"
-"@babel/types@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.31.tgz#42c9c86784f674c173fb21882ca9643334029de4"
+"@babel/types@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.36.tgz#64f2004353de42adb72f9ebb4665fc35b5499d23"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^2.0.0"
+"@browserify/acorn5-object-spread@^5.0.1":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz#92e9b37f97beac9ec429a3cc479ded380297540c"
+ dependencies:
+ acorn "^5.2.1"
+
"@gulp-sourcemaps/identity-map@1.X":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1"
@@ -73,8 +78,8 @@
through2 "^2.0.3"
"@types/node@*":
- version "8.5.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
+ version "8.0.53"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
JSONStream@^0.8.4:
version "0.8.4"
@@ -90,7 +95,7 @@ JSONStream@^1.0.3:
jsonparse "^1.2.0"
through ">=2.2.7 <3"
-abab@^1.0.3:
+abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -143,7 +148,7 @@ acorn-dynamic-import@^2.0.0:
dependencies:
acorn "^4.0.3"
-acorn-globals@^4.0.0:
+acorn-globals@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538"
dependencies:
@@ -155,7 +160,7 @@ acorn-jsx@^3.0.0:
dependencies:
acorn "^3.0.4"
-acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.2, acorn@^5.2.1:
+acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
@@ -495,8 +500,8 @@ assert@^1.1.1, assert@^1.4.0:
util "0.10.3"
assertion-error@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
assign-symbols@^1.0.0:
version "1.0.0"
@@ -513,8 +518,8 @@ astw@^2.0.0:
acorn "^4.0.3"
async-done@^1.2.0, async-done@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.3.tgz#6c7abc7d61ca27fe6f1f2ba3206ea9ae60a43983"
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.4.tgz#17b0fcefb9a33cb9de63daa8904c0a65bd535fa0"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.2"
@@ -541,6 +546,10 @@ async-foreach@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
+async-limiter@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
+
async-reduce@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/async-reduce/-/async-reduce-0.0.1.tgz#b236b5f376d6fae381cded9006aa7f2c73b17f31"
@@ -597,14 +606,14 @@ autoprefixer@^6.0.0:
postcss-value-parser "^3.2.3"
autoprefixer@^7.0.0, autoprefixer@^7.1.2:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.3.tgz#c2841e38b7940c2d0a9bbffd72c75f33637854f8"
+ version "7.2.5"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.5.tgz#04ccbd0c6a61131b6d13f53d371926092952d192"
dependencies:
- browserslist "^2.10.0"
- caniuse-lite "^1.0.30000783"
+ browserslist "^2.11.1"
+ caniuse-lite "^1.0.30000791"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
- postcss "^6.0.14"
+ postcss "^6.0.16"
postcss-value-parser "^3.2.3"
await-semaphore@^0.1.1:
@@ -656,13 +665,13 @@ babel-core@^6.0.14, babel-core@^6.23.1, babel-core@^6.24.1, babel-core@^6.26.0:
source-map "^0.5.6"
babel-eslint@^8.0.0:
- version "8.1.2"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.1.2.tgz#a39230b0c20ecbaa19a35d5633bf9b9ca2c8116f"
+ version "8.2.1"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.1.tgz#136888f3c109edc65376c23ebf494f36a3e03951"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/traverse" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
eslint-scope "~3.7.1"
eslint-visitor-keys "^1.0.0"
@@ -1230,7 +1239,7 @@ babel-preset-env@^1.3.2:
invariant "^2.2.2"
semver "^5.3.0"
-babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.24.0, babel-preset-es2015@^6.6.0:
+babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.6.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
dependencies:
@@ -1374,9 +1383,9 @@ babelify@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3"
-babylon@7.0.0-beta.31:
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f"
+babylon@7.0.0-beta.36:
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.36.tgz#3a3683ba6a9a1e02b0aa507c8e63435e39305b9e"
babylon@^6.18.0:
version "6.18.0"
@@ -1522,8 +1531,8 @@ bindings@^1.2.1:
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
bip39@^2.2.0, bip39@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.4.0.tgz#a0b8adbf163f53495f00f05d9ede7c25369ccf13"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235"
dependencies:
create-hash "^1.1.0"
pbkdf2 "^3.0.9"
@@ -1684,12 +1693,13 @@ browser-pack@^5.0.1:
umd "^3.0.0"
browser-pack@^6.0.1:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531"
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.3.tgz#91ca96518583ef580ab063a309de62e407767a39"
dependencies:
JSONStream "^1.0.3"
- combine-source-map "~0.7.1"
+ combine-source-map "~0.8.0"
defined "^1.0.0"
+ safe-buffer "^5.1.1"
through2 "^2.0.0"
umd "^3.0.0"
@@ -1791,7 +1801,7 @@ browserify-zlib@^0.2.0, browserify-zlib@~0.2.0:
dependencies:
pako "~1.0.5"
-browserify@^14.0.0, browserify@^14.4.0:
+browserify@^14.4.0:
version "14.5.0"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5"
dependencies:
@@ -1843,6 +1853,59 @@ browserify@^14.0.0, browserify@^14.4.0:
vm-browserify "~0.0.1"
xtend "^4.0.0"
+browserify@^15.2.0:
+ version "15.2.0"
+ resolved "https://registry.yarnpkg.com/browserify/-/browserify-15.2.0.tgz#1e121ba1fa72cf9fd2d8df002f8674b68b45df89"
+ dependencies:
+ JSONStream "^1.0.3"
+ assert "^1.4.0"
+ browser-pack "^6.0.1"
+ browser-resolve "^1.11.0"
+ browserify-zlib "~0.2.0"
+ buffer "^5.0.2"
+ cached-path-relative "^1.0.0"
+ concat-stream "~1.5.1"
+ console-browserify "^1.1.0"
+ constants-browserify "~1.0.0"
+ crypto-browserify "^3.0.0"
+ defined "^1.0.0"
+ deps-sort "^2.0.0"
+ domain-browser "~1.1.0"
+ duplexer2 "~0.1.2"
+ events "~1.1.0"
+ glob "^7.1.0"
+ has "^1.0.0"
+ htmlescape "^1.1.0"
+ https-browserify "^1.0.0"
+ inherits "~2.0.1"
+ insert-module-globals "^7.0.0"
+ labeled-stream-splicer "^2.0.0"
+ mkdirp "^0.5.0"
+ module-deps "^5.0.1"
+ os-browserify "~0.3.0"
+ parents "^1.0.1"
+ path-browserify "~0.0.0"
+ process "~0.11.0"
+ punycode "^1.3.2"
+ querystring-es3 "~0.2.0"
+ read-only-stream "^2.0.0"
+ readable-stream "^2.0.2"
+ resolve "^1.1.4"
+ shasum "^1.0.0"
+ shell-quote "^1.6.1"
+ stream-browserify "^2.0.0"
+ stream-http "^2.0.0"
+ string_decoder "~1.0.0"
+ subarg "^1.0.0"
+ syntax-error "^1.1.1"
+ through2 "^2.0.0"
+ timers-browserify "^1.0.1"
+ tty-browserify "~0.0.0"
+ url "~0.11.0"
+ util "~0.10.1"
+ vm-browserify "~0.0.1"
+ xtend "^4.0.0"
+
browserslist@^1.1.1, browserslist@^1.1.3, browserslist@^1.7.6:
version "1.7.7"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
@@ -1850,12 +1913,12 @@ browserslist@^1.1.1, browserslist@^1.1.3, browserslist@^1.7.6:
caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7"
-browserslist@^2.1.2, browserslist@^2.10.0:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346"
+browserslist@^2.1.2, browserslist@^2.11.1:
+ version "2.11.3"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2"
dependencies:
- caniuse-lite "^1.0.30000780"
- electron-to-chromium "^1.3.28"
+ caniuse-lite "^1.0.30000792"
+ electron-to-chromium "^1.3.30"
bs58@^2.0.1:
version "2.0.1"
@@ -2001,12 +2064,12 @@ camelcase@^4.1.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000784.tgz#1be95012d9489c7719074f81aee57dbdffe6361b"
+ version "1.0.30000798"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000798.tgz#92f26f77f89cc2a4d60487f41e0b3d2a6c3fe341"
-caniuse-lite@^1.0.30000780, caniuse-lite@^1.0.30000783:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0"
+caniuse-lite@^1.0.30000791, caniuse-lite@^1.0.30000792:
+ version "1.0.30000792"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz#d0cea981f8118f3961471afbb43c9a1e5bbf0332"
caseless@~0.11.0:
version "0.11.0"
@@ -2171,13 +2234,12 @@ circular-json@^0.3.1:
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
class-utils@^0.3.5:
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.5.tgz#17e793103750f9627b2176ea34cfd1b565903c80"
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
dependencies:
arr-union "^3.1.0"
define-property "^0.2.5"
isobject "^3.0.0"
- lazy-cache "^2.0.2"
static-extend "^0.1.1"
classnames@^2.2.4, classnames@^2.2.5:
@@ -2214,6 +2276,14 @@ cliui@^3.0.3, cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+cliui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
+ dependencies:
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+ wrap-ansi "^2.0.0"
+
clone-buffer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
@@ -2366,6 +2436,15 @@ combine-source-map@~0.7.1:
lodash.memoize "~3.0.3"
source-map "~0.5.3"
+combine-source-map@~0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b"
+ dependencies:
+ convert-source-map "~1.1.0"
+ inline-source-map "~0.6.0"
+ lodash.memoize "~3.0.3"
+ source-map "~0.5.3"
+
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -2382,11 +2461,7 @@ commander@2.9.0:
dependencies:
graceful-readlink ">= 1.0.0"
-commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.12.1:
- version "2.12.2"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
-
-commander@~2.13.0:
+commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
@@ -2506,7 +2581,7 @@ content-disposition@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
-content-type-parser@^1.0.1:
+content-type-parser@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
@@ -2964,10 +3039,14 @@ delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-depd@1.1.1, depd@~1.1.0, depd@~1.1.1:
+depd@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+depd@~1.1.0, depd@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+
deps-sort@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5"
@@ -3041,6 +3120,14 @@ detective@^4.0.0, detective@^4.3.1:
acorn "^5.2.1"
defined "^1.0.0"
+detective@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/detective/-/detective-5.0.2.tgz#84ec2e1c581e74211e2ae4ffce1edf52c3263f84"
+ dependencies:
+ "@browserify/acorn5-object-spread" "^5.0.1"
+ acorn "^5.2.1"
+ defined "^1.0.0"
+
di@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
@@ -3107,9 +3194,9 @@ dnode@^1.2.2:
optionalDependencies:
weak "^1.0.0"
-doctrine@^2.0.0, doctrine@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
+doctrine@^2.0.2, doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
dependencies:
esutils "^2.0.2"
@@ -3154,7 +3241,11 @@ dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
-domain-browser@^1.1.1, domain-browser@~1.1.0:
+domain-browser@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+
+domain-browser@~1.1.0:
version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
@@ -3167,8 +3258,10 @@ domelementtype@~1.1.1:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
domexception@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.0.tgz#81fe5df81b3f057052cde3a9fa9bf536a85b9ab0"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ dependencies:
+ webidl-conversions "^4.0.2"
domhandler@^2.3.0:
version "2.4.1"
@@ -3224,9 +3317,9 @@ duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
-duplexify@^3.1.2, duplexify@^3.4.2, duplexify@^3.5.0:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd"
+duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.5.3:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e"
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
@@ -3260,15 +3353,9 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-releases@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e"
-
-electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.28:
- version "1.3.30"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80"
- dependencies:
- electron-releases "^2.1.0"
+electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30:
+ version "1.3.31"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz#00d832cba9fe2358652b0c48a8816c8e3a037e9f"
elliptic@^6.0.0, elliptic@^6.2.3:
version "6.4.0"
@@ -3287,8 +3374,8 @@ emojis-list@^2.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
encodeurl@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
encoding@^0.1.11:
version "0.1.12"
@@ -3297,8 +3384,8 @@ encoding@^0.1.11:
iconv-lite "~0.4.13"
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
dependencies:
once "^1.4.0"
@@ -3425,12 +3512,12 @@ enzyme-adapter-react-15@^1.0.5:
prop-types "^15.5.10"
enzyme-adapter-utils@^1.1.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.2.0.tgz#7f4471ee0a70b91169ec8860d2bf0a6b551664b2"
dependencies:
lodash "^4.17.4"
object.assign "^4.0.4"
- prop-types "^15.6.0"
+ prop-types "^15.5.10"
enzyme@^3.2.0:
version "3.3.0"
@@ -3484,13 +3571,13 @@ es-to-primitive@^1.1.1:
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
- version "0.10.37"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
+ version "0.10.38"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3"
dependencies:
- es6-iterator "~2.0.1"
+ es6-iterator "~2.0.3"
es6-symbol "~3.1.1"
-es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
dependencies:
@@ -3593,12 +3680,12 @@ eslint-plugin-mocha@^4.9.0:
ramda "^0.24.1"
eslint-plugin-react@^7.4.0:
- version "7.5.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b"
+ version "7.6.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.6.1.tgz#5d0e908be599f0c02fbf4eef0c7ed6f29dff7633"
dependencies:
- doctrine "^2.0.0"
+ doctrine "^2.0.2"
has "^1.0.1"
- jsx-ast-utils "^2.0.0"
+ jsx-ast-utils "^2.0.1"
prop-types "^15.6.0"
eslint-scope@^3.7.1, eslint-scope@~3.7.1:
@@ -3613,8 +3700,8 @@ eslint-visitor-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^4.0.0, eslint@^4.2.0:
- version "4.14.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82"
+ version "4.16.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.16.0.tgz#934ada9e98715e1d7bbfd6f6f0519ed2fab35cc1"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
@@ -3622,7 +3709,7 @@ eslint@^4.0.0, eslint@^4.2.0:
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.1.0"
- doctrine "^2.0.2"
+ doctrine "^2.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
espree "^3.5.2"
@@ -3761,8 +3848,8 @@ eth-block-tracker@^2.3.0:
tape "^4.6.3"
eth-contract-metadata@^1.1.5:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.3.0.tgz#caf3cdc3d69995b6d7532c9d96fedbad46361ca8"
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.5.0.tgz#97fbbfe588b66b55f2830dae0fa0ccdb40280128"
eth-ens-namehash@^1.0.2:
version "1.0.2"
@@ -3771,17 +3858,7 @@ eth-ens-namehash@^1.0.2:
idna-uts46 "^1.0.1"
js-sha3 "^0.5.7"
-eth-hd-keyring@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.1.tgz#15ab3919b4153a8497e14673e8e8039e5965131c"
- dependencies:
- bip39 "^2.2.0"
- eth-sig-util "^1.3.0"
- ethereumjs-util "^5.1.1"
- ethereumjs-wallet "^0.6.0"
- events "^1.1.1"
-
-eth-hd-keyring@^1.2.2:
+eth-hd-keyring@^1.2.1, eth-hd-keyring@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz#ad5f479074436a93b439b0b95c79095c28791882"
dependencies:
@@ -3811,8 +3888,8 @@ eth-json-rpc-infura@^2.0.11:
tape "^4.8.0"
eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-middleware@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz#16b1053386aa3803b125732aa6de07eadf068729"
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.2.tgz#14cb0af1e9910c24dd063beabbbb7142d39d9bb9"
dependencies:
async "^2.5.0"
eth-query "^2.1.2"
@@ -3822,6 +3899,7 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-mid
ethereumjs-util "^5.1.2"
ethereumjs-vm "^2.1.0"
fetch-ponyfill "^4.0.0"
+ json-rpc-engine "^3.6.0"
json-rpc-error "^2.0.0"
json-stable-stringify "^1.0.1"
promise-to-callback "^1.0.0"
@@ -3855,14 +3933,7 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
json-rpc-random-id "^1.0.0"
xtend "^4.0.1"
-eth-sig-util@^1.3.0, eth-sig-util@^1.4.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.1.tgz#dfcde3cbd03c38d429ad8695938a2678ec56f1ae"
- dependencies:
- ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
- ethereumjs-util "^5.1.1"
-
-eth-sig-util@^1.4.2:
+eth-sig-util@^1.3.0, eth-sig-util@^1.4.0, eth-sig-util@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210"
dependencies:
@@ -3960,20 +4031,7 @@ ethereumjs-util@4.5.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumj
rlp "^2.0.0"
secp256k1 "^3.0.1"
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz#25ba0215cbb4c2f0b108a6f96af2a2e62e45921f"
- dependencies:
- babel-preset-es2015 "^6.24.0"
- babelify "^7.3.0"
- bn.js "^4.8.0"
- create-hash "^1.1.2"
- ethjs-util "^0.1.3"
- keccak "^1.0.2"
- rlp "^2.0.0"
- secp256k1 "^3.0.1"
-
-ethereumjs-util@^5.1.3:
+ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.3.tgz#0c1f6efb1da9c5b6720a65697859fc0be6672df0"
dependencies:
@@ -4111,20 +4169,16 @@ ethjs-query@^0.2.4, ethjs-query@^0.2.6, ethjs-query@^0.2.9:
ethjs-rpc "0.1.5"
ethjs-query@^0.3.1:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.2.tgz#f488a48ce1994cd4c77eccb7b52902c6f29cfd85"
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.1.tgz#aed5b60bdb7e73ad831d1218c8b067310013b86f"
dependencies:
ethjs-format "0.2.4"
- ethjs-rpc "0.1.8"
+ ethjs-rpc "0.1.5"
ethjs-rpc@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.5.tgz#099e22f27dc4c18b6978a485fc36b1b0f7969080"
-ethjs-rpc@0.1.8:
- version "0.1.8"
- resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.8.tgz#1676740e41c7228196a71189d33f15c9c85b599d"
-
ethjs-schema@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.5.tgz#59740e3b3977bcdbb9b11bc3068201e8aceabb0d"
@@ -4331,7 +4385,7 @@ extend-shallow@^2.0.1:
dependencies:
is-extendable "^0.1.0"
-extend-shallow@^3.0.0:
+extend-shallow@^3.0.0, extend-shallow@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
dependencies:
@@ -4371,8 +4425,8 @@ extglob@^0.3.1:
is-extglob "^1.0.0"
extglob@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.3.tgz#55e019d0c95bf873949c737b7e5172dba84ebb29"
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
dependencies:
array-unique "^0.3.2"
define-property "^1.0.0"
@@ -4410,7 +4464,7 @@ falafel@^2.1.0:
isarray "0.0.1"
object-keys "^1.0.6"
-fancy-log@^1.1.0:
+fancy-log@^1.1.0, fancy-log@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1"
dependencies:
@@ -4795,11 +4849,11 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
function.prototype.name@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
dependencies:
define-properties "^1.1.2"
- function-bind "^1.1.0"
+ function-bind "^1.1.1"
is-callable "^1.1.3"
functional-red-black-tree@^1.0.1:
@@ -5008,13 +5062,9 @@ global@~4.3.0:
min-document "^2.19.0"
process "~0.5.1"
-globals@^10.0.0:
- version "10.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7"
-
-globals@^11.0.1:
- version "11.1.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
+globals@^11.0.1, globals@^11.1.0:
+ version "11.2.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.2.0.tgz#aa2ece052a787563ba70a3dcd9dc2eb8a9a0488c"
globals@^9.18.0:
version "9.18.0"
@@ -5065,8 +5115,8 @@ globule@^1.0.0:
minimatch "~3.0.2"
glogg@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
dependencies:
sparkles "^1.0.0"
@@ -5093,27 +5143,28 @@ growly@^1.3.0:
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
gulp-autoprefixer@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-autoprefixer/-/gulp-autoprefixer-4.0.0.tgz#e00a8c571b85d06516ac26341be90dfd9fc1eab0"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-autoprefixer/-/gulp-autoprefixer-4.1.0.tgz#064af73cc02cadac8ff34d0bf93ffdfb94ea12aa"
dependencies:
autoprefixer "^7.0.0"
- gulp-util "^3.0.0"
+ fancy-log "^1.3.2"
+ plugin-error "^0.1.2"
postcss "^6.0.1"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-babel@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.0.tgz#7b93c975159f7a0553e4263b4a55100ccc239b28"
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.1.tgz#b9c8e29fa376b36c57989db820fc1c1715bb47cb"
dependencies:
- gulp-util "^3.0.0"
+ plugin-error "^1.0.1"
replace-ext "0.0.1"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-cli@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.0.tgz#7f049ad298ed388cda9bd813b5d7062407d62cad"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.1.tgz#7847e220cb3662f2be8a6d572bf14e17be5a994b"
dependencies:
ansi-colors "^1.0.1"
archy "^1.0.0"
@@ -5121,25 +5172,26 @@ gulp-cli@^2.0.0:
color-support "^1.1.3"
concat-stream "^1.6.0"
copy-props "^2.0.1"
- fancy-log "^1.1.0"
+ fancy-log "^1.3.2"
gulplog "^1.0.0"
- interpret "^1.0.0"
+ interpret "^1.1.0"
isobject "^3.0.1"
- liftoff "^2.3.0"
+ liftoff "^2.5.0"
matchdep "^2.0.0"
mute-stdout "^1.0.0"
pretty-hrtime "^1.0.0"
replace-homedir "^1.0.0"
- semver-greatest-satisfied-range "^1.0.0"
+ semver-greatest-satisfied-range "^1.1.0"
v8flags "^3.0.1"
yargs "^7.1.0"
gulp-eslint@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.0.tgz#16d9ea4d696e7b7a9d65eeb1aa5bc4ba0a22c7f7"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.2.tgz#18a2a6768e4404cbf3e203239cb57474168fa606"
dependencies:
eslint "^4.0.0"
- gulp-util "^3.0.8"
+ fancy-log "^1.3.2"
+ plugin-error "^1.0.0"
gulp-if@^2.0.2:
version "2.0.2"
@@ -5195,8 +5247,8 @@ gulp-sass@^3.1.0:
vinyl-sourcemaps-apply "^0.2.0"
gulp-sourcemaps@^2.6.0:
- version "2.6.2"
- resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.2.tgz#4f41c72b35a7ea06b666d2e3f57917e2c0e71c4e"
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz#cbb2008450b1bcce6cd23bf98337be751bf6e30a"
dependencies:
"@gulp-sourcemaps/identity-map" "1.X"
"@gulp-sourcemaps/map-sources" "1.X"
@@ -5206,7 +5258,7 @@ gulp-sourcemaps@^2.6.0:
debug-fabulous "1.X"
detect-newline "2.X"
graceful-fs "4.X"
- source-map "0.X"
+ source-map "~0.6.0"
strip-bom-string "1.X"
through2 "2.X"
@@ -5255,7 +5307,7 @@ gulp-uglify@^3.0.0:
uglify-js "^3.0.5"
vinyl-sourcemaps-apply "^0.2.0"
-gulp-util@^3.0, gulp-util@^3.0.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
+gulp-util@^3.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
version "3.0.8"
resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
dependencies:
@@ -5294,12 +5346,13 @@ gulp-watch@^4.3.5:
vinyl-file "^2.0.0"
gulp-zip@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.0.0.tgz#1cefc08b4bf36df4b5b1e7c6b36ee55ebbe4a881"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.1.0.tgz#dab178bd99afa190923f1eb78abaf0db47817704"
dependencies:
get-stream "^3.0.0"
- gulp-util "^3.0.0"
+ plugin-error "^0.1.2"
through2 "^2.0.1"
+ vinyl "^2.1.0"
yazl "^2.1.0"
"gulp@github:gulpjs/gulp#4.0":
@@ -5494,6 +5547,16 @@ he@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
+history@^4.7.2:
+ version "4.7.2"
+ resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
+ dependencies:
+ invariant "^2.2.1"
+ loose-envify "^1.2.0"
+ resolve-pathname "^2.2.0"
+ value-equal "^0.4.0"
+ warning "^3.0.0"
+
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -5510,7 +5573,7 @@ hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
-hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.1:
+hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -5531,7 +5594,7 @@ hosted-git-info@^2.1.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
-html-encoding-sniffer@^1.0.1:
+html-encoding-sniffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
dependencies:
@@ -5776,11 +5839,11 @@ insert-module-globals@^7.0.0:
through2 "^2.0.0"
xtend "^4.0.0"
-interpret@^1.0.0:
+interpret@^1.0.0, interpret@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
-invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2:
+invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
@@ -6078,8 +6141,8 @@ is-relative@^1.0.0:
is-unc-path "^1.0.0"
is-resolvable@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
@@ -6241,8 +6304,8 @@ jazzicon@^1.2.0:
raphael "^2.2.0"
js-base64@^2.1.8, js-base64@^2.1.9:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582"
js-beautify@~1.5.4:
version "1.5.10"
@@ -6288,33 +6351,35 @@ jsdom-global@^3.0.2:
resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"
jsdom@^11.1.0:
- version "11.5.1"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.5.1.tgz#5df753b8d0bca20142ce21f4f6c039f99a992929"
+ version "11.6.1"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.1.tgz#43fffc10072597a8ee9680cba46900d9e4dbeba2"
dependencies:
- abab "^1.0.3"
- acorn "^5.1.2"
- acorn-globals "^4.0.0"
+ abab "^1.0.4"
+ acorn "^5.3.0"
+ acorn-globals "^4.1.0"
array-equal "^1.0.0"
browser-process-hrtime "^0.1.2"
- content-type-parser "^1.0.1"
+ content-type-parser "^1.0.2"
cssom ">= 0.3.2 < 0.4.0"
cssstyle ">= 0.2.37 < 0.3.0"
domexception "^1.0.0"
escodegen "^1.9.0"
- html-encoding-sniffer "^1.0.1"
+ html-encoding-sniffer "^1.0.2"
left-pad "^1.2.0"
nwmatcher "^1.4.3"
- parse5 "^3.0.2"
- pn "^1.0.0"
+ parse5 "^4.0.0"
+ pn "^1.1.0"
request "^2.83.0"
- request-promise-native "^1.0.3"
- sax "^1.2.1"
- symbol-tree "^3.2.1"
+ request-promise-native "^1.0.5"
+ sax "^1.2.4"
+ symbol-tree "^3.2.2"
tough-cookie "^2.3.3"
+ w3c-hr-time "^1.0.1"
webidl-conversions "^4.0.2"
- whatwg-encoding "^1.0.1"
- whatwg-url "^6.3.0"
- xml-name-validator "^2.0.1"
+ whatwg-encoding "^1.0.3"
+ whatwg-url "^6.4.0"
+ ws "^4.0.0"
+ xml-name-validator "^3.0.0"
jsesc@^1.3.0:
version "1.3.0"
@@ -6477,7 +6542,7 @@ jstransform@^10.1.0:
esprima-fb "13001.1001.0-dev-harmony-fb"
source-map "0.1.31"
-jsx-ast-utils@^2.0.0:
+jsx-ast-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
dependencies:
@@ -6717,7 +6782,7 @@ lexical-scope@^1.2.0:
dependencies:
astw "^2.0.0"
-liftoff@^2.3.0:
+liftoff@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
dependencies:
@@ -6731,8 +6796,8 @@ liftoff@^2.3.0:
resolve "^1.1.7"
livereload-js@^2.2.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a"
load-json-file@^1.0.0:
version "1.1.0"
@@ -6982,8 +7047,8 @@ log-symbols@^1.0.0, log-symbols@^1.0.2:
chalk "^1.0.0"
log-symbols@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6"
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
dependencies:
chalk "^2.0.1"
@@ -6995,16 +7060,16 @@ log4js@^0.6.31:
semver "~4.3.3"
loglevel@^1.4.1, loglevel@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934"
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
lolex@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
lolex@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.1.tgz#3d2319894471ea0950ef64692ead2a5318cff362"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807"
longest-streak@^2.0.1:
version "2.0.2"
@@ -7014,7 +7079,7 @@ longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@@ -7027,9 +7092,12 @@ loud-rejection@^1.0.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"
-lru-cache@2.2.x:
- version "2.2.4"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
+lru-cache@4.1.x, lru-cache@^4.0.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
+ dependencies:
+ pseudomap "^1.0.2"
+ yallist "^2.1.2"
lru-cache@^3.2.0:
version "3.2.0"
@@ -7037,13 +7105,6 @@ lru-cache@^3.2.0:
dependencies:
pseudomap "^1.0.1"
-lru-cache@^4.0.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
- dependencies:
- pseudomap "^1.0.2"
- yallist "^2.1.2"
-
lru-queue@0.1:
version "0.1.0"
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
@@ -7296,8 +7357,8 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
regex-cache "^0.4.2"
micromatch@^3.0.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.4.tgz#bb812e741a41f982c854e42b421a7eac458796f4"
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.5.tgz#d05e168c206472dfbca985bfef4f57797b4cd4ba"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
@@ -7409,8 +7470,8 @@ minimist@~0.0.1, minimist@~0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
mississippi@^1.2.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-1.3.0.tgz#d201583eb12327e3c5c1642a404a9cacf94e34f5"
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-1.3.1.tgz#2a8bb465e86550ac8b36a7b6f45599171d78671e"
dependencies:
concat-stream "^1.5.0"
duplexify "^3.4.2"
@@ -7492,6 +7553,26 @@ module-deps@^4.0.8:
through2 "^2.0.0"
xtend "^4.0.0"
+module-deps@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-5.0.1.tgz#3bc47c14b0a6d925aff2ec4a177b456a96ae0396"
+ dependencies:
+ JSONStream "^1.0.3"
+ browser-resolve "^1.7.0"
+ cached-path-relative "^1.0.0"
+ concat-stream "~1.6.0"
+ defined "^1.0.0"
+ detective "^5.0.2"
+ duplexer2 "^0.1.2"
+ inherits "^2.0.1"
+ parents "^1.0.0"
+ readable-stream "^2.0.2"
+ resolve "^1.1.3"
+ stream-combiner2 "^1.1.1"
+ subarg "^1.0.0"
+ through2 "^2.0.0"
+ xtend "^4.0.0"
+
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
@@ -7554,8 +7635,8 @@ nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.2:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
nanomatch@^1.2.5:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.6.tgz#f27233e97c34a8706b7e781a4bc611c957a81625"
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
@@ -7594,8 +7675,8 @@ next-tick@1:
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
nise@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.2.tgz#9aa5edb500da38035884106e3c571341bc68b2c1"
dependencies:
formatio "^1.2.0"
just-extend "^1.1.26"
@@ -7604,8 +7685,8 @@ nise@^1.2.0:
text-encoding "^0.6.4"
nock@^9.0.14:
- version "9.1.5"
- resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.5.tgz#9e4878e0e1c050bdd93ae1e326e89461ea15618b"
+ version "9.1.6"
+ resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.6.tgz#16395af4c45b0fd84d1a4a9668154e16fa6624db"
dependencies:
chai ">=1.9.2 <4.0.0"
debug "^2.2.0"
@@ -7671,13 +7752,13 @@ node-libs-browser@^2.0.0:
vm-browserify "0.0.4"
node-notifier@^5.0.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea"
dependencies:
growly "^1.3.0"
- semver "^5.3.0"
- shellwords "^0.1.0"
- which "^1.2.12"
+ semver "^5.4.1"
+ shellwords "^0.1.1"
+ which "^1.3.0"
node-pre-gyp@^0.6.39:
version "0.6.39"
@@ -8107,8 +8188,10 @@ p-finally@^1.0.0:
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
p-limit@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
+ dependencies:
+ p-try "^1.0.0"
p-locate@^2.0.0:
version "2.0.0"
@@ -8120,6 +8203,10 @@ p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+
pako@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
@@ -8206,12 +8293,16 @@ parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
-parse5@^3.0.1, parse5@^3.0.2:
+parse5@^3.0.1:
version "3.0.3"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
dependencies:
"@types/node" "*"
+parse5@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
+
parsejson@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab"
@@ -8403,6 +8494,15 @@ plugin-error@^0.1.2:
arr-union "^2.0.1"
extend-shallow "^1.1.2"
+plugin-error@^1.0.0, plugin-error@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c"
+ dependencies:
+ ansi-colors "^1.0.1"
+ arr-diff "^4.0.0"
+ arr-union "^3.1.0"
+ extend-shallow "^3.0.2"
+
plur@^2.0.0, plur@^2.1.0, plur@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a"
@@ -8413,9 +8513,9 @@ pluralize@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
-pn@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/pn/-/pn-1.0.0.tgz#1cf5a30b0d806cd18f88fc41a6b5d4ad615b3ba9"
+pn@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
pojo-migrator@^2.1.0:
version "2.1.0"
@@ -8522,10 +8622,10 @@ postcss-scss@^0.4.0:
postcss "^5.2.13"
postcss-scss@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-1.0.2.tgz#ff45cf3354b879ee89a4eb68680f46ac9bb14f94"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-1.0.3.tgz#4c00ab440fc1c994134e3d4e600c23341af6cd27"
dependencies:
- postcss "^6.0.3"
+ postcss "^6.0.15"
postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.1.1:
version "2.2.3"
@@ -8563,13 +8663,13 @@ postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.
source-map "^0.5.6"
supports-color "^3.2.3"
-postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.8:
- version "6.0.14"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885"
+postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.15, postcss@^6.0.16, postcss@^6.0.6, postcss@^6.0.8:
+ version "6.0.16"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.16.tgz#112e2fe2a6d2109be0957687243170ea5589e146"
dependencies:
chalk "^2.3.0"
source-map "^0.6.1"
- supports-color "^4.4.0"
+ supports-color "^5.1.0"
prelude-ls@~1.1.2:
version "1.1.2"
@@ -8647,7 +8747,14 @@ prompt@^1.0.0:
utile "0.3.x"
winston "2.1.x"
-prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0:
+prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8:
+ version "15.5.10"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
+ dependencies:
+ fbjs "^0.8.9"
+ loose-envify "^1.3.1"
+
+prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@@ -8695,13 +8802,20 @@ pump@^1.0.0, pump@^1.0.2:
end-of-stream "^1.1.0"
once "^1.3.1"
+pump@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
pumpify@^1.3.3, pumpify@^1.3.4, pumpify@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb"
dependencies:
- duplexify "^3.1.2"
- inherits "^2.0.1"
- pump "^1.0.0"
+ duplexify "^3.5.3"
+ inherits "^2.0.3"
+ pump "^2.0.0"
punycode@1.3.2:
version "1.3.2"
@@ -8815,8 +8929,8 @@ randomatic@^1.1.3:
kind-of "^4.0.0"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
dependencies:
safe-buffer "^5.1.0"
@@ -8855,8 +8969,8 @@ raw-body@~2.1.5:
unpipe "1.0.0"
rc@^1.1.7:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.4.tgz#a0f606caae2a3b862bbd0ef85482c0125b315fa3"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
@@ -8889,18 +9003,18 @@ react-hyperscript@^2.4.0:
react ">= 0.12.0 < 16.0.0"
react-hyperscript@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.0.0.tgz#3c16010b33175de6bc01fd1ebad0a16a9a6dc9ab"
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.1.0.tgz#8f0fa74003b20ccee98fbb496dfb0791139a287d"
-react-input-autosize@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.1.2.tgz#a3dc11a5517c434db25229925541309de3f7a8f5"
+react-input-autosize@^2.1.2:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
dependencies:
prop-types "^15.5.8"
react-markdown@^3.0.0:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.3.tgz#5ac1f20cb5a3e8c47b6ae3c8522e813b08f58c34"
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.4.tgz#4f37aa5ac4f78f64f93b41b12ad0c08e92eb1680"
dependencies:
prop-types "^15.6.0"
remark-parse "^4.0.0"
@@ -8927,13 +9041,36 @@ react-redux@^5.0.5:
loose-envify "^1.1.0"
prop-types "^15.5.10"
+react-router-dom@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d"
+ dependencies:
+ history "^4.7.2"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ prop-types "^15.5.4"
+ react-router "^4.2.0"
+ warning "^3.0.0"
+
+react-router@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986"
+ dependencies:
+ history "^4.7.2"
+ hoist-non-react-statics "^2.3.0"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ path-to-regexp "^1.7.0"
+ prop-types "^15.5.4"
+ warning "^3.0.0"
+
react-select@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.1.0.tgz#626a2de839fdea2ade74dd1b143a9bde34be6c82"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.2.1.tgz#a2fe58a569eb14dcaa6543816260b97e538120d1"
dependencies:
classnames "^2.2.4"
prop-types "^15.5.8"
- react-input-autosize "^2.1.0"
+ react-input-autosize "^2.1.2"
react-simple-file-input@^2.0.0:
version "2.0.1"
@@ -8979,13 +9116,6 @@ react-tooltip-component@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/react-tooltip-component/-/react-tooltip-component-0.3.0.tgz#fb3ec78c3270fe919692bc31f1404108bcf4785e"
-react-tooltip@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-3.4.0.tgz#037f38f797c3e6b1b58d2534ccc8c2c76af4f52d"
- dependencies:
- classnames "^2.2.5"
- prop-types "^15.6.0"
-
react-transition-group@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
@@ -9094,7 +9224,7 @@ read@1.0.x:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3:
+readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
@@ -9367,7 +9497,7 @@ request-promise-core@1.1.1:
dependencies:
lodash "^4.13.1"
-request-promise-native@^1.0.3:
+request-promise-native@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
dependencies:
@@ -9526,6 +9656,10 @@ resolve-options@^1.1.0:
dependencies:
value-or-function "^3.0.0"
+resolve-pathname@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
+
resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@@ -9658,7 +9792,7 @@ sass-graph@^2.2.4:
scss-tokenizer "^0.2.3"
yargs "^7.0.0"
-sax@^1.2.1:
+sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -9697,8 +9831,8 @@ scss-tokenizer@^0.2.3:
source-map "^0.4.2"
secp256k1@^3.0.1:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.4.0.tgz#1c905b256fa4ae5b9cc170e672dd59b4c5de46a4"
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0"
dependencies:
bindings "^1.2.1"
bip66 "^1.1.3"
@@ -9713,15 +9847,15 @@ semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
-semver-greatest-satisfied-range@^1.0.0:
+semver-greatest-satisfied-range@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b"
dependencies:
sver-compat "^1.5.0"
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@~5.4.1:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
semver@~4.3.3:
version "4.3.6"
@@ -9731,6 +9865,10 @@ semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+semver@~5.4.1:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+
send@0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
@@ -9803,8 +9941,8 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
- version "2.4.9"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
+ version "2.4.10"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b"
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"
@@ -9845,7 +9983,7 @@ shell-quote@^1.4.2, shell-quote@^1.6.1:
array-reduce "~0.0.0"
jsonify "~0.0.0"
-shellwords@^0.1.0:
+shellwords@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@@ -9858,15 +9996,15 @@ signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
sinon@^4.0.0:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.3.tgz#fc599eda47ed9f1a694ce774b94ab44260bd7ac5"
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.2.2.tgz#e039ab27bdb426fc61363c380726e996a2e2c620"
dependencies:
diff "^3.1.0"
formatio "1.2.0"
lodash.get "^4.4.2"
lolex "^2.2.0"
nise "^1.2.0"
- supports-color "^4.4.0"
+ supports-color "^5.1.0"
type-detect "^4.0.5"
sizzle@2.3.3:
@@ -10051,9 +10189,9 @@ source-map@0.1.31:
dependencies:
amdefine ">=0.0.4"
-source-map@0.X, "source-map@>= 0.1.2", source-map@^0.6.1, source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+"source-map@>= 0.1.2":
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.0.tgz#ebf0d13a48f3619f91891816fdda932f83a6021f"
source-map@^0.1.38, source-map@~0.1.33:
version "0.1.43"
@@ -10071,6 +10209,10 @@ source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, sour
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
sparkles@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
@@ -10242,12 +10384,12 @@ stream-exhaust@^1.0.1:
resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d"
stream-http@^2.0.0, stream-http@^2.7.2:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10"
dependencies:
builtin-status-codes "^3.0.0"
inherits "^2.0.1"
- readable-stream "^2.2.6"
+ readable-stream "^2.3.3"
to-arraybuffer "^1.0.0"
xtend "^4.0.0"
@@ -10574,12 +10716,18 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
dependencies:
has-flag "^1.0.0"
-supports-color@^4.0.0, supports-color@^4.4.0:
+supports-color@^4.0.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
dependencies:
has-flag "^2.0.0"
+supports-color@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5"
+ dependencies:
+ has-flag "^2.0.0"
+
sver-compat@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8"
@@ -10604,10 +10752,10 @@ sw-stream@^2.0.0:
through2 "^2.0.3"
symbol-observable@^1.0.3, symbol-observable@^1.0.4:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
-symbol-tree@^3.2.1:
+symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
@@ -10825,8 +10973,8 @@ timers-browserify@^1.0.1:
process "~0.11.0"
timers-browserify@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae"
dependencies:
setimmediate "^1.0.4"
@@ -10964,10 +11112,14 @@ trumpet@^1.7.1:
readable-stream "^1.0.27-1"
through2 "^1.0.0"
-tty-browserify@0.0.0, tty-browserify@~0.0.0:
+tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
+tty-browserify@~0.0.0:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
+
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -10997,8 +11149,8 @@ type-detect@^1.0.0:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
type-detect@^4.0.0, type-detect@^4.0.5:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2"
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.7.tgz#862bd2cf6058ad92799ff5a5b8cf7b6cec726198"
type-is@~1.6.10, type-is@~1.6.15:
version "1.6.15"
@@ -11015,16 +11167,9 @@ ua-parser-js@^0.7.9:
version "0.7.17"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
-uglify-es@^3.0.15:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.3.tgz#095f5314d2a5d27e215390e50fa90751473dac2f"
- dependencies:
- commander "~2.12.1"
- source-map "~0.6.1"
-
-uglify-es@^3.2.0:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.7.tgz#d1249af668666aba7cb1163e277455be9eb393cf"
+uglify-es@^3.0.15, uglify-es@^3.2.0:
+ version "3.3.9"
+ resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
@@ -11039,8 +11184,8 @@ uglify-js@^2.6, uglify-js@^2.8.27:
uglify-to-browserify "~1.0.0"
uglify-js@^3.0.5:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.7.tgz#28463e7c7451f89061d2b235e30925bf5625e14d"
+ version "3.3.9"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.9.tgz#33869666c8ab7f7658ce3d22f0f1ced40097d33a"
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
@@ -11067,6 +11212,10 @@ ultron@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
+ultron@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
+
umd@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
@@ -11207,10 +11356,10 @@ use@^2.0.0:
lazy-cache "^2.0.2"
useragent@^2.1.12:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
dependencies:
- lru-cache "2.2.x"
+ lru-cache "4.1.x"
tmp "0.0.x"
utf8@^2.1.1:
@@ -11247,8 +11396,8 @@ uuid@^2.0.1:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
uuid@^3.0.0, uuid@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
v8flags@^3.0.1:
version "3.0.1"
@@ -11267,6 +11416,10 @@ validate-npm-package-license@^3.0.1:
spdx-correct "~1.0.0"
spdx-expression-parse "~1.0.0"
+value-equal@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
+
value-or-function@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"
@@ -11325,10 +11478,9 @@ vinyl-file@^2.0.0:
vinyl "^1.1.0"
vinyl-fs@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.1.tgz#74af5f6836a1cf414d35eeb3c10f2e65fc2a2c10"
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.2.tgz#1b86258844383f57581fcaac081fe09ef6d6d752"
dependencies:
- flush-write-stream "^1.0.0"
fs-mkdirp-stream "^1.0.0"
glob-stream "^6.1.0"
graceful-fs "^4.0.0"
@@ -11337,6 +11489,7 @@ vinyl-fs@^3.0.0:
lead "^1.0.0"
object.assign "^4.0.4"
pumpify "^1.3.5"
+ readable-stream "^2.3.3"
remove-bom-buffer "^3.0.0"
remove-bom-stream "^1.2.0"
resolve-options "^1.1.0"
@@ -11412,6 +11565,12 @@ vreme@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/vreme/-/vreme-3.0.2.tgz#4721376b449457fefde8a849d3340933b90b5686"
+w3c-hr-time@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
+ dependencies:
+ browser-process-hrtime "^0.1.2"
+
walk-sync@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465"
@@ -11426,11 +11585,11 @@ warning@^3.0.0:
loose-envify "^1.0.0"
watchify@^3.9.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.9.0.tgz#f075fd2e8a86acde84cedba6e5c2a0bedd523d9e"
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.10.0.tgz#f436605553c432d87f62f718cc78077418ffbccb"
dependencies:
anymatch "^1.3.0"
- browserify "^14.0.0"
+ browserify "^15.2.0"
chokidar "^1.0.0"
defined "^1.0.0"
outpipe "^1.1.0"
@@ -11517,8 +11676,8 @@ web3@^0.18.4:
xmlhttprequest "*"
web3@^0.20.1:
- version "0.20.3"
- resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.3.tgz#caa44373dc8815ac8767bddb6ba73073964caa8b"
+ version "0.20.4"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.4.tgz#400e6579a65bb4a3dde71a6ebf6509afadc33a04"
dependencies:
bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
crypto-js "^3.1.4"
@@ -11574,7 +11733,7 @@ websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
-whatwg-encoding@^1.0.1:
+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3"
dependencies:
@@ -11584,7 +11743,7 @@ whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
-whatwg-url@^6.3.0:
+whatwg-url@^6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08"
dependencies:
@@ -11695,6 +11854,14 @@ ws@1.1.2:
options ">=0.0.5"
ultron "1.0.x"
+ws@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-4.0.0.tgz#bfe1da4c08eeb9780b986e0e4d10eccd7345999f"
+ dependencies:
+ async-limiter "~1.0.0"
+ safe-buffer "~5.1.0"
+ ultron "~1.1.0"
+
wtf-8@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"
@@ -11724,9 +11891,9 @@ xhr@^2.2.0:
parse-headers "^2.0.0"
xtend "^4.0.0"
-xml-name-validator@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
+xml-name-validator@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
xmldom@^0.1.19:
version "0.1.27"
@@ -11781,7 +11948,7 @@ yargs-parser@^5.0.0:
dependencies:
camelcase "^3.0.0"
-yargs-parser@^8.0.0:
+yargs-parser@^8.0.0, yargs-parser@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
dependencies:
@@ -11792,10 +11959,10 @@ yargs@^1.2.6:
resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
yargs@^10.0.3:
- version "10.0.3"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"
+ version "10.1.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5"
dependencies:
- cliui "^3.2.0"
+ cliui "^4.0.0"
decamelize "^1.1.1"
find-up "^2.1.0"
get-caller-file "^1.0.1"
@@ -11806,7 +11973,7 @@ yargs@^10.0.3:
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
- yargs-parser "^8.0.0"
+ yargs-parser "^8.1.0"
yargs@^3.5.4:
version "3.32.0"