aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app
diff options
context:
space:
mode:
authorbrunobar79 <brunobar79@gmail.com>2018-11-07 09:21:19 +0800
committerbrunobar79 <brunobar79@gmail.com>2018-11-07 09:21:19 +0800
commitc651212025ab7cd0309d96be6687c1eba35ab9fa (patch)
treefa5a6020daae332c5df47bdee3492e8a079375e3 /ui/app
parent9c1b2108f69334884473eb95758e2d1c02c984d6 (diff)
parent7f944923d170d6e7e04f6e238d2fd5f80abe3161 (diff)
downloadtangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar.gz
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar.bz2
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar.lz
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar.xz
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.tar.zst
tangerine-wallet-browser-c651212025ab7cd0309d96be6687c1eba35ab9fa.zip
fix merge conflicts
Diffstat (limited to 'ui/app')
-rw-r--r--ui/app/actions.js33
-rw-r--r--ui/app/app.js8
-rw-r--r--ui/app/components/account-dropdowns.js3
-rw-r--r--ui/app/components/account-menu/index.js2
-rw-r--r--ui/app/components/account-panel.js2
-rw-r--r--ui/app/components/app-header/app-header.component.js2
-rw-r--r--ui/app/components/balance-component.js16
-rw-r--r--ui/app/components/currency-display/currency-display.component.js17
-rw-r--r--ui/app/components/currency-display/currency-display.container.js12
-rw-r--r--ui/app/components/currency-display/index.scss4
-rw-r--r--ui/app/components/currency-display/tests/currency-display.container.test.js31
-rw-r--r--ui/app/components/currency-input/currency-input.component.js5
-rw-r--r--ui/app/components/currency-input/currency-input.container.js7
-rw-r--r--ui/app/components/currency-input/tests/currency-input.component.test.js24
-rw-r--r--ui/app/components/currency-input/tests/currency-input.container.test.js5
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js8
-rw-r--r--ui/app/components/dropdowns/network-dropdown.js35
-rw-r--r--ui/app/components/dropdowns/tests/network-dropdown.test.js4
-rw-r--r--ui/app/components/eth-balance.js12
-rw-r--r--ui/app/components/identicon.js124
-rw-r--r--ui/app/components/identicon/identicon.component.js99
-rw-r--r--ui/app/components/identicon/identicon.container.js12
-rw-r--r--ui/app/components/identicon/index.js1
-rw-r--r--ui/app/components/identicon/index.scss7
-rw-r--r--ui/app/components/identicon/tests/identicon.component.test.js51
-rw-r--r--ui/app/components/index.scss4
-rw-r--r--ui/app/components/jazzicon/index.js1
-rw-r--r--ui/app/components/jazzicon/jazzicon.component.js69
-rw-r--r--ui/app/components/modals/account-modal-container.js2
-rw-r--r--ui/app/components/modals/clear-approved-origins/clear-approved-origins.component.js39
-rw-r--r--ui/app/components/modals/clear-approved-origins/clear-approved-origins.container.js16
-rw-r--r--ui/app/components/modals/clear-approved-origins/index.js1
-rw-r--r--ui/app/components/modals/hide-token-confirmation-modal.js2
-rw-r--r--ui/app/components/modals/modal.js28
-rw-r--r--ui/app/components/modals/transaction-details/index.js1
-rw-r--r--ui/app/components/modals/transaction-details/transaction-details.component.js54
-rw-r--r--ui/app/components/modals/transaction-details/transaction-details.container.js4
-rw-r--r--ui/app/components/network-display/index.scss5
-rw-r--r--ui/app/components/network-display/network-display.component.js19
-rw-r--r--ui/app/components/network.js5
-rw-r--r--ui/app/components/page-container/index.scss1
-rw-r--r--ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js2
-rw-r--r--ui/app/components/pages/home/home.component.js10
-rw-r--r--ui/app/components/pages/home/home.container.js2
-rw-r--r--ui/app/components/pages/provider-approval/index.js1
-rw-r--r--ui/app/components/pages/provider-approval/provider-approval.component.js28
-rw-r--r--ui/app/components/pages/provider-approval/provider-approval.container.js12
-rw-r--r--ui/app/components/pages/settings/settings-tab/index.scss12
-rw-r--r--ui/app/components/pages/settings/settings-tab/settings-tab.component.js185
-rw-r--r--ui/app/components/pages/settings/settings-tab/settings-tab.container.js22
-rw-r--r--ui/app/components/provider-page-container/index.js3
-rw-r--r--ui/app/components/provider-page-container/index.scss121
-rw-r--r--ui/app/components/provider-page-container/provider-page-container-content/index.js1
-rw-r--r--ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.component.js77
-rw-r--r--ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.container.js11
-rw-r--r--ui/app/components/provider-page-container/provider-page-container-header/index.js1
-rw-r--r--ui/app/components/provider-page-container/provider-page-container-header/provider-page-container-header.component.js12
-rw-r--r--ui/app/components/provider-page-container/provider-page-container.component.js50
-rw-r--r--ui/app/components/send/account-list-item/account-list-item.container.js2
-rw-r--r--ui/app/components/send/account-list-item/tests/account-list-item-component.test.js1
-rw-r--r--ui/app/components/send/account-list-item/tests/account-list-item-container.test.js2
-rw-r--r--ui/app/components/send/send-content/send-amount-row/tests/send-amount-row-component.test.js1
-rw-r--r--ui/app/components/send/send.selectors.js5
-rw-r--r--ui/app/components/send/send.utils.js4
-rw-r--r--ui/app/components/send/tests/send-selectors-test-data.js1
-rw-r--r--ui/app/components/send/tests/send-selectors.test.js10
-rw-r--r--ui/app/components/signature-request.js2
-rw-r--r--ui/app/components/token-cell.js2
-rw-r--r--ui/app/components/token-input/tests/token-input.component.test.js12
-rw-r--r--ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js3
-rw-r--r--ui/app/components/transaction-activity-log/transaction-activity-log.component.js21
-rw-r--r--ui/app/components/transaction-activity-log/transaction-activity-log.container.js3
-rw-r--r--ui/app/components/transaction-activity-log/transaction-activity-log.util.js11
-rw-r--r--ui/app/components/transaction-breakdown/index.js2
-rw-r--r--ui/app/components/transaction-breakdown/transaction-breakdown.component.js7
-rw-r--r--ui/app/components/transaction-breakdown/transaction-breakdown.container.js11
-rw-r--r--ui/app/components/transaction-list-item/index.scss2
-rw-r--r--ui/app/components/transaction-list-item/transaction-list-item.component.js19
-rw-r--r--ui/app/components/transaction-list-item/transaction-list-item.container.js10
-rw-r--r--ui/app/components/transaction-list/index.scss3
-rw-r--r--ui/app/components/transaction-view-balance/index.scss9
-rw-r--r--ui/app/components/transaction-view-balance/transaction-view-balance.container.js3
-rw-r--r--ui/app/components/transaction-view/index.scss1
-rw-r--r--ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js22
-rw-r--r--ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js1
-rw-r--r--ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js18
-rw-r--r--ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js6
-rw-r--r--ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js4
-rw-r--r--ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js6
-rw-r--r--ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js4
-rw-r--r--ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js6
-rw-r--r--ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js4
-rw-r--r--ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js6
-rw-r--r--ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js4
-rw-r--r--ui/app/components/wallet-view.js3
-rw-r--r--ui/app/constants/error-keys.js1
-rw-r--r--ui/app/css/itcss/components/buttons.scss5
-rw-r--r--ui/app/css/itcss/components/pages/index.scss2
-rw-r--r--ui/app/css/itcss/components/pages/provider-approval.scss11
-rw-r--r--ui/app/css/itcss/components/request-signature.scss2
-rw-r--r--ui/app/css/itcss/components/wallet-balance.scss5
-rw-r--r--ui/app/ducks/confirm-transaction.duck.js11
-rw-r--r--ui/app/helpers/confirm-transaction/util.js8
-rw-r--r--ui/app/helpers/conversions.util.js10
-rw-r--r--ui/app/helpers/transactions.util.js15
-rw-r--r--ui/app/reducers.js26
-rw-r--r--ui/app/reducers/metamask.js2
-rw-r--r--ui/app/selectors.js5
-rw-r--r--ui/app/selectors/confirm-transaction.js1
-rw-r--r--ui/app/util.js8
110 files changed, 1224 insertions, 444 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index f8a375e2f..501fef76d 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -309,7 +309,7 @@ var actions = {
setPreference,
updatePreferences,
UPDATE_PREFERENCES: 'UPDATE_PREFERENCES',
- setUseETHAsPrimaryCurrencyPreference,
+ setUseNativeCurrencyAsPrimaryCurrencyPreference,
setMouseUserState,
SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
@@ -325,6 +325,9 @@ var actions = {
clearPendingTokens,
createCancelTransaction,
+ approveProviderRequest,
+ rejectProviderRequest,
+ clearApprovedOrigins,
}
module.exports = actions
@@ -1874,10 +1877,10 @@ function updateProviderType (type) {
}
}
-function setRpcTarget (newRpc) {
+function setRpcTarget (newRpc, chainId, ticker = 'ETH', nickname = '') {
return (dispatch) => {
- log.debug(`background.setRpcTarget: ${newRpc}`)
- background.setCustomRpc(newRpc, (err, result) => {
+ log.debug(`background.setRpcTarget: ${newRpc} ${chainId} ${ticker} ${nickname}`)
+ background.setCustomRpc(newRpc, chainId, ticker, nickname, (err, result) => {
if (err) {
log.error(err)
return dispatch(actions.displayWarning('Had a problem changing networks!'))
@@ -2330,8 +2333,8 @@ function updatePreferences (value) {
}
}
-function setUseETHAsPrimaryCurrencyPreference (value) {
- return setPreference('useETHAsPrimaryCurrency', value)
+function setUseNativeCurrencyAsPrimaryCurrencyPreference (value) {
+ return setPreference('useNativeCurrencyAsPrimaryCurrency', value)
}
function setNetworkNonce (networkNonce) {
@@ -2484,3 +2487,21 @@ function setPendingTokens (pendingTokens) {
payload: tokens,
}
}
+
+function approveProviderRequest (origin) {
+ return (dispatch) => {
+ background.approveProviderRequest(origin)
+ }
+}
+
+function rejectProviderRequest (origin) {
+ return (dispatch) => {
+ background.rejectProviderRequest(origin)
+ }
+}
+
+function clearApprovedOrigins () {
+ return (dispatch) => {
+ background.clearApprovedOrigins()
+ }
+}
diff --git a/ui/app/app.js b/ui/app/app.js
index aeb3d05ee..b3aff1f39 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -101,7 +101,7 @@ class App extends Component {
network,
isMouseUser,
provider,
- frequentRpcList,
+ frequentRpcListDetail,
currentView,
setMouseUserState,
sidebar,
@@ -147,7 +147,7 @@ class App extends Component {
// network dropdown
h(NetworkDropdown, {
provider,
- frequentRpcList,
+ frequentRpcListDetail,
}, []),
h(AccountMenu),
@@ -230,7 +230,7 @@ App.propTypes = {
alertMessage: PropTypes.string,
network: PropTypes.string,
provider: PropTypes.object,
- frequentRpcList: PropTypes.array,
+ frequentRpcListDetail: PropTypes.array,
currentView: PropTypes.object,
sidebar: PropTypes.object,
alertOpen: PropTypes.bool,
@@ -322,7 +322,7 @@ function mapStateToProps (state) {
forgottenPassword: state.appState.forgottenPassword,
nextUnreadNotice,
lostAccounts,
- frequentRpcList: state.metamask.frequentRpcList || [],
+ frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
currentCurrency: state.metamask.currentCurrency,
isMouseUser: state.appState.isMouseUser,
betaUI: state.metamask.featureFlags.betaUI,
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index 043008a36..06376e48b 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -6,10 +6,11 @@ const genAccountLink = require('etherscan-link').createAccountLink
const connect = require('react-redux').connect
const Dropdown = require('./dropdown').Dropdown
const DropdownMenuItem = require('./dropdown').DropdownMenuItem
-const Identicon = require('./identicon')
const copyToClipboard = require('copy-to-clipboard')
const { checksumAddress } = require('../util')
+import Identicon from './identicon'
+
class AccountDropdowns extends Component {
constructor (props) {
super(props)
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
index c9c5b60e1..94eae8d07 100644
--- a/ui/app/components/account-menu/index.js
+++ b/ui/app/components/account-menu/index.js
@@ -7,10 +7,10 @@ const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../../actions')
const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
-const Identicon = require('../identicon')
const { ENVIRONMENT_TYPE_POPUP } = require('../../../../app/scripts/lib/enums')
const { getEnvironmentType } = require('../../../../app/scripts/lib/util')
const Tooltip = require('../tooltip')
+import Identicon from '../identicon'
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
import { PRIMARY } from '../../constants/common'
diff --git a/ui/app/components/account-panel.js b/ui/app/components/account-panel.js
index abaaf8163..a379ed3ac 100644
--- a/ui/app/components/account-panel.js
+++ b/ui/app/components/account-panel.js
@@ -1,7 +1,7 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
-const Identicon = require('./identicon')
+import Identicon from './identicon'
const formatBalance = require('../util').formatBalance
const addressSummary = require('../util').addressSummary
diff --git a/ui/app/components/app-header/app-header.component.js b/ui/app/components/app-header/app-header.component.js
index b8b002dcc..c82dc1de9 100644
--- a/ui/app/components/app-header/app-header.component.js
+++ b/ui/app/components/app-header/app-header.component.js
@@ -2,13 +2,13 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { matchPath } from 'react-router-dom'
+import Identicon from '../identicon'
const {
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP,
} = require('../../../../app/scripts/lib/enums')
const { DEFAULT_ROUTE, INITIALIZE_ROUTE, CONFIRM_TRANSACTION_ROUTE } = require('../../routes')
-const Identicon = require('../identicon')
const NetworkIndicator = require('../network')
export default class AppHeader extends PureComponent {
diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js
index e1fcf08e0..0f8514c81 100644
--- a/ui/app/components/balance-component.js
+++ b/ui/app/components/balance-component.js
@@ -2,11 +2,11 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const inherits = require('util').inherits
-const TokenBalance = require('./token-balance')
-const Identicon = require('./identicon')
+import TokenBalance from './token-balance'
+import Identicon from './identicon'
import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../constants/common'
-const { getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors')
+const { getNativeCurrency, getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors')
const { formatBalance } = require('../util')
@@ -21,6 +21,7 @@ function mapStateToProps (state) {
return {
account,
network,
+ nativeCurrency: getNativeCurrency(state),
conversionRate: conversionRateSelector(state),
currentCurrency: getCurrentCurrency(state),
assetImages: getAssetImages(state),
@@ -66,10 +67,10 @@ BalanceComponent.prototype.renderTokenBalance = function () {
BalanceComponent.prototype.renderBalance = function () {
const props = this.props
- const { account } = props
+ const { account, nativeCurrency } = props
const balanceValue = account && account.balance
const needsParse = 'needsParse' in props ? props.needsParse : true
- const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse) : '...'
+ const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse, nativeCurrency) : '...'
const showFiat = 'showFiat' in props ? props.showFiat : true
if (formattedBalance === 'None' || formattedBalance === '...') {
@@ -81,11 +82,12 @@ BalanceComponent.prototype.renderBalance = function () {
}
return h('div.flex-column.balance-display', {}, [
- h('div.token-amount', {}, h(UserPreferencedCurrencyDisplay, {
+ h(UserPreferencedCurrencyDisplay, {
+ className: 'token-amount',
value: balanceValue,
type: PRIMARY,
ethNumberOfDecimals: 3,
- })),
+ }),
showFiat && h(UserPreferencedCurrencyDisplay, {
value: balanceValue,
diff --git a/ui/app/components/currency-display/currency-display.component.js b/ui/app/components/currency-display/currency-display.component.js
index 5f5717be3..2d7413b57 100644
--- a/ui/app/components/currency-display/currency-display.component.js
+++ b/ui/app/components/currency-display/currency-display.component.js
@@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
-import { ETH, GWEI } from '../../constants/common'
+import { GWEI } from '../../constants/common'
export default class CurrencyDisplay extends PureComponent {
static propTypes = {
@@ -10,8 +10,9 @@ export default class CurrencyDisplay extends PureComponent {
prefix: PropTypes.string,
prefixComponent: PropTypes.node,
style: PropTypes.object,
+ suffix: PropTypes.string,
// Used in container
- currency: PropTypes.oneOf([ETH]),
+ currency: PropTypes.string,
denomination: PropTypes.oneOf([GWEI]),
value: PropTypes.string,
numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -19,17 +20,25 @@ export default class CurrencyDisplay extends PureComponent {
}
render () {
- const { className, displayValue, prefix, prefixComponent, style } = this.props
+ const { className, displayValue, prefix, prefixComponent, style, suffix } = this.props
const text = `${prefix || ''}${displayValue}`
+ const title = `${text} ${suffix}`
return (
<div
className={classnames('currency-display-component', className)}
style={style}
- title={text}
+ title={title}
>
{ prefixComponent}
<span className="currency-display-component__text">{ text }</span>
+ {
+ suffix && (
+ <span className="currency-display-component__suffix">
+ { suffix }
+ </span>
+ )
+ }
</div>
)
}
diff --git a/ui/app/components/currency-display/currency-display.container.js b/ui/app/components/currency-display/currency-display.container.js
index b387229b5..6ddf07172 100644
--- a/ui/app/components/currency-display/currency-display.container.js
+++ b/ui/app/components/currency-display/currency-display.container.js
@@ -3,16 +3,17 @@ import CurrencyDisplay from './currency-display.component'
import { getValueFromWeiHex, formatCurrency } from '../../helpers/confirm-transaction/util'
const mapStateToProps = state => {
- const { metamask: { currentCurrency, conversionRate } } = state
+ const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state
return {
currentCurrency,
conversionRate,
+ nativeCurrency,
}
}
const mergeProps = (stateProps, dispatchProps, ownProps) => {
- const { currentCurrency, conversionRate, ...restStateProps } = stateProps
+ const { nativeCurrency, currentCurrency, conversionRate, ...restStateProps } = stateProps
const {
value,
numberOfDecimals = 2,
@@ -24,16 +25,17 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
const toCurrency = currency || currentCurrency
const convertedValue = getValueFromWeiHex({
- value, toCurrency, conversionRate, numberOfDecimals, toDenomination: denomination,
+ value, fromCurrency: nativeCurrency, toCurrency, conversionRate, numberOfDecimals, toDenomination: denomination,
})
- const formattedValue = formatCurrency(convertedValue, toCurrency)
- const displayValue = hideLabel ? formattedValue : `${formattedValue} ${toCurrency.toUpperCase()}`
+ const displayValue = formatCurrency(convertedValue, toCurrency)
+ const suffix = hideLabel ? undefined : toCurrency.toUpperCase()
return {
...restStateProps,
...dispatchProps,
...restOwnProps,
displayValue,
+ suffix,
}
}
diff --git a/ui/app/components/currency-display/index.scss b/ui/app/components/currency-display/index.scss
index 8c0196102..313c932b8 100644
--- a/ui/app/components/currency-display/index.scss
+++ b/ui/app/components/currency-display/index.scss
@@ -7,4 +7,8 @@
overflow: hidden;
text-overflow: ellipsis;
}
+
+ &__suffix {
+ padding-left: 4px;
+ }
}
diff --git a/ui/app/components/currency-display/tests/currency-display.container.test.js b/ui/app/components/currency-display/tests/currency-display.container.test.js
index b9f98c543..0c886af50 100644
--- a/ui/app/components/currency-display/tests/currency-display.container.test.js
+++ b/ui/app/components/currency-display/tests/currency-display.container.test.js
@@ -20,12 +20,14 @@ describe('CurrencyDisplay container', () => {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
},
}
assert.deepEqual(mapStateToProps(mockState), {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
})
})
})
@@ -35,6 +37,7 @@ describe('CurrencyDisplay container', () => {
const mockStateProps = {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
}
const tests = [
@@ -43,71 +46,93 @@ describe('CurrencyDisplay container', () => {
value: '0x2386f26fc10000',
numberOfDecimals: 2,
currency: 'usd',
+ nativeCurrency: 'ETH',
},
result: {
- displayValue: '$2.80 USD',
+ displayValue: '$2.80',
+ suffix: 'USD',
+ nativeCurrency: 'ETH',
},
},
{
props: {
value: '0x2386f26fc10000',
+ currency: 'usd',
+ nativeCurrency: 'ETH',
},
result: {
- displayValue: '$2.80 USD',
+ displayValue: '$2.80',
+ suffix: 'USD',
+ nativeCurrency: 'ETH',
},
},
{
props: {
value: '0x1193461d01595930',
currency: 'ETH',
+ nativeCurrency: 'ETH',
numberOfDecimals: 3,
},
result: {
- displayValue: '1.266 ETH',
+ displayValue: '1.266',
+ suffix: 'ETH',
+ nativeCurrency: 'ETH',
},
},
{
props: {
value: '0x1193461d01595930',
currency: 'ETH',
+ nativeCurrency: 'ETH',
numberOfDecimals: 3,
hideLabel: true,
},
result: {
+ nativeCurrency: 'ETH',
displayValue: '1.266',
+ suffix: undefined,
},
},
{
props: {
value: '0x3b9aca00',
currency: 'ETH',
+ nativeCurrency: 'ETH',
denomination: 'GWEI',
hideLabel: true,
},
result: {
+ nativeCurrency: 'ETH',
displayValue: '1',
+ suffix: undefined,
},
},
{
props: {
value: '0x3b9aca00',
currency: 'ETH',
+ nativeCurrency: 'ETH',
denomination: 'WEI',
hideLabel: true,
},
result: {
+ nativeCurrency: 'ETH',
displayValue: '1000000000',
+ suffix: undefined,
},
},
{
props: {
value: '0x3b9aca00',
currency: 'ETH',
+ nativeCurrency: 'ETH',
numberOfDecimals: 100,
hideLabel: true,
},
result: {
+ nativeCurrency: 'ETH',
displayValue: '1e-9',
+ suffix: undefined,
},
},
]
diff --git a/ui/app/components/currency-input/currency-input.component.js b/ui/app/components/currency-input/currency-input.component.js
index 54cd0e1ac..0761a75c5 100644
--- a/ui/app/components/currency-input/currency-input.component.js
+++ b/ui/app/components/currency-input/currency-input.component.js
@@ -14,6 +14,7 @@ export default class CurrencyInput extends PureComponent {
static propTypes = {
conversionRate: PropTypes.number,
currentCurrency: PropTypes.string,
+ nativeCurrency: PropTypes.string,
onChange: PropTypes.func,
onBlur: PropTypes.func,
suffix: PropTypes.string,
@@ -77,13 +78,13 @@ export default class CurrencyInput extends PureComponent {
}
renderConversionComponent () {
- const { useFiat, currentCurrency } = this.props
+ const { useFiat, currentCurrency, nativeCurrency } = this.props
const { hexValue } = this.state
let currency, numberOfDecimals
if (useFiat) {
// Display ETH
- currency = ETH
+ currency = nativeCurrency || ETH
numberOfDecimals = 6
} else {
// Display Fiat
diff --git a/ui/app/components/currency-input/currency-input.container.js b/ui/app/components/currency-input/currency-input.container.js
index 18e5533de..1d1ed7b41 100644
--- a/ui/app/components/currency-input/currency-input.container.js
+++ b/ui/app/components/currency-input/currency-input.container.js
@@ -3,18 +3,19 @@ import CurrencyInput from './currency-input.component'
import { ETH } from '../../constants/common'
const mapStateToProps = state => {
- const { metamask: { currentCurrency, conversionRate } } = state
+ const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state
return {
+ nativeCurrency,
currentCurrency,
conversionRate,
}
}
const mergeProps = (stateProps, dispatchProps, ownProps) => {
- const { currentCurrency } = stateProps
+ const { nativeCurrency, currentCurrency } = stateProps
const { useFiat } = ownProps
- const suffix = useFiat ? currentCurrency.toUpperCase() : ETH
+ const suffix = useFiat ? currentCurrency.toUpperCase() : nativeCurrency || ETH
return {
...stateProps,
diff --git a/ui/app/components/currency-input/tests/currency-input.component.test.js b/ui/app/components/currency-input/tests/currency-input.component.test.js
index 8de0ef863..a33889f94 100644
--- a/ui/app/components/currency-input/tests/currency-input.component.test.js
+++ b/ui/app/components/currency-input/tests/currency-input.component.test.js
@@ -22,6 +22,7 @@ describe('CurrencyInput Component', () => {
it('should render properly with a suffix', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -32,6 +33,7 @@ describe('CurrencyInput Component', () => {
<Provider store={store}>
<CurrencyInput
suffix="ETH"
+ nativeCurrency="ETH"
/>
</Provider>
)
@@ -45,6 +47,7 @@ describe('CurrencyInput Component', () => {
it('should render properly with an ETH value', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -56,6 +59,7 @@ describe('CurrencyInput Component', () => {
<CurrencyInput
value="de0b6b3a7640000"
suffix="ETH"
+ nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
/>
@@ -69,12 +73,13 @@ describe('CurrencyInput Component', () => {
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH')
assert.equal(wrapper.find('.unit-input__input').props().value, '1')
- assert.equal(wrapper.find('.currency-display-component').text(), '$231.06 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$231.06USD')
})
it('should render properly with a fiat value', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -87,6 +92,7 @@ describe('CurrencyInput Component', () => {
value="f602f2234d0ea"
suffix="USD"
useFiat
+ nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
/>
@@ -100,7 +106,7 @@ describe('CurrencyInput Component', () => {
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'USD')
assert.equal(wrapper.find('.unit-input__input').props().value, '1')
- assert.equal(wrapper.find('.currency-display-component').text(), '0.004328 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '0.004328ETH')
})
})
@@ -116,6 +122,7 @@ describe('CurrencyInput Component', () => {
it('should call onChange and onBlur on input changes with the hex value for ETH', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -127,6 +134,7 @@ describe('CurrencyInput Component', () => {
onChange={handleChangeSpy}
onBlur={handleBlurSpy}
suffix="ETH"
+ nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
/>
@@ -140,14 +148,14 @@ describe('CurrencyInput Component', () => {
const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance()
assert.equal(currencyInputInstance.state.decimalValue, 0)
assert.equal(currencyInputInstance.state.hexValue, undefined)
- assert.equal(wrapper.find('.currency-display-component').text(), '$0.00 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$0.00USD')
const input = wrapper.find('input')
assert.equal(input.props().value, 0)
input.simulate('change', { target: { value: 1 } })
assert.equal(handleChangeSpy.callCount, 1)
assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000'))
- assert.equal(wrapper.find('.currency-display-component').text(), '$231.06 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$231.06USD')
assert.equal(currencyInputInstance.state.decimalValue, 1)
assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000')
@@ -160,6 +168,7 @@ describe('CurrencyInput Component', () => {
it('should call onChange and onBlur on input changes with the hex value for fiat', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -171,6 +180,7 @@ describe('CurrencyInput Component', () => {
onChange={handleChangeSpy}
onBlur={handleBlurSpy}
suffix="USD"
+ nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
useFiat
@@ -185,14 +195,14 @@ describe('CurrencyInput Component', () => {
const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance()
assert.equal(currencyInputInstance.state.decimalValue, 0)
assert.equal(currencyInputInstance.state.hexValue, undefined)
- assert.equal(wrapper.find('.currency-display-component').text(), '0 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '0ETH')
const input = wrapper.find('input')
assert.equal(input.props().value, 0)
input.simulate('change', { target: { value: 1 } })
assert.equal(handleChangeSpy.callCount, 1)
assert.ok(handleChangeSpy.calledWith('f602f2234d0ea'))
- assert.equal(wrapper.find('.currency-display-component').text(), '0.004328 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '0.004328ETH')
assert.equal(currencyInputInstance.state.decimalValue, 1)
assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea')
@@ -205,6 +215,7 @@ describe('CurrencyInput Component', () => {
it('should change the state and pass in a new decimalValue when props.value changes', () => {
const mockStore = {
metamask: {
+ nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
@@ -216,6 +227,7 @@ describe('CurrencyInput Component', () => {
onChange={handleChangeSpy}
onBlur={handleBlurSpy}
suffix="USD"
+ nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
useFiat
diff --git a/ui/app/components/currency-input/tests/currency-input.container.test.js b/ui/app/components/currency-input/tests/currency-input.container.test.js
index e77945e4d..5d72958e6 100644
--- a/ui/app/components/currency-input/tests/currency-input.container.test.js
+++ b/ui/app/components/currency-input/tests/currency-input.container.test.js
@@ -20,12 +20,14 @@ describe('CurrencyInput container', () => {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
},
}
assert.deepEqual(mapStateToProps(mockState), {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
})
})
})
@@ -35,12 +37,14 @@ describe('CurrencyInput container', () => {
const mockStateProps = {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
}
const mockDispatchProps = {}
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, { useFiat: true }), {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
useFiat: true,
suffix: 'USD',
})
@@ -48,6 +52,7 @@ describe('CurrencyInput container', () => {
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, {}), {
conversionRate: 280.45,
currentCurrency: 'usd',
+ nativeCurrency: 'ETH',
suffix: 'ETH',
})
})
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
index b497f5c09..e6b3e0c0c 100644
--- a/ui/app/components/dropdowns/components/account-dropdowns.js
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -6,7 +6,7 @@ const genAccountLink = require('../../../../lib/account-link.js')
const connect = require('react-redux').connect
const Dropdown = require('./dropdown').Dropdown
const DropdownMenuItem = require('./dropdown').DropdownMenuItem
-const Identicon = require('../../identicon')
+import Identicon from '../../identicon'
const { checksumAddress } = require('../../../util')
const copyToClipboard = require('copy-to-clipboard')
const { formatBalance } = require('../../../util')
@@ -26,14 +26,14 @@ class AccountDropdowns extends Component {
}
renderAccounts () {
- const { identities, accounts, selected, menuItemStyles, actions, keyrings } = this.props
+ const { identities, accounts, selected, menuItemStyles, actions, keyrings, ticker } = this.props
return Object.keys(identities).map((key, index) => {
const identity = identities[key]
const isSelected = identity.address === selected
const balanceValue = accounts[key].balance
- const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...'
+ const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, true, ticker) : '...'
const simpleAddress = identity.address.substring(2).toLowerCase()
const keyring = keyrings.find((kr) => {
@@ -421,6 +421,7 @@ AccountDropdowns.propTypes = {
network: PropTypes.number,
// actions.showExportPrivateKeyModal: ,
style: PropTypes.object,
+ ticker: PropTypes.string,
enableAccountsSelector: PropTypes.bool,
enableAccountOption: PropTypes.bool,
enableAccountOptions: PropTypes.bool,
@@ -458,6 +459,7 @@ const mapDispatchToProps = (dispatch) => {
function mapStateToProps (state) {
return {
+ ticker: state.metamask.ticker,
keyrings: state.metamask.keyrings,
sidebarOpen: state.appState.sidebar.isOpen,
}
diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js
index b252b25d9..d4cc695a6 100644
--- a/ui/app/components/dropdowns/network-dropdown.js
+++ b/ui/app/components/dropdowns/network-dropdown.js
@@ -24,8 +24,9 @@ const notToggleElementClassnames = [
function mapStateToProps (state) {
return {
provider: state.metamask.provider,
- frequentRpcList: state.metamask.frequentRpcList || [],
+ frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
networkDropdownOpen: state.appState.networkDropdownOpen,
+ network: state.metamask.network,
}
}
@@ -40,8 +41,8 @@ function mapDispatchToProps (dispatch) {
setDefaultRpcTarget: type => {
dispatch(actions.setDefaultRpcTarget(type))
},
- setRpcTarget: (target) => {
- dispatch(actions.setRpcTarget(target))
+ setRpcTarget: (target, network, ticker, nickname) => {
+ dispatch(actions.setRpcTarget(target, network, ticker, nickname))
},
delRpcTarget: (target) => {
dispatch(actions.delRpcTarget(target))
@@ -71,7 +72,7 @@ module.exports = compose(
NetworkDropdown.prototype.render = function () {
const props = this.props
const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
- const rpcList = props.frequentRpcList
+ const rpcListDetail = props.frequentRpcListDetail
const isOpen = this.props.networkDropdownOpen
const dropdownMenuItemStyle = {
fontSize: '16px',
@@ -225,7 +226,7 @@ NetworkDropdown.prototype.render = function () {
),
this.renderCustomOption(props.provider),
- this.renderCommonRpc(rpcList, props.provider),
+ this.renderCommonRpc(rpcListDetail, props.provider),
h(
DropdownMenuItem,
@@ -267,28 +268,33 @@ NetworkDropdown.prototype.getNetworkName = function () {
} else if (providerName === 'rinkeby') {
name = this.context.t('rinkeby')
} else {
- name = this.context.t('unknownNetwork')
+ name = provider.nickname || this.context.t('unknownNetwork')
}
return name
}
-NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
+NetworkDropdown.prototype.renderCommonRpc = function (rpcListDetail, provider) {
const props = this.props
- const reversedRpcList = rpcList.slice().reverse()
+ const reversedRpcListDetail = rpcListDetail.slice().reverse()
+ const network = props.network
- return reversedRpcList.map((rpc) => {
+ return reversedRpcListDetail.map((entry) => {
+ const rpc = entry.rpcUrl
+ const ticker = entry.ticker || 'ETH'
+ const nickname = entry.nickname || ''
const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget
if ((rpc === 'http://localhost:8545') || currentRpcTarget) {
return null
} else {
+ const chainId = entry.chainId || network
return h(
DropdownMenuItem,
{
key: `common${rpc}`,
closeMenu: () => this.props.hideNetworkDropdown(),
- onClick: () => props.setRpcTarget(rpc),
+ onClick: () => props.setRpcTarget(rpc, chainId, ticker, nickname),
style: {
fontSize: '16px',
lineHeight: '20px',
@@ -302,7 +308,7 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
style: {
color: currentRpcTarget ? '#ffffff' : '#9b9b9b',
},
- }, rpc),
+ }, nickname || rpc),
h('i.fa.fa-times.delete',
{
onClick: (e) => {
@@ -317,8 +323,9 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
}
NetworkDropdown.prototype.renderCustomOption = function (provider) {
- const { rpcTarget, type } = provider
+ const { rpcTarget, type, ticker, nickname } = provider
const props = this.props
+ const network = props.network
if (type !== 'rpc') return null
@@ -332,7 +339,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
DropdownMenuItem,
{
key: rpcTarget,
- onClick: () => props.setRpcTarget(rpcTarget),
+ onClick: () => props.setRpcTarget(rpcTarget, network, ticker, nickname),
closeMenu: () => this.props.hideNetworkDropdown(),
style: {
fontSize: '16px',
@@ -347,7 +354,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
style: {
color: '#ffffff',
},
- }, rpcTarget),
+ }, nickname || rpcTarget),
]
)
}
diff --git a/ui/app/components/dropdowns/tests/network-dropdown.test.js b/ui/app/components/dropdowns/tests/network-dropdown.test.js
index 699b54605..88ad56851 100644
--- a/ui/app/components/dropdowns/tests/network-dropdown.test.js
+++ b/ui/app/components/dropdowns/tests/network-dropdown.test.js
@@ -45,8 +45,8 @@ describe('Network Dropdown', () => {
provider: {
'type': 'test',
},
- frequentRpcList: [
- 'http://localhost:7545',
+ frequentRpcListDetail: [
+ { rpcUrl: 'http://localhost:7545' },
],
},
appState: {
diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js
index c3d084bdc..2f6395a2d 100644
--- a/ui/app/components/eth-balance.js
+++ b/ui/app/components/eth-balance.js
@@ -1,5 +1,6 @@
const { Component } = require('react')
const h = require('react-hyperscript')
+const connect = require('react-redux').connect
const { inherits } = require('util')
const {
formatBalance,
@@ -8,7 +9,12 @@ const {
const Tooltip = require('./tooltip.js')
const FiatValue = require('./fiat-value.js')
-module.exports = EthBalanceComponent
+module.exports = connect(mapStateToProps)(EthBalanceComponent)
+function mapStateToProps (state) {
+ return {
+ ticker: state.metamask.ticker,
+ }
+}
inherits(EthBalanceComponent, Component)
function EthBalanceComponent () {
@@ -17,9 +23,9 @@ function EthBalanceComponent () {
EthBalanceComponent.prototype.render = function () {
const props = this.props
- const { value, style, width, needsParse = true } = props
+ const { ticker, value, style, width, needsParse = true } = props
- const formattedValue = value ? formatBalance(value, 6, needsParse) : '...'
+ const formattedValue = value ? formatBalance(value, 6, needsParse, ticker) : '...'
return (
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
deleted file mode 100644
index 7bd921892..000000000
--- a/ui/app/components/identicon.js
+++ /dev/null
@@ -1,124 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const isNode = require('detect-node')
-const findDOMNode = require('react-dom').findDOMNode
-const jazzicon = require('jazzicon')
-const iconFactoryGen = require('../../lib/icon-factory')
-const iconFactory = iconFactoryGen(jazzicon)
-const { toDataUrl } = require('../../lib/blockies')
-
-module.exports = connect(mapStateToProps)(IdenticonComponent)
-
-inherits(IdenticonComponent, Component)
-function IdenticonComponent () {
- Component.call(this)
-
- this.defaultDiameter = 46
-}
-
-function mapStateToProps (state) {
- return {
- useBlockie: state.metamask.useBlockie,
- }
-}
-
-IdenticonComponent.prototype.render = function () {
- var props = this.props
- const { className = '', address, image } = props
- var diameter = props.diameter || this.defaultDiameter
- const style = {
- height: diameter,
- width: diameter,
- borderRadius: diameter / 2,
- }
- if (image) {
- return h('img', {
- className: `${className} identicon`,
- src: image,
- style: {
- ...style,
- },
- })
- } else if (address) {
- return h('div', {
- className: `${className} identicon`,
- key: 'identicon-' + address,
- style: {
- display: 'flex',
- flexShrink: 0,
- alignItems: 'center',
- justifyContent: 'center',
- ...style,
- overflow: 'hidden',
- },
- })
- } else {
- return h('img.balance-icon', {
- className,
- src: './images/eth_logo.svg',
- style: {
- ...style,
- },
- })
- }
-}
-
-IdenticonComponent.prototype.componentDidMount = function () {
- var props = this.props
- const { address, useBlockie } = props
-
- if (!address) return
-
- if (!isNode) {
- // eslint-disable-next-line react/no-find-dom-node
- var container = findDOMNode(this)
-
- const diameter = props.diameter || this.defaultDiameter
-
- if (useBlockie) {
- _generateBlockie(container, address, diameter)
- } else {
- _generateJazzicon(container, address, diameter)
- }
- }
-}
-
-IdenticonComponent.prototype.componentDidUpdate = function () {
- var props = this.props
- const { address, useBlockie } = props
-
- if (!address) return
-
- if (!isNode) {
- // eslint-disable-next-line react/no-find-dom-node
- var container = findDOMNode(this)
-
- var children = container.children
- for (var i = 0; i < children.length; i++) {
- container.removeChild(children[i])
- }
-
- const diameter = props.diameter || this.defaultDiameter
-
- if (useBlockie) {
- _generateBlockie(container, address, diameter)
- } else {
- _generateJazzicon(container, address, diameter)
- }
- }
-}
-
-function _generateBlockie (container, address, diameter) {
- const img = new Image()
- img.src = toDataUrl(address)
- img.height = diameter
- img.width = diameter
- container.appendChild(img)
-}
-
-function _generateJazzicon (container, address, diameter) {
- const img = iconFactory.iconForAddress(address, diameter)
- container.appendChild(img)
-}
diff --git a/ui/app/components/identicon/identicon.component.js b/ui/app/components/identicon/identicon.component.js
new file mode 100644
index 000000000..b892e5ae5
--- /dev/null
+++ b/ui/app/components/identicon/identicon.component.js
@@ -0,0 +1,99 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import classnames from 'classnames'
+import { toDataUrl } from '../../../lib/blockies'
+import contractMap from 'eth-contract-metadata'
+import { checksumAddress } from '../../../app/util'
+import Jazzicon from '../jazzicon'
+
+const getStyles = diameter => (
+ {
+ height: diameter,
+ width: diameter,
+ borderRadius: diameter / 2,
+ }
+)
+
+export default class Identicon extends PureComponent {
+ static propTypes = {
+ address: PropTypes.string,
+ className: PropTypes.string,
+ diameter: PropTypes.number,
+ image: PropTypes.string,
+ useBlockie: PropTypes.bool,
+ }
+
+ static defaultProps = {
+ diameter: 46,
+ }
+
+ renderImage () {
+ const { className, diameter, image } = this.props
+
+ return (
+ <img
+ className={classnames('identicon', className)}
+ src={image}
+ style={getStyles(diameter)}
+ />
+ )
+ }
+
+ renderJazzicon () {
+ const { address, className, diameter } = this.props
+
+ return (
+ <Jazzicon
+ address={address}
+ diameter={diameter}
+ className={classnames('identicon', className)}
+ style={getStyles(diameter)}
+ />
+ )
+ }
+
+ renderBlockie () {
+ const { address, className, diameter } = this.props
+
+ return (
+ <div
+ className={classnames('identicon', className)}
+ style={getStyles(diameter)}
+ >
+ <img
+ src={toDataUrl(address)}
+ height={diameter}
+ width={diameter}
+ />
+ </div>
+ )
+ }
+
+ render () {
+ const { className, address, image, diameter, useBlockie } = this.props
+
+ if (image) {
+ return this.renderImage()
+ }
+
+ if (address) {
+ const checksummedAddress = checksumAddress(address)
+
+ if (contractMap[checksummedAddress] && contractMap[checksummedAddress].logo) {
+ return this.renderJazzicon()
+ }
+
+ return useBlockie
+ ? this.renderBlockie()
+ : this.renderJazzicon()
+ }
+
+ return (
+ <img
+ className={classnames('balance-icon', className)}
+ src="./images/eth_logo.svg"
+ style={getStyles(diameter)}
+ />
+ )
+ }
+}
diff --git a/ui/app/components/identicon/identicon.container.js b/ui/app/components/identicon/identicon.container.js
new file mode 100644
index 000000000..bc49bc18e
--- /dev/null
+++ b/ui/app/components/identicon/identicon.container.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux'
+import Identicon from './identicon.component'
+
+const mapStateToProps = state => {
+ const { metamask: { useBlockie } } = state
+
+ return {
+ useBlockie,
+ }
+}
+
+export default connect(mapStateToProps)(Identicon)
diff --git a/ui/app/components/identicon/index.js b/ui/app/components/identicon/index.js
new file mode 100644
index 000000000..799c886f2
--- /dev/null
+++ b/ui/app/components/identicon/index.js
@@ -0,0 +1 @@
+export { default } from './identicon.container'
diff --git a/ui/app/components/identicon/index.scss b/ui/app/components/identicon/index.scss
new file mode 100644
index 000000000..657afc48f
--- /dev/null
+++ b/ui/app/components/identicon/index.scss
@@ -0,0 +1,7 @@
+.identicon {
+ display: flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+}
diff --git a/ui/app/components/identicon/tests/identicon.component.test.js b/ui/app/components/identicon/tests/identicon.component.test.js
new file mode 100644
index 000000000..2944818f5
--- /dev/null
+++ b/ui/app/components/identicon/tests/identicon.component.test.js
@@ -0,0 +1,51 @@
+import React from 'react'
+import assert from 'assert'
+import thunk from 'redux-thunk'
+import configureMockStore from 'redux-mock-store'
+import { mount } from 'enzyme'
+import Identicon from '../identicon.component'
+
+describe('Identicon', () => {
+ const state = {
+ metamask: {
+ useBlockie: false,
+ },
+ }
+
+ const middlewares = [thunk]
+ const mockStore = configureMockStore(middlewares)
+ const store = mockStore(state)
+
+ it('renders default eth_logo identicon with no props', () => {
+ const wrapper = mount(
+ <Identicon store={store}/>
+ )
+
+ assert.equal(wrapper.find('img.balance-icon').prop('src'), './images/eth_logo.svg')
+ })
+
+ it('renders custom image and add className props', () => {
+ const wrapper = mount(
+ <Identicon
+ store={store}
+ className="test-image"
+ image="test-image"
+ />
+ )
+
+ assert.equal(wrapper.find('img.test-image').prop('className'), 'identicon test-image')
+ assert.equal(wrapper.find('img.test-image').prop('src'), 'test-image')
+ })
+
+ it('renders div with address prop', () => {
+ const wrapper = mount(
+ <Identicon
+ store={store}
+ className="test-address"
+ address="0xTest"
+ />
+ )
+
+ assert.equal(wrapper.find('div.test-address').prop('className'), 'identicon test-address')
+ })
+})
diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss
index beffdb221..e27b0f182 100644
--- a/ui/app/components/index.scss
+++ b/ui/app/components/index.scss
@@ -16,6 +16,8 @@
@import './export-text-container/index';
+@import './identicon/index';
+
@import './info-box/index';
@import './menu-bar/index';
@@ -30,6 +32,8 @@
@import './pages/index';
+@import './provider-page-container/index';
+
@import './selected-account/index';
@import './sender-to-recipient/index';
diff --git a/ui/app/components/jazzicon/index.js b/ui/app/components/jazzicon/index.js
new file mode 100644
index 000000000..bea900ab9
--- /dev/null
+++ b/ui/app/components/jazzicon/index.js
@@ -0,0 +1 @@
+export { default } from './jazzicon.component'
diff --git a/ui/app/components/jazzicon/jazzicon.component.js b/ui/app/components/jazzicon/jazzicon.component.js
new file mode 100644
index 000000000..fcb1c59b1
--- /dev/null
+++ b/ui/app/components/jazzicon/jazzicon.component.js
@@ -0,0 +1,69 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import isNode from 'detect-node'
+import { findDOMNode } from 'react-dom'
+import jazzicon from 'jazzicon'
+import iconFactoryGenerator from '../../../lib/icon-factory'
+const iconFactory = iconFactoryGenerator(jazzicon)
+
+/**
+ * Wrapper around the jazzicon library to return a React component, as the library returns an
+ * HTMLDivElement which needs to be appended.
+ */
+export default class Jazzicon extends PureComponent {
+ static propTypes = {
+ address: PropTypes.string.isRequired,
+ className: PropTypes.string,
+ diameter: PropTypes.number,
+ style: PropTypes.object,
+ }
+
+ static defaultProps = {
+ diameter: 46,
+ }
+
+ componentDidMount () {
+ if (!isNode) {
+ this.appendJazzicon()
+ }
+ }
+
+ componentDidUpdate (prevProps) {
+ const { address: prevAddress } = prevProps
+ const { address } = this.props
+
+ if (!isNode && address !== prevAddress) {
+ this.removeExistingChildren()
+ this.appendJazzicon()
+ }
+ }
+
+ removeExistingChildren () {
+ // eslint-disable-next-line react/no-find-dom-node
+ const container = findDOMNode(this)
+ const { children } = container
+
+ for (let i = 0; i < children.length; i++) {
+ container.removeChild(children[i])
+ }
+ }
+
+ appendJazzicon () {
+ // eslint-disable-next-line react/no-find-dom-node
+ const container = findDOMNode(this)
+ const { address, diameter } = this.props
+ const image = iconFactory.iconForAddress(address, diameter)
+ container.appendChild(image)
+ }
+
+ render () {
+ const { className, style } = this.props
+
+ return (
+ <div
+ className={className}
+ style={style}
+ />
+ )
+ }
+}
diff --git a/ui/app/components/modals/account-modal-container.js b/ui/app/components/modals/account-modal-container.js
index aa0593df8..2a6c655e1 100644
--- a/ui/app/components/modals/account-modal-container.js
+++ b/ui/app/components/modals/account-modal-container.js
@@ -5,7 +5,7 @@ const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../actions')
const { getSelectedIdentity } = require('../../selectors')
-const Identicon = require('../identicon')
+import Identicon from '../identicon'
function mapStateToProps (state, ownProps) {
return {
diff --git a/ui/app/components/modals/clear-approved-origins/clear-approved-origins.component.js b/ui/app/components/modals/clear-approved-origins/clear-approved-origins.component.js
new file mode 100644
index 000000000..ceaa20a95
--- /dev/null
+++ b/ui/app/components/modals/clear-approved-origins/clear-approved-origins.component.js
@@ -0,0 +1,39 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import Modal, { ModalContent } from '../../modal'
+
+export default class ClearApprovedOrigins extends PureComponent {
+ static propTypes = {
+ hideModal: PropTypes.func.isRequired,
+ clearApprovedOrigins: PropTypes.func.isRequired,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ handleClear = () => {
+ const { clearApprovedOrigins, hideModal } = this.props
+ clearApprovedOrigins()
+ hideModal()
+ }
+
+ render () {
+ const { t } = this.context
+
+ return (
+ <Modal
+ onSubmit={this.handleClear}
+ onCancel={() => this.props.hideModal()}
+ submitText={t('ok')}
+ cancelText={t('nevermind')}
+ submitType="secondary"
+ >
+ <ModalContent
+ title={t('clearApprovalData')}
+ description={t('confirmClear')}
+ />
+ </Modal>
+ )
+ }
+}
diff --git a/ui/app/components/modals/clear-approved-origins/clear-approved-origins.container.js b/ui/app/components/modals/clear-approved-origins/clear-approved-origins.container.js
new file mode 100644
index 000000000..3a801a062
--- /dev/null
+++ b/ui/app/components/modals/clear-approved-origins/clear-approved-origins.container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux'
+import { compose } from 'recompose'
+import withModalProps from '../../../higher-order-components/with-modal-props'
+import ClearApprovedOriginsComponent from './clear-approved-origins.component'
+import { clearApprovedOrigins } from '../../../actions'
+
+const mapDispatchToProps = dispatch => {
+ return {
+ clearApprovedOrigins: () => dispatch(clearApprovedOrigins()),
+ }
+}
+
+export default compose(
+ withModalProps,
+ connect(null, mapDispatchToProps)
+)(ClearApprovedOriginsComponent)
diff --git a/ui/app/components/modals/clear-approved-origins/index.js b/ui/app/components/modals/clear-approved-origins/index.js
new file mode 100644
index 000000000..b3e321995
--- /dev/null
+++ b/ui/app/components/modals/clear-approved-origins/index.js
@@ -0,0 +1 @@
+export { default } from './clear-approved-origins.container'
diff --git a/ui/app/components/modals/hide-token-confirmation-modal.js b/ui/app/components/modals/hide-token-confirmation-modal.js
index fb38516d3..43f3009a5 100644
--- a/ui/app/components/modals/hide-token-confirmation-modal.js
+++ b/ui/app/components/modals/hide-token-confirmation-modal.js
@@ -4,7 +4,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../actions')
-const Identicon = require('../identicon')
+import Identicon from '../identicon'
function mapStateToProps (state) {
return {
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
index 15ca9deaa..5aff4f5e1 100644
--- a/ui/app/components/modals/modal.js
+++ b/ui/app/components/modals/modal.js
@@ -27,8 +27,8 @@ import TransactionConfirmed from './transaction-confirmed'
import ConfirmCustomizeGasModal from './customize-gas'
import CancelTransaction from './cancel-transaction'
import WelcomeBeta from './welcome-beta'
-import TransactionDetails from './transaction-details'
import RejectTransactions from './reject-transactions'
+import ClearApprovedOrigins from './clear-approved-origins'
const modalContainerBaseStyle = {
transform: 'translate3d(-50%, 0, 0px)',
@@ -213,6 +213,19 @@ const MODALS = {
},
},
+ CLEAR_APPROVED_ORIGINS: {
+ contents: h(ClearApprovedOrigins),
+ mobileModalStyle: {
+ ...modalContainerMobileStyle,
+ },
+ laptopModalStyle: {
+ ...modalContainerLaptopStyle,
+ },
+ contentStyle: {
+ borderRadius: '8px',
+ },
+ },
+
OLD_UI_NOTIFICATION_MODAL: {
contents: [
h(NotifcationModal, {
@@ -366,19 +379,6 @@ const MODALS = {
},
},
- TRANSACTION_DETAILS: {
- contents: h(TransactionDetails),
- mobileModalStyle: {
- ...modalContainerMobileStyle,
- },
- laptopModalStyle: {
- ...modalContainerLaptopStyle,
- },
- contentStyle: {
- borderRadius: '8px',
- },
- },
-
REJECT_TRANSACTIONS: {
contents: h(RejectTransactions),
mobileModalStyle: {
diff --git a/ui/app/components/modals/transaction-details/index.js b/ui/app/components/modals/transaction-details/index.js
deleted file mode 100644
index 1fc42c662..000000000
--- a/ui/app/components/modals/transaction-details/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './transaction-details.container'
diff --git a/ui/app/components/modals/transaction-details/transaction-details.component.js b/ui/app/components/modals/transaction-details/transaction-details.component.js
deleted file mode 100644
index f2fec3409..000000000
--- a/ui/app/components/modals/transaction-details/transaction-details.component.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import React, { PureComponent } from 'react'
-import PropTypes from 'prop-types'
-import Modal from '../../modal'
-import TransactionListItemDetails from '../../transaction-list-item-details'
-import { hexToDecimal } from '../../../helpers/conversions.util'
-
-export default class TransactionConfirmed extends PureComponent {
- static contextTypes = {
- t: PropTypes.func,
- }
-
- static propTypes = {
- hideModal: PropTypes.func,
- transaction: PropTypes.object,
- onRetry: PropTypes.func,
- showRetry: PropTypes.bool,
- onCancel: PropTypes.func,
- showCancel: PropTypes.bool,
- }
-
- handleSubmit = () => {
- this.props.hideModal()
- }
-
- handleRetry = () => {
- const { onRetry, hideModal } = this.props
-
- Promise.resolve(onRetry()).then(() => hideModal())
- }
-
- render () {
- const { t } = this.context
- const { transaction, showRetry, onCancel, showCancel } = this.props
- const { txParams: { nonce } = {} } = transaction
- const decimalNonce = nonce && hexToDecimal(nonce)
-
- return (
- <Modal
- onSubmit={this.handleSubmit}
- onClose={this.handleSubmit}
- submitText={t('ok')}
- headerText={t('transactionWithNonce', [`#${decimalNonce}`])}
- >
- <TransactionListItemDetails
- transaction={transaction}
- onRetry={this.handleRetry}
- showRetry={showRetry}
- onCancel={() => onCancel()}
- showCancel={showCancel}
- />
- </Modal>
- )
- }
-}
diff --git a/ui/app/components/modals/transaction-details/transaction-details.container.js b/ui/app/components/modals/transaction-details/transaction-details.container.js
deleted file mode 100644
index f212920bb..000000000
--- a/ui/app/components/modals/transaction-details/transaction-details.container.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import TransactionDetails from './transaction-details.component'
-import withModalProps from '../../../higher-order-components/with-modal-props'
-
-export default withModalProps(TransactionDetails)
diff --git a/ui/app/components/network-display/index.scss b/ui/app/components/network-display/index.scss
index 2085cff67..e9f2f2057 100644
--- a/ui/app/components/network-display/index.scss
+++ b/ui/app/components/network-display/index.scss
@@ -3,11 +3,14 @@
display: flex;
align-items: center;
justify-content: flex-start;
- background-color: lighten(rgb(125, 128, 130), 45%);
padding: 0 10px;
border-radius: 4px;
height: 25px;
+ &--colored {
+ background-color: lighten(rgb(125, 128, 130), 45%);
+ }
+
&--mainnet {
background-color: lighten($blue-lagoon, 68%);
}
diff --git a/ui/app/components/network-display/network-display.component.js b/ui/app/components/network-display/network-display.component.js
index 38626af20..22d617099 100644
--- a/ui/app/components/network-display/network-display.component.js
+++ b/ui/app/components/network-display/network-display.component.js
@@ -16,7 +16,12 @@ const networkToClassHash = {
}
export default class NetworkDisplay extends Component {
+ static defaultProps = {
+ colored: true,
+ }
+
static propTypes = {
+ colored: PropTypes.bool,
network: PropTypes.string,
provider: PropTypes.object,
}
@@ -41,14 +46,16 @@ export default class NetworkDisplay extends Component {
}
render () {
- const { network, provider: { type } } = this.props
+ const { colored, network, provider: { type, nickname } } = this.props
const networkClass = networkToClassHash[network]
return (
- <div className={classnames(
- 'network-display__container',
- networkClass && ('network-display__container--' + networkClass)
- )}>
+ <div
+ className={classnames('network-display__container', {
+ 'network-display__container--colored': colored,
+ ['network-display__container--' + networkClass]: colored && networkClass,
+ })}
+ >
{
networkClass
? <div className={`network-display__icon network-display__icon--${networkClass}`} />
@@ -61,7 +68,7 @@ export default class NetworkDisplay extends Component {
/>
}
<div className="network-display__name">
- { this.context.t(type) }
+ { type === 'rpc' && nickname ? nickname : this.context.t(type) }
</div>
</div>
)
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 83297c4f2..611aadb7b 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -23,9 +23,10 @@ Network.prototype.render = function () {
const props = this.props
const context = this.context
const networkNumber = props.network
- let providerName
+ let providerName, providerNick
try {
providerName = props.provider.type
+ providerNick = props.provider.nickname || ''
} catch (e) {
providerName = null
}
@@ -131,7 +132,7 @@ Network.prototype.render = function () {
},
}),
- h('.network-name', context.t('privateNetwork')),
+ h('.network-name', providerNick || context.t('privateNetwork')),
h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
}
diff --git a/ui/app/components/page-container/index.scss b/ui/app/components/page-container/index.scss
index 6742e3082..ba1215e84 100644
--- a/ui/app/components/page-container/index.scss
+++ b/ui/app/components/page-container/index.scss
@@ -101,6 +101,7 @@
font-size: 2rem;
font-weight: 500;
line-height: 2rem;
+ margin-right: 1.5rem;
}
&__subtitle {
diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
index c92867afe..7d01aaffb 100644
--- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
+++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
@@ -136,7 +136,7 @@ export default class ConfirmTransactionBase extends Component {
if (simulationFails) {
return {
valid: true,
- errorKey: TRANSACTION_ERROR_KEY,
+ errorKey: simulationFails.errorKey ? simulationFails.errorKey : TRANSACTION_ERROR_KEY,
}
}
diff --git a/ui/app/components/pages/home/home.component.js b/ui/app/components/pages/home/home.component.js
index d3c71c4f6..b9ec3c258 100644
--- a/ui/app/components/pages/home/home.component.js
+++ b/ui/app/components/pages/home/home.component.js
@@ -4,6 +4,8 @@ import Media from 'react-media'
import { Redirect } from 'react-router-dom'
import WalletView from '../../wallet-view'
import TransactionView from '../../transaction-view'
+import ProviderApproval from '../provider-approval'
+
import {
INITIALIZE_BACKUP_PHRASE_ROUTE,
RESTORE_VAULT_ROUTE,
@@ -21,6 +23,7 @@ export default class Home extends PureComponent {
seedWords: PropTypes.string,
suggestedTokens: PropTypes.object,
unconfirmedTransactionsCount: PropTypes.number,
+ providerRequests: PropTypes.array,
}
componentDidMount () {
@@ -46,6 +49,7 @@ export default class Home extends PureComponent {
lostAccounts,
forgottenPassword,
seedWords,
+ providerRequests,
} = this.props
// notices
@@ -62,6 +66,12 @@ export default class Home extends PureComponent {
return <Redirect to={{ pathname: RESTORE_VAULT_ROUTE }} />
}
+ if (providerRequests && providerRequests.length > 0) {
+ return (
+ <ProviderApproval providerRequest={providerRequests[0]} />
+ )
+ }
+
return (
<div className="main-container">
<div className="account-and-transaction-details">
diff --git a/ui/app/components/pages/home/home.container.js b/ui/app/components/pages/home/home.container.js
index 58001df6b..bb8cf5e81 100644
--- a/ui/app/components/pages/home/home.container.js
+++ b/ui/app/components/pages/home/home.container.js
@@ -11,6 +11,7 @@ const mapStateToProps = state => {
lostAccounts,
seedWords,
suggestedTokens,
+ providerRequests,
} = metamask
const { forgottenPassword } = appState
@@ -21,6 +22,7 @@ const mapStateToProps = state => {
seedWords,
suggestedTokens,
unconfirmedTransactionsCount: unconfirmedTransactionsCountSelector(state),
+ providerRequests,
}
}
diff --git a/ui/app/components/pages/provider-approval/index.js b/ui/app/components/pages/provider-approval/index.js
new file mode 100644
index 000000000..4162f3155
--- /dev/null
+++ b/ui/app/components/pages/provider-approval/index.js
@@ -0,0 +1 @@
+export { default } from './provider-approval.container'
diff --git a/ui/app/components/pages/provider-approval/provider-approval.component.js b/ui/app/components/pages/provider-approval/provider-approval.component.js
new file mode 100644
index 000000000..da98bc3fc
--- /dev/null
+++ b/ui/app/components/pages/provider-approval/provider-approval.component.js
@@ -0,0 +1,28 @@
+import PropTypes from 'prop-types'
+import React, { Component } from 'react'
+import ProviderPageContainer from '../../provider-page-container'
+
+export default class ProviderApproval extends Component {
+ static propTypes = {
+ approveProviderRequest: PropTypes.func.isRequired,
+ providerRequest: PropTypes.object.isRequired,
+ rejectProviderRequest: PropTypes.func.isRequired,
+ };
+
+ static contextTypes = {
+ t: PropTypes.func,
+ };
+
+ render () {
+ const { approveProviderRequest, providerRequest, rejectProviderRequest } = this.props
+ return (
+ <ProviderPageContainer
+ approveProviderRequest={approveProviderRequest}
+ origin={providerRequest.origin}
+ rejectProviderRequest={rejectProviderRequest}
+ siteImage={providerRequest.siteImage}
+ siteTitle={providerRequest.siteTitle}
+ />
+ )
+ }
+}
diff --git a/ui/app/components/pages/provider-approval/provider-approval.container.js b/ui/app/components/pages/provider-approval/provider-approval.container.js
new file mode 100644
index 000000000..b223244a1
--- /dev/null
+++ b/ui/app/components/pages/provider-approval/provider-approval.container.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux'
+import ProviderApproval from './provider-approval.component'
+import { approveProviderRequest, rejectProviderRequest } from '../../../actions'
+
+function mapDispatchToProps (dispatch) {
+ return {
+ approveProviderRequest: origin => dispatch(approveProviderRequest(origin)),
+ rejectProviderRequest: origin => dispatch(rejectProviderRequest(origin)),
+ }
+}
+
+export default connect(null, mapDispatchToProps)(ProviderApproval)
diff --git a/ui/app/components/pages/settings/settings-tab/index.scss b/ui/app/components/pages/settings/settings-tab/index.scss
index 3bf840c86..ef32b0e4c 100644
--- a/ui/app/components/pages/settings/settings-tab/index.scss
+++ b/ui/app/components/pages/settings/settings-tab/index.scss
@@ -5,12 +5,9 @@
color: $crimson;
}
- &__rpc-save-button {
- align-self: flex-end;
- padding: 5px;
- text-transform: uppercase;
- color: $dusty-gray;
- cursor: pointer;
+ &__advanced-link {
+ color: $curious-blue;
+ padding-left: 5px;
}
&__rpc-save-button {
@@ -19,6 +16,9 @@
text-transform: uppercase;
color: $dusty-gray;
cursor: pointer;
+ width: 25%;
+ min-width: 80px;
+ height: 33px;
}
&__button--red {
diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
index a9e2a723e..a0a8ed47e 100644
--- a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
+++ b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
@@ -39,12 +39,15 @@ export default class SettingsTab extends PureComponent {
metamask: PropTypes.object,
setUseBlockie: PropTypes.func,
setHexDataFeatureFlag: PropTypes.func,
+ setPrivacyMode: PropTypes.func,
+ privacyMode: PropTypes.bool,
setCurrentCurrency: PropTypes.func,
setRpcTarget: PropTypes.func,
delRpcTarget: PropTypes.func,
displayWarning: PropTypes.func,
revealSeedConfirmation: PropTypes.func,
setFeatureFlagToBeta: PropTypes.func,
+ showClearApprovalModal: PropTypes.func,
showResetAccountConfirmationModal: PropTypes.func,
warning: PropTypes.string,
history: PropTypes.object,
@@ -55,12 +58,17 @@ export default class SettingsTab extends PureComponent {
sendHexData: PropTypes.bool,
currentCurrency: PropTypes.string,
conversionDate: PropTypes.number,
- useETHAsPrimaryCurrency: PropTypes.bool,
- setUseETHAsPrimaryCurrencyPreference: PropTypes.func,
+ nativeCurrency: PropTypes.string,
+ useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
+ setUseNativeCurrencyAsPrimaryCurrencyPreference: PropTypes.func,
}
state = {
newRpc: '',
+ chainId: '',
+ showOptions: false,
+ ticker: '',
+ nickname: '',
}
renderCurrentConversion () {
@@ -121,37 +129,98 @@ export default class SettingsTab extends PureComponent {
renderNewRpcUrl () {
const { t } = this.context
- const { newRpc } = this.state
+ const { newRpc, chainId, ticker, nickname } = this.state
return (
<div className="settings-page__content-row">
<div className="settings-page__content-item">
- <span>{ t('newRPC') }</span>
+ <span>{ t('newNetwork') }</span>
</div>
<div className="settings-page__content-item">
<div className="settings-page__content-item-col">
<TextField
type="text"
id="new-rpc"
- placeholder={t('newRPC')}
+ placeholder={t('rpcURL')}
value={newRpc}
onChange={e => this.setState({ newRpc: e.target.value })}
onKeyPress={e => {
if (e.key === 'Enter') {
- this.validateRpc(newRpc)
+ this.validateRpc(newRpc, chainId, ticker, nickname)
}
}}
fullWidth
- margin="none"
+ margin="dense"
/>
- <div
- className="settings-tab__rpc-save-button"
- onClick={e => {
- e.preventDefault()
- this.validateRpc(newRpc)
+ <TextField
+ type="text"
+ id="chainid"
+ placeholder={t('optionalChainId')}
+ value={chainId}
+ onChange={e => this.setState({ chainId: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
}}
- >
- { t('save') }
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <TextField
+ type="text"
+ id="ticker"
+ placeholder={t('optionalSymbol')}
+ value={ticker}
+ onChange={e => this.setState({ ticker: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <TextField
+ type="text"
+ id="nickname"
+ placeholder={t('optionalNickname')}
+ value={nickname}
+ onChange={e => this.setState({ nickname: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <div className="flex-row flex-align-center space-between">
+ <span className="settings-tab__advanced-link"
+ onClick={e => {
+ e.preventDefault()
+ this.setState({ showOptions: !this.state.showOptions })
+ }}
+ >
+ { t(this.state.showOptions ? 'hideAdvancedOptions' : 'showAdvancedOptions') }
+ </span>
+ <button
+ className="button btn-primary settings-tab__rpc-save-button"
+ onClick={e => {
+ e.preventDefault()
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }}
+ >
+ { t('save') }
+ </button>
</div>
</div>
</div>
@@ -159,11 +228,11 @@ export default class SettingsTab extends PureComponent {
)
}
- validateRpc (newRpc) {
+ validateRpc (newRpc, chainId, ticker = 'ETH', nickname) {
const { setRpcTarget, displayWarning } = this.props
if (validUrl.isWebUri(newRpc)) {
- setRpcTarget(newRpc)
+ setRpcTarget(newRpc, chainId, ticker, nickname)
} else {
const appendedRpc = `http://${newRpc}`
@@ -210,6 +279,36 @@ export default class SettingsTab extends PureComponent {
)
}
+ renderClearApproval () {
+ const { t } = this.context
+ const { showClearApprovalModal } = this.props
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('approvalData') }</span>
+ <span className="settings-page__content-description">
+ { t('approvalDataDescription') }
+ </span>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <Button
+ type="secondary"
+ large
+ className="settings-tab__button--orange"
+ onClick={event => {
+ event.preventDefault()
+ showClearApprovalModal()
+ }}
+ >
+ { t('clearApprovalData') }
+ </Button>
+ </div>
+ </div>
+ </div>
+ )
+ }
+
renderSeedWords () {
const { t } = this.context
const { history } = this.props
@@ -341,9 +440,13 @@ export default class SettingsTab extends PureComponent {
)
}
- renderUseEthAsPrimaryCurrency () {
+ renderUsePrimaryCurrencyOptions () {
const { t } = this.context
- const { useETHAsPrimaryCurrency, setUseETHAsPrimaryCurrencyPreference } = this.props
+ const {
+ nativeCurrency,
+ setUseNativeCurrencyAsPrimaryCurrencyPreference,
+ useNativeCurrencyAsPrimaryCurrency,
+ } = this.props
return (
<div className="settings-page__content-row">
@@ -359,23 +462,23 @@ export default class SettingsTab extends PureComponent {
<div className="settings-tab__radio-button">
<input
type="radio"
- id="eth-primary-currency"
- onChange={() => setUseETHAsPrimaryCurrencyPreference(true)}
- checked={Boolean(useETHAsPrimaryCurrency)}
+ id="native-primary-currency"
+ onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(true)}
+ checked={Boolean(useNativeCurrencyAsPrimaryCurrency)}
/>
<label
- htmlFor="eth-primary-currency"
+ htmlFor="native-primary-currency"
className="settings-tab__radio-label"
>
- { t('eth') }
+ { nativeCurrency }
</label>
</div>
<div className="settings-tab__radio-button">
<input
type="radio"
id="fiat-primary-currency"
- onChange={() => setUseETHAsPrimaryCurrencyPreference(false)}
- checked={!useETHAsPrimaryCurrency}
+ onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(false)}
+ checked={!useNativeCurrencyAsPrimaryCurrency}
/>
<label
htmlFor="fiat-primary-currency"
@@ -391,6 +494,32 @@ export default class SettingsTab extends PureComponent {
)
}
+ renderPrivacyOptIn () {
+ const { t } = this.context
+ const { privacyMode, setPrivacyMode } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('privacyMode') }</span>
+ <div className="settings-page__content-description">
+ { t('privacyModeDescription') }
+ </div>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <ToggleButton
+ value={privacyMode}
+ onToggle={value => setPrivacyMode(!value)}
+ activeLabel=""
+ inactiveLabel=""
+ />
+ </div>
+ </div>
+ </div>
+ )
+ }
+
render () {
const { warning, isMascara } = this.props
@@ -398,15 +527,17 @@ export default class SettingsTab extends PureComponent {
<div className="settings-page__content">
{ warning && <div className="settings-tab__error">{ warning }</div> }
{ this.renderCurrentConversion() }
- { this.renderUseEthAsPrimaryCurrency() }
+ { this.renderUsePrimaryCurrencyOptions() }
{ this.renderCurrentLocale() }
{ this.renderNewRpcUrl() }
{ this.renderStateLogs() }
{ this.renderSeedWords() }
{ !isMascara && this.renderOldUI() }
{ this.renderResetAccount() }
- { this.renderBlockieOptIn() }
+ { this.renderClearApproval() }
+ { this.renderPrivacyOptIn() }
{ this.renderHexDataOptIn() }
+ { this.renderBlockieOptIn() }
</div>
)
}
diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
index de30f309c..b6c33a5b2 100644
--- a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
+++ b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
@@ -11,7 +11,7 @@ import {
updateCurrentLocale,
setFeatureFlag,
showModal,
- setUseETHAsPrimaryCurrencyPreference,
+ setUseNativeCurrencyAsPrimaryCurrencyPreference,
} from '../../../../actions'
import { preferencesSelector } from '../../../../selectors'
@@ -20,13 +20,17 @@ const mapStateToProps = state => {
const {
currentCurrency,
conversionDate,
+ nativeCurrency,
useBlockie,
- featureFlags: { sendHexData } = {},
+ featureFlags: {
+ sendHexData,
+ privacyMode,
+ } = {},
provider = {},
isMascara,
currentLocale,
} = metamask
- const { useETHAsPrimaryCurrency } = preferencesSelector(state)
+ const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
return {
warning,
@@ -34,17 +38,19 @@ const mapStateToProps = state => {
currentLocale,
currentCurrency,
conversionDate,
+ nativeCurrency,
useBlockie,
sendHexData,
+ privacyMode,
provider,
- useETHAsPrimaryCurrency,
+ useNativeCurrencyAsPrimaryCurrency,
}
}
const mapDispatchToProps = dispatch => {
return {
setCurrentCurrency: currency => dispatch(setCurrentCurrency(currency)),
- setRpcTarget: newRpc => dispatch(setRpcTarget(newRpc)),
+ setRpcTarget: (newRpc, chainId, ticker, nickname) => dispatch(setRpcTarget(newRpc, chainId, ticker, nickname)),
displayWarning: warning => dispatch(displayWarning(warning)),
revealSeedConfirmation: () => dispatch(revealSeedConfirmation()),
setUseBlockie: value => dispatch(setUseBlockie(value)),
@@ -53,10 +59,12 @@ const mapDispatchToProps = dispatch => {
return dispatch(setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
},
setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)),
+ setPrivacyMode: enabled => dispatch(setFeatureFlag('privacyMode', enabled)),
showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })),
- setUseETHAsPrimaryCurrencyPreference: value => {
- return dispatch(setUseETHAsPrimaryCurrencyPreference(value))
+ setUseNativeCurrencyAsPrimaryCurrencyPreference: value => {
+ return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value))
},
+ showClearApprovalModal: () => dispatch(showModal({ name: 'CLEAR_APPROVED_ORIGINS' })),
}
}
diff --git a/ui/app/components/provider-page-container/index.js b/ui/app/components/provider-page-container/index.js
new file mode 100644
index 000000000..927c35940
--- /dev/null
+++ b/ui/app/components/provider-page-container/index.js
@@ -0,0 +1,3 @@
+export {default} from './provider-page-container.component'
+export {default as ProviderPageContainerContent} from './provider-page-container-content'
+export {default as ProviderPageContainerHeader} from './provider-page-container-header'
diff --git a/ui/app/components/provider-page-container/index.scss b/ui/app/components/provider-page-container/index.scss
new file mode 100644
index 000000000..8d35ac179
--- /dev/null
+++ b/ui/app/components/provider-page-container/index.scss
@@ -0,0 +1,121 @@
+.provider-approval-container {
+ display: flex;
+
+ &__header {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ border-bottom: 1px solid $geyser;
+ padding: 9px;
+ }
+
+ &__content {
+ display: flex;
+ overflow-y: auto;
+ flex: 1;
+ flex-direction: column;
+ justify-content: space-between;
+ color: #7C808E;
+
+ h1, h2 {
+ color: #4A4A4A;
+ display: flex;
+ justify-content: center;
+ text-align: center;
+ }
+
+ h2 {
+ font-size: 16px;
+ line-height: 18px;
+ padding: 20px;
+ }
+
+ h1 {
+ font-size: 22px;
+ line-height: 26px;
+ padding: 20px;
+ }
+
+ p {
+ padding: 0 40px;
+ text-align: center;
+ font-size: 12px;
+ line-height: 18px;
+ }
+
+ a, a:hover {
+ color: $dodger-blue;
+ }
+
+ .provider-approval-visual {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-evenly;
+ position: relative;
+ margin: 0 32px;
+
+ section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ flex: 1;
+ }
+
+ h1 {
+ font-size: 14px;
+ line-height: 18px;
+ padding: 8px 0 0;
+ }
+
+ h2 {
+ font-size: 10px;
+ line-height: 14px;
+ padding: 0;
+ color: #A2A4AC;
+ }
+
+ &__check {
+ width: 40px;
+ height: 40px;
+ background: white url("/images/provider-approval-check.svg") no-repeat;
+ margin-top: 14px;
+ }
+
+ &__identicon {
+ width: 64px;
+ height: 64px;
+
+ &--default {
+ background-color: #777A87;
+ color: white;
+ width: 64px;
+ height: 64px;
+ border-radius: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ }
+ }
+
+ &:before {
+ border-top: 2px dashed #CDD1E4;
+ content: "";
+ margin: 0 auto;
+ position: absolute;
+ top: 32px;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ width: 65%;
+ z-index: -1;
+ }
+ }
+
+ .secure-badge {
+ display: flex;
+ justify-content: center;
+ padding: 25px;
+ }
+ }
+}
diff --git a/ui/app/components/provider-page-container/provider-page-container-content/index.js b/ui/app/components/provider-page-container/provider-page-container-content/index.js
new file mode 100644
index 000000000..73e491adc
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container-content/index.js
@@ -0,0 +1 @@
+export {default} from './provider-page-container-content.container'
diff --git a/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.component.js b/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.component.js
new file mode 100644
index 000000000..268db613f
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.component.js
@@ -0,0 +1,77 @@
+import PropTypes from 'prop-types'
+import React, {PureComponent} from 'react'
+import Identicon from '../../identicon'
+
+export default class ProviderPageContainerContent extends PureComponent {
+ static propTypes = {
+ origin: PropTypes.string.isRequired,
+ selectedIdentity: PropTypes.string.isRequired,
+ siteImage: PropTypes.string,
+ siteTitle: PropTypes.string.isRequired,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ };
+
+ renderConnectVisual = () => {
+ const { origin, selectedIdentity, siteImage, siteTitle } = this.props
+
+ return (
+ <div className="provider-approval-visual">
+ <section>
+ {siteImage ? (
+ <img
+ className="provider-approval-visual__identicon"
+ src={siteImage}
+ />
+ ) : (
+ <i className="provider-approval-visual__identicon--default">
+ {siteTitle.charAt(0).toUpperCase()}
+ </i>
+ )}
+ <h1>{siteTitle}</h1>
+ <h2>{origin}</h2>
+ </section>
+ <span className="provider-approval-visual__check" />
+ <section>
+ <Identicon
+ className="provider-approval-visual__identicon"
+ address={selectedIdentity.address}
+ diameter={64}
+ />
+ <h1>{selectedIdentity.name}</h1>
+ </section>
+ </div>
+ )
+ }
+
+ render () {
+ const { siteTitle } = this.props
+ const { t } = this.context
+
+ return (
+ <div className="provider-approval-container__content">
+ <section>
+ <h2>{t('connectRequest')}</h2>
+ {this.renderConnectVisual()}
+ <h1>{t('providerRequest', [siteTitle])}</h1>
+ <p>
+ {t('providerRequestInfo')}
+ <br/>
+ <a
+ href="https://medium.com/metamask/introducing-privacy-mode-42549d4870fa"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ {t('learnMore')}.
+ </a>
+ </p>
+ </section>
+ <section className="secure-badge">
+ <img src="/images/mm-secure.svg" />
+ </section>
+ </div>
+ )
+ }
+}
diff --git a/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.container.js b/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.container.js
new file mode 100644
index 000000000..3ea1ce20e
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container-content/provider-page-container-content.container.js
@@ -0,0 +1,11 @@
+import { connect } from 'react-redux'
+import ProviderPageContainerContent from './provider-page-container-content.component'
+import { getSelectedIdentity } from '../../../selectors'
+
+const mapStateToProps = (state) => {
+ return {
+ selectedIdentity: getSelectedIdentity(state),
+ }
+}
+
+export default connect(mapStateToProps)(ProviderPageContainerContent)
diff --git a/ui/app/components/provider-page-container/provider-page-container-header/index.js b/ui/app/components/provider-page-container/provider-page-container-header/index.js
new file mode 100644
index 000000000..430627d3a
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container-header/index.js
@@ -0,0 +1 @@
+export {default} from './provider-page-container-header.component'
diff --git a/ui/app/components/provider-page-container/provider-page-container-header/provider-page-container-header.component.js b/ui/app/components/provider-page-container/provider-page-container-header/provider-page-container-header.component.js
new file mode 100644
index 000000000..41bf6c3dd
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container-header/provider-page-container-header.component.js
@@ -0,0 +1,12 @@
+import React, {PureComponent} from 'react'
+import NetworkDisplay from '../../network-display'
+
+export default class ProviderPageContainerHeader extends PureComponent {
+ render () {
+ return (
+ <div className="provider-approval-container__header">
+ <NetworkDisplay colored={false} />
+ </div>
+ )
+ }
+}
diff --git a/ui/app/components/provider-page-container/provider-page-container.component.js b/ui/app/components/provider-page-container/provider-page-container.component.js
new file mode 100644
index 000000000..902733616
--- /dev/null
+++ b/ui/app/components/provider-page-container/provider-page-container.component.js
@@ -0,0 +1,50 @@
+import PropTypes from 'prop-types'
+import React, {PureComponent} from 'react'
+import { ProviderPageContainerContent, ProviderPageContainerHeader } from './'
+import { PageContainerFooter } from '../page-container'
+
+export default class ProviderPageContainer extends PureComponent {
+ static propTypes = {
+ approveProviderRequest: PropTypes.func.isRequired,
+ origin: PropTypes.string.isRequired,
+ rejectProviderRequest: PropTypes.func.isRequired,
+ siteImage: PropTypes.string,
+ siteTitle: PropTypes.string.isRequired,
+ };
+
+ static contextTypes = {
+ t: PropTypes.func,
+ };
+
+ onCancel = () => {
+ const { origin, rejectProviderRequest } = this.props
+ rejectProviderRequest(origin)
+ }
+
+ onSubmit = () => {
+ const { approveProviderRequest, origin } = this.props
+ approveProviderRequest(origin)
+ }
+
+ render () {
+ const {origin, siteImage, siteTitle} = this.props
+
+ return (
+ <div className="page-container provider-approval-container">
+ <ProviderPageContainerHeader />
+ <ProviderPageContainerContent
+ origin={origin}
+ siteImage={siteImage}
+ siteTitle={siteTitle}
+ />
+ <PageContainerFooter
+ onCancel={() => this.onCancel()}
+ cancelText={this.context.t('cancel')}
+ onSubmit={() => this.onSubmit()}
+ submitText={this.context.t('connect')}
+ submitButtonType="confirm"
+ />
+ </div>
+ )
+ }
+}
diff --git a/ui/app/components/send/account-list-item/account-list-item.container.js b/ui/app/components/send/account-list-item/account-list-item.container.js
index 4b4519288..f8e73d923 100644
--- a/ui/app/components/send/account-list-item/account-list-item.container.js
+++ b/ui/app/components/send/account-list-item/account-list-item.container.js
@@ -2,6 +2,7 @@ import { connect } from 'react-redux'
import {
getConversionRate,
getCurrentCurrency,
+ getNativeCurrency,
} from '../send.selectors.js'
import AccountListItem from './account-list-item.component'
@@ -11,5 +12,6 @@ function mapStateToProps (state) {
return {
conversionRate: getConversionRate(state),
currentCurrency: getCurrentCurrency(state),
+ nativeCurrency: getNativeCurrency(state),
}
}
diff --git a/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js
index f88c0dbd0..6ffc0b1c6 100644
--- a/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js
+++ b/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js
@@ -28,6 +28,7 @@ describe('AccountListItem Component', function () {
className={'mockClassName'}
conversionRate={4}
currentCurrency={'mockCurrentyCurrency'}
+ nativeCurrency={'ETH'}
displayAddress={false}
displayBalance={false}
handleClick={propsMethodSpies.handleClick}
diff --git a/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js b/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js
index af0859117..7c2f5fcb2 100644
--- a/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js
+++ b/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js
@@ -13,6 +13,7 @@ proxyquire('../account-list-item.container.js', {
'../send.selectors.js': {
getConversionRate: (s) => `mockConversionRate:${s}`,
getCurrentCurrency: (s) => `mockCurrentCurrency:${s}`,
+ getNativeCurrency: (s) => `mockNativeCurrency:${s}`,
},
})
@@ -24,6 +25,7 @@ describe('account-list-item container', () => {
assert.deepEqual(mapStateToProps('mockState'), {
conversionRate: 'mockConversionRate:mockState',
currentCurrency: 'mockCurrentCurrency:mockState',
+ nativeCurrency: 'mockNativeCurrency:mockState',
})
})
diff --git a/ui/app/components/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/components/send/send-content/send-amount-row/tests/send-amount-row-component.test.js
index e63db4a2d..56e80cb83 100644
--- a/ui/app/components/send/send-content/send-amount-row/tests/send-amount-row-component.test.js
+++ b/ui/app/components/send/send-content/send-amount-row/tests/send-amount-row-component.test.js
@@ -151,7 +151,6 @@ describe('SendAmountRow Component', function () {
})
it('should render a UserPreferencedTokenInput as the second child of the SendRowWrapper', () => {
- console.log('HI', wrapper.find(SendRowWrapper).childAt(1))
assert(wrapper.find(SendRowWrapper).childAt(1).is(UserPreferencedTokenInput))
})
diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js
index 22e379693..eb22a08b7 100644
--- a/ui/app/components/send/send.selectors.js
+++ b/ui/app/components/send/send.selectors.js
@@ -19,6 +19,7 @@ const selectors = {
getCurrentNetwork,
getCurrentViewContext,
getForceGasMin,
+ getNativeCurrency,
getGasLimit,
getGasPrice,
getGasPriceFromRecentBlocks,
@@ -111,6 +112,10 @@ function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
+function getNativeCurrency (state) {
+ return state.metamask.nativeCurrency
+}
+
function getCurrentNetwork (state) {
return state.metamask.network
}
diff --git a/ui/app/components/send/send.utils.js b/ui/app/components/send/send.utils.js
index a18a9e4b3..eb1667c63 100644
--- a/ui/app/components/send/send.utils.js
+++ b/ui/app/components/send/send.utils.js
@@ -215,7 +215,9 @@ async function estimateGas ({
// if recipient has no code, gas is 21k max:
if (!selectedToken && !data) {
const code = Boolean(to) && await global.eth.getCode(to)
- if (!code || code === '0x') {
+ // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'
+ const codeIsEmpty = !code || code === '0x' || code === '0x0'
+ if (codeIsEmpty) {
return SIMPLE_GAS_COST
}
} else if (selectedToken && !to) {
diff --git a/ui/app/components/send/tests/send-selectors-test-data.js b/ui/app/components/send/tests/send-selectors-test-data.js
index 8b939dadb..30a2666cf 100644
--- a/ui/app/components/send/tests/send-selectors-test-data.js
+++ b/ui/app/components/send/tests/send-selectors-test-data.js
@@ -26,6 +26,7 @@ module.exports = {
'currentCurrency': 'USD',
'conversionRate': 1200.88200327,
'conversionDate': 1489013762,
+ 'nativeCurrency': 'ETH',
'noActiveNotices': true,
'frequentRpcList': [],
'network': '3',
diff --git a/ui/app/components/send/tests/send-selectors.test.js b/ui/app/components/send/tests/send-selectors.test.js
index 1a47cd209..e7e901f0d 100644
--- a/ui/app/components/send/tests/send-selectors.test.js
+++ b/ui/app/components/send/tests/send-selectors.test.js
@@ -12,6 +12,7 @@ const {
getCurrentCurrency,
getCurrentNetwork,
getCurrentViewContext,
+ getNativeCurrency,
getForceGasMin,
getGasLimit,
getGasPrice,
@@ -178,6 +179,15 @@ describe('send selectors', () => {
})
})
+ describe('getNativeCurrency()', () => {
+ it('should return the ticker symbol of the selected network', () => {
+ assert.equal(
+ getNativeCurrency(mockState),
+ 'ETH'
+ )
+ })
+ })
+
describe('getCurrentNetwork()', () => {
it('should return the id of the currently selected network', () => {
assert.equal(
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
index d76eb5ef8..85af3b00b 100644
--- a/ui/app/components/signature-request.js
+++ b/ui/app/components/signature-request.js
@@ -2,7 +2,7 @@ const Component = require('react').Component
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const inherits = require('util').inherits
-const Identicon = require('./identicon')
+import Identicon from './identicon'
const connect = require('react-redux').connect
const ethUtil = require('ethereumjs-util')
const classnames = require('classnames')
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
index 477d97597..75ba347fa 100644
--- a/ui/app/components/token-cell.js
+++ b/ui/app/components/token-cell.js
@@ -2,7 +2,7 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
-const Identicon = require('./identicon')
+import Identicon from './identicon'
const prefixForNetwork = require('../../lib/etherscan-prefix-for-network')
const selectors = require('../selectors')
const actions = require('../actions')
diff --git a/ui/app/components/token-input/tests/token-input.component.test.js b/ui/app/components/token-input/tests/token-input.component.test.js
index 2131e7705..2dacb9bc4 100644
--- a/ui/app/components/token-input/tests/token-input.component.test.js
+++ b/ui/app/components/token-input/tests/token-input.component.test.js
@@ -122,7 +122,7 @@ describe('TokenInput Component', () => {
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC')
assert.equal(wrapper.find('.unit-input__input').props().value, '1')
- assert.equal(wrapper.find('.currency-display-component').text(), '2 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '2ETH')
})
it('should render properly with a token value for fiat', () => {
@@ -157,7 +157,7 @@ describe('TokenInput Component', () => {
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC')
assert.equal(wrapper.find('.unit-input__input').props().value, '1')
- assert.equal(wrapper.find('.currency-display-component').text(), '$462.12 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$462.12USD')
})
})
@@ -201,14 +201,14 @@ describe('TokenInput Component', () => {
const tokenInputInstance = wrapper.find(TokenInput).at(0).instance()
assert.equal(tokenInputInstance.state.decimalValue, 0)
assert.equal(tokenInputInstance.state.hexValue, undefined)
- assert.equal(wrapper.find('.currency-display-component').text(), '0 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '0ETH')
const input = wrapper.find('input')
assert.equal(input.props().value, 0)
input.simulate('change', { target: { value: 1 } })
assert.equal(handleChangeSpy.callCount, 1)
assert.ok(handleChangeSpy.calledWith('2710'))
- assert.equal(wrapper.find('.currency-display-component').text(), '2 ETH')
+ assert.equal(wrapper.find('.currency-display-component').text(), '2ETH')
assert.equal(tokenInputInstance.state.decimalValue, 1)
assert.equal(tokenInputInstance.state.hexValue, '2710')
@@ -250,14 +250,14 @@ describe('TokenInput Component', () => {
const tokenInputInstance = wrapper.find(TokenInput).at(0).instance()
assert.equal(tokenInputInstance.state.decimalValue, 0)
assert.equal(tokenInputInstance.state.hexValue, undefined)
- assert.equal(wrapper.find('.currency-display-component').text(), '$0.00 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$0.00USD')
const input = wrapper.find('input')
assert.equal(input.props().value, 0)
input.simulate('change', { target: { value: 1 } })
assert.equal(handleChangeSpy.callCount, 1)
assert.ok(handleChangeSpy.calledWith('2710'))
- assert.equal(wrapper.find('.currency-display-component').text(), '$462.12 USD')
+ assert.equal(wrapper.find('.currency-display-component').text(), '$462.12USD')
assert.equal(tokenInputInstance.state.decimalValue, 1)
assert.equal(tokenInputInstance.state.hexValue, '2710')
diff --git a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js
index 85d56a6a2..a7c35f51e 100644
--- a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js
+++ b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js
@@ -18,10 +18,11 @@ describe('TransactionActivityLog container', () => {
const mockState = {
metamask: {
conversionRate: 280.45,
+ nativeCurrency: 'ETH',
},
}
- assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45 })
+ assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH' })
})
})
})
diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js
index c4cf57d14..58d932a0f 100644
--- a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js
+++ b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js
@@ -4,7 +4,6 @@ import classnames from 'classnames'
import { getActivities } from './transaction-activity-log.util'
import Card from '../card'
import { getEthConversionFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util'
-import { ETH } from '../../constants/common'
import { formatDate } from '../../util'
export default class TransactionActivityLog extends PureComponent {
@@ -16,6 +15,7 @@ export default class TransactionActivityLog extends PureComponent {
transaction: PropTypes.object,
className: PropTypes.string,
conversionRate: PropTypes.number,
+ nativeCurrency: PropTypes.string,
}
state = {
@@ -27,10 +27,14 @@ export default class TransactionActivityLog extends PureComponent {
}
componentDidUpdate (prevProps) {
- const { transaction: { history: prevHistory = [] } = {} } = prevProps
- const { transaction: { history = [] } = {} } = this.props
+ const {
+ transaction: { history: prevHistory = [], txReceipt: { status: prevStatus } = {} } = {},
+ } = prevProps
+ const {
+ transaction: { history = [], txReceipt: { status } = {} } = {},
+ } = this.props
- if (prevHistory.length !== history.length) {
+ if (prevHistory.length !== history.length || prevStatus !== status) {
this.setActivites()
}
}
@@ -41,16 +45,17 @@ export default class TransactionActivityLog extends PureComponent {
}
renderActivity (activity, index) {
- const { conversionRate } = this.props
+ const { conversionRate, nativeCurrency } = this.props
const { eventKey, value, timestamp } = activity
const ethValue = index === 0
? `${getValueFromWeiHex({
value,
- toCurrency: ETH,
+ fromCurrency: nativeCurrency,
+ toCurrency: nativeCurrency,
conversionRate,
numberOfDecimals: 6,
- })} ${ETH}`
- : getEthConversionFromWeiHex({ value, toCurrency: ETH, conversionRate })
+ })} ${nativeCurrency}`
+ : getEthConversionFromWeiHex({ value, fromCurrency: nativeCurrency, conversionRate })
const formattedTimestamp = formatDate(timestamp)
const activityText = this.context.t(eventKey, [ethValue, formattedTimestamp])
diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js
index 4c8b6d971..622f77df1 100644
--- a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js
+++ b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js
@@ -1,10 +1,11 @@
import { connect } from 'react-redux'
import TransactionActivityLog from './transaction-activity-log.component'
-import { conversionRateSelector } from '../../selectors'
+import { conversionRateSelector, getNativeCurrency } from '../../selectors'
const mapStateToProps = state => {
return {
conversionRate: conversionRateSelector(state),
+ nativeCurrency: getNativeCurrency(state),
}
}
diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.util.js b/ui/app/components/transaction-activity-log/transaction-activity-log.util.js
index 97aa9a8f1..16597ae1a 100644
--- a/ui/app/components/transaction-activity-log/transaction-activity-log.util.js
+++ b/ui/app/components/transaction-activity-log/transaction-activity-log.util.js
@@ -18,6 +18,7 @@ const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted'
const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed'
const TRANSACTION_DROPPED_EVENT = 'transactionDropped'
const TRANSACTION_UPDATED_EVENT = 'transactionUpdated'
+const TRANSACTION_ERRORED_EVENT = 'transactionErrored'
const eventPathsHash = {
[STATUS_PATH]: true,
@@ -39,9 +40,9 @@ function eventCreator (eventKey, timestamp, value) {
}
export function getActivities (transaction) {
- const { history = [] } = transaction
+ const { history = [], txReceipt: { status } = {} } = transaction
- return history.reduce((acc, base) => {
+ const historyActivities = history.reduce((acc, base) => {
// First history item should be transaction creation
if (!Array.isArray(base) && base.status === UNAPPROVED_STATUS && base.txParams) {
const { time, txParams: { value } = {} } = base
@@ -83,4 +84,10 @@ export function getActivities (transaction) {
return acc
}, [])
+
+ // If txReceipt.status is '0x0', that means that an on-chain error occured for the transaction,
+ // so we add an error entry to the Activity Log.
+ return status === '0x0'
+ ? historyActivities.concat(eventCreator(TRANSACTION_ERRORED_EVENT))
+ : historyActivities
}
diff --git a/ui/app/components/transaction-breakdown/index.js b/ui/app/components/transaction-breakdown/index.js
index c887f504f..4a5b52663 100644
--- a/ui/app/components/transaction-breakdown/index.js
+++ b/ui/app/components/transaction-breakdown/index.js
@@ -1 +1 @@
-export { default } from './transaction-breakdown.component'
+export { default } from './transaction-breakdown.container'
diff --git a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js
index 77bedcad7..3a7647873 100644
--- a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js
+++ b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js
@@ -6,7 +6,7 @@ import Card from '../card'
import CurrencyDisplay from '../currency-display'
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
import HexToDecimal from '../hex-to-decimal'
-import { ETH, GWEI, PRIMARY, SECONDARY } from '../../constants/common'
+import { GWEI, PRIMARY, SECONDARY } from '../../constants/common'
import { getHexGasTotal } from '../../helpers/confirm-transaction/util'
import { sumHexes } from '../../helpers/transactions.util'
@@ -18,6 +18,7 @@ export default class TransactionBreakdown extends PureComponent {
static propTypes = {
transaction: PropTypes.object,
className: PropTypes.string,
+ nativeCurrency: PropTypes.string.isRequired,
}
static defaultProps = {
@@ -26,7 +27,7 @@ export default class TransactionBreakdown extends PureComponent {
render () {
const { t } = this.context
- const { transaction, className } = this.props
+ const { transaction, className, nativeCurrency } = this.props
const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {} } = transaction
const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas
@@ -72,7 +73,7 @@ export default class TransactionBreakdown extends PureComponent {
<TransactionBreakdownRow title={t('gasPrice')}>
<CurrencyDisplay
className="transaction-breakdown__value"
- currency={ETH}
+ currency={nativeCurrency}
denomination={GWEI}
value={gasPrice}
hideLabel
diff --git a/ui/app/components/transaction-breakdown/transaction-breakdown.container.js b/ui/app/components/transaction-breakdown/transaction-breakdown.container.js
new file mode 100644
index 000000000..ed2708e03
--- /dev/null
+++ b/ui/app/components/transaction-breakdown/transaction-breakdown.container.js
@@ -0,0 +1,11 @@
+import { connect } from 'react-redux'
+import TransactionBreakdown from './transaction-breakdown.component'
+import { getNativeCurrency } from '../../selectors'
+
+const mapStateToProps = (state) => {
+ return {
+ nativeCurrency: getNativeCurrency(state),
+ }
+}
+
+export default connect(mapStateToProps)(TransactionBreakdown)
diff --git a/ui/app/components/transaction-list-item/index.scss b/ui/app/components/transaction-list-item/index.scss
index 9d694546b..ac0e7beeb 100644
--- a/ui/app/components/transaction-list-item/index.scss
+++ b/ui/app/components/transaction-list-item/index.scss
@@ -85,6 +85,7 @@
text-align: end;
grid-area: primary-amount;
align-self: end;
+ justify-self: end;
@media screen and (max-width: $break-small) {
padding-bottom: 2px;
@@ -97,6 +98,7 @@
color: #5e6064;
grid-area: secondary-amount;
align-self: start;
+ justify-self: end;
}
}
diff --git a/ui/app/components/transaction-list-item/transaction-list-item.component.js b/ui/app/components/transaction-list-item/transaction-list-item.component.js
index 88573d2d5..696634fe0 100644
--- a/ui/app/components/transaction-list-item/transaction-list-item.component.js
+++ b/ui/app/components/transaction-list-item/transaction-list-item.component.js
@@ -10,7 +10,6 @@ import TransactionListItemDetails from '../transaction-list-item-details'
import { CONFIRM_TRANSACTION_ROUTE } from '../../routes'
import { UNAPPROVED_STATUS, TOKEN_METHOD_TRANSFER } from '../../constants/transactions'
import { PRIMARY, SECONDARY } from '../../constants/common'
-import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../app/scripts/lib/enums'
import { getStatusKey } from '../../helpers/transactions.util'
export default class TransactionListItem extends PureComponent {
@@ -24,7 +23,6 @@ export default class TransactionListItem extends PureComponent {
showCancelModal: PropTypes.func,
showCancel: PropTypes.bool,
showRetry: PropTypes.bool,
- showTransactionDetailsModal: PropTypes.func,
token: PropTypes.object,
tokenData: PropTypes.object,
transaction: PropTypes.object,
@@ -39,31 +37,16 @@ export default class TransactionListItem extends PureComponent {
const {
transaction,
history,
- showTransactionDetailsModal,
- methodData,
- showCancel,
- showRetry,
} = this.props
const { id, status } = transaction
const { showTransactionDetails } = this.state
- const windowType = window.METAMASK_UI_TYPE
if (status === UNAPPROVED_STATUS) {
history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`)
return
}
- if (windowType === ENVIRONMENT_TYPE_FULLSCREEN) {
- this.setState({ showTransactionDetails: !showTransactionDetails })
- } else {
- showTransactionDetailsModal({
- transaction,
- onRetry: this.handleRetry,
- showRetry: showRetry && methodData.done,
- onCancel: this.handleCancel,
- showCancel,
- })
- }
+ this.setState({ showTransactionDetails: !showTransactionDetails })
}
handleCancel = () => {
diff --git a/ui/app/components/transaction-list-item/transaction-list-item.container.js b/ui/app/components/transaction-list-item/transaction-list-item.container.js
index 72f5f5d61..62ed7a73f 100644
--- a/ui/app/components/transaction-list-item/transaction-list-item.container.js
+++ b/ui/app/components/transaction-list-item/transaction-list-item.container.js
@@ -28,16 +28,6 @@ const mapDispatchToProps = dispatch => {
showCancelModal: (transactionId, originalGasPrice) => {
return dispatch(showModal({ name: 'CANCEL_TRANSACTION', transactionId, originalGasPrice }))
},
- showTransactionDetailsModal: ({ transaction, onRetry, showRetry, onCancel, showCancel }) => {
- return dispatch(showModal({
- name: 'TRANSACTION_DETAILS',
- transaction,
- onRetry,
- showRetry,
- onCancel,
- showCancel,
- }))
- },
}
}
diff --git a/ui/app/components/transaction-list/index.scss b/ui/app/components/transaction-list/index.scss
index 777f701f9..ba7ffd87b 100644
--- a/ui/app/components/transaction-list/index.scss
+++ b/ui/app/components/transaction-list/index.scss
@@ -2,9 +2,7 @@
display: flex;
flex-direction: column;
flex: 1;
- overflow-y: hidden;
margin-top: 8px;
- border-top: 1px solid $geyser;
&__completed-transactions {
display: flex;
@@ -26,7 +24,6 @@
&__transactions {
flex: 1;
- overflow-y: auto;
}
&__pending-transactions {
diff --git a/ui/app/components/transaction-view-balance/index.scss b/ui/app/components/transaction-view-balance/index.scss
index 12045ab6d..659f896ff 100644
--- a/ui/app/components/transaction-view-balance/index.scss
+++ b/ui/app/components/transaction-view-balance/index.scss
@@ -4,11 +4,13 @@
align-items: center;
flex: 1;
height: 54px;
+ min-width: 0;
&__balance {
- margin-left: 12px;
+ margin: 0 12px;
display: flex;
flex-direction: column;
+ min-width: 0;
@media screen and (max-width: $break-small) {
align-items: center;
@@ -21,7 +23,8 @@
font-size: 1.5rem;
@media screen and (max-width: $break-small) {
- margin-bottom: 12px;
+ margin: 12px 0;
+ margin-left: 0;
font-size: 1.75rem;
}
}
@@ -30,7 +33,6 @@
font-size: 1.5rem;
@media screen and (max-width: $break-small) {
- margin-bottom: 12px;
font-size: 1.75rem;
}
}
@@ -45,6 +47,7 @@
display: flex;
flex-direction: row;
align-items: center;
+ min-width: 0;
@media screen and (max-width: $break-small) {
flex-direction: column;
diff --git a/ui/app/components/transaction-view-balance/transaction-view-balance.container.js b/ui/app/components/transaction-view-balance/transaction-view-balance.container.js
index 30c5cab16..cb8078ec1 100644
--- a/ui/app/components/transaction-view-balance/transaction-view-balance.container.js
+++ b/ui/app/components/transaction-view-balance/transaction-view-balance.container.js
@@ -2,7 +2,7 @@ import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { compose } from 'recompose'
import TransactionViewBalance from './transaction-view-balance.component'
-import { getSelectedToken, getSelectedAddress, getSelectedTokenAssetImage } from '../../selectors'
+import { getSelectedToken, getSelectedAddress, getNativeCurrency, getSelectedTokenAssetImage } from '../../selectors'
import { showModal } from '../../actions'
const mapStateToProps = state => {
@@ -15,6 +15,7 @@ const mapStateToProps = state => {
selectedToken: getSelectedToken(state),
network,
balance,
+ nativeCurrency: getNativeCurrency(state),
assetImage: getSelectedTokenAssetImage(state),
}
}
diff --git a/ui/app/components/transaction-view/index.scss b/ui/app/components/transaction-view/index.scss
index af9771ce0..13187f0e5 100644
--- a/ui/app/components/transaction-view/index.scss
+++ b/ui/app/components/transaction-view/index.scss
@@ -4,6 +4,7 @@
min-width: 0;
display: flex;
flex-direction: column;
+ overflow-y: auto;
&__balance-wrapper {
@media screen and (max-width: $break-small) {
diff --git a/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js b/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js
index 41ad3b73e..ba1c23d83 100644
--- a/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js
+++ b/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js
@@ -18,14 +18,16 @@ describe('UserPreferencedCurrencyDisplay container', () => {
it('should return the correct props', () => {
const mockState = {
metamask: {
+ nativeCurrency: 'ETH',
preferences: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
- useETHAsPrimaryCurrency: true,
+ nativeCurrency: 'ETH',
+ useNativeCurrencyAsPrimaryCurrency: true,
})
})
})
@@ -37,33 +39,38 @@ describe('UserPreferencedCurrencyDisplay container', () => {
const tests = [
{
stateProps: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
+ nativeCurrency: 'ETH',
},
ownProps: {
type: 'PRIMARY',
},
result: {
currency: 'ETH',
+ nativeCurrency: 'ETH',
numberOfDecimals: 6,
prefix: undefined,
},
},
{
stateProps: {
- useETHAsPrimaryCurrency: false,
+ useNativeCurrencyAsPrimaryCurrency: false,
+ nativeCurrency: 'ETH',
},
ownProps: {
type: 'PRIMARY',
},
result: {
currency: undefined,
+ nativeCurrency: 'ETH',
numberOfDecimals: 2,
prefix: undefined,
},
},
{
stateProps: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
+ nativeCurrency: 'ETH',
},
ownProps: {
type: 'SECONDARY',
@@ -71,6 +78,7 @@ describe('UserPreferencedCurrencyDisplay container', () => {
fiatPrefix: '-',
},
result: {
+ nativeCurrency: 'ETH',
currency: undefined,
numberOfDecimals: 4,
prefix: '-',
@@ -78,7 +86,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
},
{
stateProps: {
- useETHAsPrimaryCurrency: false,
+ useNativeCurrencyAsPrimaryCurrency: false,
+ nativeCurrency: 'ETH',
},
ownProps: {
type: 'SECONDARY',
@@ -89,6 +98,7 @@ describe('UserPreferencedCurrencyDisplay container', () => {
},
result: {
currency: 'ETH',
+ nativeCurrency: 'ETH',
numberOfDecimals: 3,
prefix: 'b',
},
diff --git a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js
index 4d948ca6a..f2a834ea7 100644
--- a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js
+++ b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js
@@ -21,6 +21,7 @@ export default class UserPreferencedCurrencyDisplay extends PureComponent {
fiatPrefix: PropTypes.string,
// From container
currency: PropTypes.string,
+ nativeCurrency: PropTypes.string,
}
renderEthLogo () {
diff --git a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js
index 23240c649..7999301ad 100644
--- a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js
+++ b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js
@@ -4,15 +4,16 @@ import { preferencesSelector } from '../../selectors'
import { ETH, PRIMARY, SECONDARY } from '../../constants/common'
const mapStateToProps = (state, ownProps) => {
- const { useETHAsPrimaryCurrency } = preferencesSelector(state)
+ const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
return {
- useETHAsPrimaryCurrency,
+ useNativeCurrencyAsPrimaryCurrency,
+ nativeCurrency: state.metamask.nativeCurrency,
}
}
const mergeProps = (stateProps, dispatchProps, ownProps) => {
- const { useETHAsPrimaryCurrency, ...restStateProps } = stateProps
+ const { useNativeCurrencyAsPrimaryCurrency, nativeCurrency, ...restStateProps } = stateProps
const {
type,
numberOfDecimals: propsNumberOfDecimals,
@@ -26,14 +27,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
let currency, numberOfDecimals, prefix
- if (type === PRIMARY && useETHAsPrimaryCurrency ||
- type === SECONDARY && !useETHAsPrimaryCurrency) {
+ if (type === PRIMARY && useNativeCurrencyAsPrimaryCurrency ||
+ type === SECONDARY && !useNativeCurrencyAsPrimaryCurrency) {
// Display ETH
- currency = ETH
+ currency = nativeCurrency || ETH
numberOfDecimals = propsNumberOfDecimals || ethNumberOfDecimals || 6
prefix = propsPrefix || ethPrefix
- } else if (type === SECONDARY && useETHAsPrimaryCurrency ||
- type === PRIMARY && !useETHAsPrimaryCurrency) {
+ } else if (type === SECONDARY && useNativeCurrencyAsPrimaryCurrency ||
+ type === PRIMARY && !useNativeCurrencyAsPrimaryCurrency) {
// Display Fiat
numberOfDecimals = propsNumberOfDecimals || fiatNumberOfDecimals || 2
prefix = propsPrefix || fiatPrefix
@@ -43,6 +44,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...restStateProps,
...dispatchProps,
...restOwnProps,
+ nativeCurrency,
currency,
numberOfDecimals,
prefix,
diff --git a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js
index 0af80a03d..710b5d519 100644
--- a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js
+++ b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js
@@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => {
assert.equal(wrapper.find(CurrencyInput).length, 1)
})
- it('should render useFiat for CurrencyInput based on preferences.useETHAsPrimaryCurrency', () => {
+ it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => {
const wrapper = shallow(
<UserPreferencedCurrencyInput
- useETHAsPrimaryCurrency
+ useNativeCurrencyAsPrimaryCurrency
/>
)
assert.ok(wrapper)
assert.equal(wrapper.find(CurrencyInput).length, 1)
assert.equal(wrapper.find(CurrencyInput).props().useFiat, false)
- wrapper.setProps({ useETHAsPrimaryCurrency: false })
+ wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false })
assert.equal(wrapper.find(CurrencyInput).props().useFiat, true)
})
})
diff --git a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js
index d860c38da..959726443 100644
--- a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js
+++ b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js
@@ -18,13 +18,13 @@ describe('UserPreferencedCurrencyInput container', () => {
const mockState = {
metamask: {
preferences: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
})
})
})
diff --git a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js
index 6e0e00a1d..463e66b80 100644
--- a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js
+++ b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js
@@ -4,16 +4,16 @@ import CurrencyInput from '../currency-input'
export default class UserPreferencedCurrencyInput extends PureComponent {
static propTypes = {
- useETHAsPrimaryCurrency: PropTypes.bool,
+ useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
}
render () {
- const { useETHAsPrimaryCurrency, ...restProps } = this.props
+ const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props
return (
<CurrencyInput
{...restProps}
- useFiat={!useETHAsPrimaryCurrency}
+ useFiat={!useNativeCurrencyAsPrimaryCurrency}
/>
)
}
diff --git a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js
index 397cdc7cc..0b88eb5a7 100644
--- a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js
+++ b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js
@@ -3,10 +3,10 @@ import UserPreferencedCurrencyInput from './user-preferenced-currency-input.comp
import { preferencesSelector } from '../../selectors'
const mapStateToProps = state => {
- const { useETHAsPrimaryCurrency } = preferencesSelector(state)
+ const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
return {
- useETHAsPrimaryCurrency,
+ useNativeCurrencyAsPrimaryCurrency,
}
}
diff --git a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js
index 910c7089f..d85bddeeb 100644
--- a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js
+++ b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js
@@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => {
assert.equal(wrapper.find(TokenInput).length, 1)
})
- it('should render showFiat for TokenInput based on preferences.useETHAsPrimaryCurrency', () => {
+ it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => {
const wrapper = shallow(
<UserPreferencedTokenInput
- useETHAsPrimaryCurrency
+ useNativeCurrencyAsPrimaryCurrency
/>
)
assert.ok(wrapper)
assert.equal(wrapper.find(TokenInput).length, 1)
assert.equal(wrapper.find(TokenInput).props().showFiat, false)
- wrapper.setProps({ useETHAsPrimaryCurrency: false })
+ wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false })
assert.equal(wrapper.find(TokenInput).props().showFiat, true)
})
})
diff --git a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js
index e3509149a..2f89fba90 100644
--- a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js
+++ b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js
@@ -18,13 +18,13 @@ describe('UserPreferencedTokenInput container', () => {
const mockState = {
metamask: {
preferences: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
})
})
})
diff --git a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js
index f2b537f11..8f14231ac 100644
--- a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js
+++ b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js
@@ -4,16 +4,16 @@ import TokenInput from '../token-input'
export default class UserPreferencedTokenInput extends PureComponent {
static propTypes = {
- useETHAsPrimaryCurrency: PropTypes.bool,
+ useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
}
render () {
- const { useETHAsPrimaryCurrency, ...restProps } = this.props
+ const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props
return (
<TokenInput
{...restProps}
- showFiat={!useETHAsPrimaryCurrency}
+ showFiat={!useNativeCurrencyAsPrimaryCurrency}
/>
)
}
diff --git a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js
index 416d069dd..3305d4e29 100644
--- a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js
+++ b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js
@@ -3,10 +3,10 @@ import UserPreferencedTokenInput from './user-preferenced-token-input.component'
import { preferencesSelector } from '../../selectors'
const mapStateToProps = state => {
- const { useETHAsPrimaryCurrency } = preferencesSelector(state)
+ const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
return {
- useETHAsPrimaryCurrency,
+ useNativeCurrencyAsPrimaryCurrency,
}
}
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index 8a7cb0f8d..e050e0ee6 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -7,7 +7,7 @@ const { compose } = require('recompose')
const inherits = require('util').inherits
const classnames = require('classnames')
const { checksumAddress } = require('../util')
-const Identicon = require('./identicon')
+import Identicon from './identicon'
// const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns
const Tooltip = require('./tooltip-v2.js').default
const copyToClipboard = require('copy-to-clipboard')
@@ -127,7 +127,6 @@ WalletView.prototype.render = function () {
identities,
} = this.props
// temporary logs + fake extra wallets
- // console.log('walletview, selectedAccount:', selectedAccount)
const checksummedAddress = checksumAddress(selectedAddress)
diff --git a/ui/app/constants/error-keys.js b/ui/app/constants/error-keys.js
index f70ed3b19..704064c96 100644
--- a/ui/app/constants/error-keys.js
+++ b/ui/app/constants/error-keys.js
@@ -1,3 +1,4 @@
export const INSUFFICIENT_FUNDS_ERROR_KEY = 'insufficientFunds'
export const GAS_LIMIT_TOO_LOW_ERROR_KEY = 'gasLimitTooLow'
export const TRANSACTION_ERROR_KEY = 'transactionError'
+export const TRANSACTION_NO_CONTRACT_ERROR_KEY = 'transactionErrorNoContract'
diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss
index 655188a3e..5826a8b49 100644
--- a/ui/app/css/itcss/components/buttons.scss
+++ b/ui/app/css/itcss/components/buttons.scss
@@ -3,7 +3,7 @@
*/
.button {
- height: 44px;
+ min-height: 44px;
background: $white;
display: flex;
justify-content: center;
@@ -82,12 +82,13 @@
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08);
padding: 6px;
height: initial;
+ min-height: initial;
width: initial;
min-width: initial;
}
.btn--large {
- height: 54px;
+ min-height: 54px;
}
.btn-green {
diff --git a/ui/app/css/itcss/components/pages/index.scss b/ui/app/css/itcss/components/pages/index.scss
index 709f8baf6..45e47f447 100644
--- a/ui/app/css/itcss/components/pages/index.scss
+++ b/ui/app/css/itcss/components/pages/index.scss
@@ -1 +1,3 @@
@import './reveal-seed.scss';
+
+@import './provider-approval.scss';
diff --git a/ui/app/css/itcss/components/pages/provider-approval.scss b/ui/app/css/itcss/components/pages/provider-approval.scss
new file mode 100644
index 000000000..f172165ab
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/provider-approval.scss
@@ -0,0 +1,11 @@
+.provider_approval_content {
+ height: auto;
+ overflow: auto;
+ padding: 16px;
+}
+
+.provider_approval_origin {
+ font-weight: 999;
+ margin-top: 16px;
+ word-wrap: break-word;
+}
diff --git a/ui/app/css/itcss/components/request-signature.scss b/ui/app/css/itcss/components/request-signature.scss
index 445b9ebf5..6c950d846 100644
--- a/ui/app/css/itcss/components/request-signature.scss
+++ b/ui/app/css/itcss/components/request-signature.scss
@@ -19,7 +19,7 @@
}
@media screen and (min-width: $break-large) {
- max-height: 620px;
+ height: 620px;
}
}
diff --git a/ui/app/css/itcss/components/wallet-balance.scss b/ui/app/css/itcss/components/wallet-balance.scss
index 293771550..3c3349ae0 100644
--- a/ui/app/css/itcss/components/wallet-balance.scss
+++ b/ui/app/css/itcss/components/wallet-balance.scss
@@ -29,7 +29,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
align-items: center;
margin: 20px 24px;
flex-direction: row;
- flex-grow: 3;
+ min-width: 0;
@media #{$wallet-balance-breakpoint-range} {
margin: 10% 4%;
@@ -38,8 +38,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
.balance-display {
margin-left: 15px;
- justify-content: flex-start;
- align-items: flex-start;
+ min-width: 0;
.token-amount {
font-size: 1.5rem;
diff --git a/ui/app/ducks/confirm-transaction.duck.js b/ui/app/ducks/confirm-transaction.duck.js
index 2ceafbe08..275eb1551 100644
--- a/ui/app/ducks/confirm-transaction.duck.js
+++ b/ui/app/ducks/confirm-transaction.duck.js
@@ -2,6 +2,7 @@ import {
conversionRateSelector,
currentCurrencySelector,
unconfirmedTransactionsHashSelector,
+ getNativeCurrency,
} from '../selectors/confirm-transaction'
import {
@@ -292,16 +293,17 @@ export function updateTxDataAndCalculate (txData) {
const state = getState()
const currentCurrency = currentCurrencySelector(state)
const conversionRate = conversionRateSelector(state)
+ const nativeCurrency = getNativeCurrency(state)
dispatch(updateTxData(txData))
const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData
const fiatTransactionAmount = getValueFromWeiHex({
- value, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
+ value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
})
const ethTransactionAmount = getValueFromWeiHex({
- value, toCurrency: 'ETH', conversionRate, numberOfDecimals: 6,
+ value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6,
})
dispatch(updateTransactionAmounts({
@@ -314,13 +316,15 @@ export function updateTxDataAndCalculate (txData) {
const fiatTransactionFee = getTransactionFee({
value: hexTransactionFee,
+ fromCurrency: nativeCurrency,
toCurrency: currentCurrency,
numberOfDecimals: 2,
conversionRate,
})
const ethTransactionFee = getTransactionFee({
value: hexTransactionFee,
- toCurrency: 'ETH',
+ fromCurrency: nativeCurrency,
+ toCurrency: nativeCurrency,
numberOfDecimals: 6,
conversionRate,
})
@@ -329,7 +333,6 @@ export function updateTxDataAndCalculate (txData) {
const fiatTransactionTotal = addFiat(fiatTransactionFee, fiatTransactionAmount)
const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount)
- console.log('HIHIH', value, hexTransactionFee)
const hexTransactionTotal = sumHexes(value, hexTransactionFee)
dispatch(updateTransactionTotals({
diff --git a/ui/app/helpers/confirm-transaction/util.js b/ui/app/helpers/confirm-transaction/util.js
index bcac22500..eb334a4b8 100644
--- a/ui/app/helpers/confirm-transaction/util.js
+++ b/ui/app/helpers/confirm-transaction/util.js
@@ -55,6 +55,7 @@ export function addFiat (...args) {
export function getValueFromWeiHex ({
value,
+ fromCurrency = 'ETH',
toCurrency,
conversionRate,
numberOfDecimals,
@@ -63,7 +64,7 @@ export function getValueFromWeiHex ({
return conversionUtil(value, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
- fromCurrency: 'ETH',
+ fromCurrency,
toCurrency,
numberOfDecimals,
fromDenomination: 'WEI',
@@ -74,6 +75,7 @@ export function getValueFromWeiHex ({
export function getTransactionFee ({
value,
+ fromCurrency = 'ETH',
toCurrency,
conversionRate,
numberOfDecimals,
@@ -82,7 +84,7 @@ export function getTransactionFee ({
fromNumericBase: 'BN',
toNumericBase: 'dec',
fromDenomination: 'WEI',
- fromCurrency: 'ETH',
+ fromCurrency,
toCurrency,
numberOfDecimals,
conversionRate,
@@ -99,6 +101,7 @@ export function formatCurrency (value, currencyCode) {
export function convertTokenToFiat ({
value,
+ fromCurrency = 'ETH',
toCurrency,
conversionRate,
contractExchangeRate,
@@ -108,6 +111,7 @@ export function convertTokenToFiat ({
return conversionUtil(value, {
fromNumericBase: 'dec',
toNumericBase: 'dec',
+ fromCurrency,
toCurrency,
numberOfDecimals: 2,
conversionRate: totalExchangeRate,
diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js
index 777537e1e..cb5e1b90b 100644
--- a/ui/app/helpers/conversions.util.js
+++ b/ui/app/helpers/conversions.util.js
@@ -20,8 +20,8 @@ export function decimalToHex (decimal) {
})
}
-export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDecimals = 6 }) {
- const denominations = [ETH, GWEI, WEI]
+export function getEthConversionFromWeiHex ({ value, fromCurrency = ETH, conversionRate, numberOfDecimals = 6 }) {
+ const denominations = [fromCurrency, GWEI, WEI]
let nonZeroDenomination
@@ -29,7 +29,8 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec
const convertedValue = getValueFromWeiHex({
value,
conversionRate,
- toCurrency: ETH,
+ fromCurrency,
+ toCurrency: fromCurrency,
numberOfDecimals,
toDenomination: denominations[i],
})
@@ -45,6 +46,7 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec
export function getValueFromWeiHex ({
value,
+ fromCurrency = ETH,
toCurrency,
conversionRate,
numberOfDecimals,
@@ -53,7 +55,7 @@ export function getValueFromWeiHex ({
return conversionUtil(value, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
- fromCurrency: ETH,
+ fromCurrency,
toCurrency,
numberOfDecimals,
fromDenomination: WEI,
diff --git a/ui/app/helpers/transactions.util.js b/ui/app/helpers/transactions.util.js
index e50196196..2f4b1d095 100644
--- a/ui/app/helpers/transactions.util.js
+++ b/ui/app/helpers/transactions.util.js
@@ -27,10 +27,21 @@ export function getTokenData (data = '') {
const registry = new MethodRegistry({ provider: global.ethereumProvider })
+/**
+ * Attempts to return the method data from the MethodRegistry library, if the method exists in the
+ * registry. Otherwise, returns an empty object.
+ * @param {string} data - The hex data (@code txParams.data) of a transaction
+ * @returns {Object}
+ */
export async function getMethodData (data = '') {
const prefixedData = ethUtil.addHexPrefix(data)
const fourBytePrefix = prefixedData.slice(0, 10)
const sig = await registry.lookup(fourBytePrefix)
+
+ if (!sig) {
+ return {}
+ }
+
const parsedResult = registry.parse(sig)
return {
@@ -114,7 +125,9 @@ export function getLatestSubmittedTxWithNonce (transactions = [], nonce = '0x0')
export async function isSmartContractAddress (address) {
const code = await global.eth.getCode(address)
- return code && code !== '0x'
+ // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'
+ const codeIsEmpty = !code || code === '0x' || code === '0x0'
+ return !codeIsEmpty
}
export function sumHexes (...args) {
diff --git a/ui/app/reducers.js b/ui/app/reducers.js
index 80e76d570..e1a982f93 100644
--- a/ui/app/reducers.js
+++ b/ui/app/reducers.js
@@ -1,3 +1,4 @@
+const clone = require('clone')
const extend = require('xtend')
const copyToClipboard = require('copy-to-clipboard')
@@ -52,19 +53,24 @@ function rootReducer (state, action) {
return state
}
+window.getCleanAppState = function () {
+ const state = clone(window.METAMASK_CACHED_LOG_STATE)
+ // append additional information
+ state.version = global.platform.getVersion()
+ state.browser = window.navigator.userAgent
+ // ensure seedWords are not included
+ if (state.metamask) delete state.metamask.seedWords
+ if (state.appState.currentView) delete state.appState.currentView.seedWords
+ return state
+}
+
window.logStateString = function (cb) {
- const state = window.METAMASK_CACHED_LOG_STATE
- const version = global.platform.getVersion()
- const browser = window.navigator.userAgent
- return global.platform.getPlatformInfo((err, platform) => {
- if (err) {
- return cb(err)
- }
- state.version = version
+ const state = window.getCleanAppState()
+ global.platform.getPlatformInfo((err, platform) => {
+ if (err) return cb(err)
state.platform = platform
- state.browser = browser
const stateString = JSON.stringify(state, removeSeedWords, 2)
- return cb(null, stateString)
+ cb(null, stateString)
})
}
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 37d8a9187..22fa53098 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -52,7 +52,7 @@ function reduceMetamask (state, action) {
welcomeScreenSeen: false,
currentLocale: '',
preferences: {
- useETHAsPrimaryCurrency: true,
+ useNativeCurrencyAsPrimaryCurrency: true,
},
}, state.metamask)
diff --git a/ui/app/selectors.js b/ui/app/selectors.js
index 9f11551be..7209f19d1 100644
--- a/ui/app/selectors.js
+++ b/ui/app/selectors.js
@@ -26,6 +26,7 @@ const selectors = {
getAddressBook,
getSendFrom,
getCurrentCurrency,
+ getNativeCurrency,
getSendAmount,
getSelectedTokenToFiatRate,
getSelectedTokenContract,
@@ -143,6 +144,10 @@ function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
+function getNativeCurrency (state) {
+ return state.metamask.nativeCurrency
+}
+
function getSelectedTokenToFiatRate (state) {
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
const conversionRate = conversionRateSelector(state)
diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js
index 86b10bac3..90924c036 100644
--- a/ui/app/selectors/confirm-transaction.js
+++ b/ui/app/selectors/confirm-transaction.js
@@ -93,6 +93,7 @@ export const unconfirmedTransactionsCountSelector = createSelector(
export const currentCurrencySelector = state => state.metamask.currentCurrency
export const conversionRateSelector = state => state.metamask.conversionRate
+export const getNativeCurrency = state => state.metamask.nativeCurrency
const txDataSelector = state => state.confirmTransaction.txData
const tokenDataSelector = state => state.confirmTransaction.tokenData
diff --git a/ui/app/util.js b/ui/app/util.js
index 37c0fb698..b19a028cc 100644
--- a/ui/app/util.js
+++ b/ui/app/util.js
@@ -128,7 +128,7 @@ function parseBalance (balance) {
// Takes wei hex, returns an object with three properties.
// Its "formatted" property is what we generally use to render values.
-function formatBalance (balance, decimalsToKeep, needsParse = true) {
+function formatBalance (balance, decimalsToKeep, needsParse = true, ticker = 'ETH') {
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
var beforeDecimal = parsed[0]
var afterDecimal = parsed[1]
@@ -138,14 +138,14 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) {
if (afterDecimal !== '0') {
var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
if (sigFigs) { afterDecimal = sigFigs[0] }
- formatted = '0.' + afterDecimal + ' ETH'
+ formatted = '0.' + afterDecimal + ` ${ticker}`
}
} else {
- formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
+ formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ` ${ticker}`
}
} else {
afterDecimal += Array(decimalsToKeep).join('0')
- formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
+ formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ` ${ticker}`
}
return formatted
}