aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/app/account-detail.js17
-rw-r--r--ui/app/accounts/account-list-item.js9
-rw-r--r--ui/app/accounts/import/index.js6
-rw-r--r--ui/app/accounts/import/json.js75
-rw-r--r--ui/app/accounts/import/private-key.js3
-rw-r--r--ui/app/accounts/index.js21
-rw-r--r--ui/app/actions.js112
-rw-r--r--ui/app/app.js9
-rw-r--r--ui/app/components/buy-button-subview.js1
-rw-r--r--ui/app/components/coinbase-form.js1
-rw-r--r--ui/app/components/loading.js8
-rw-r--r--ui/app/components/pending-msg-details.js2
-rw-r--r--ui/app/components/pending-tx-details.js2
-rw-r--r--ui/app/components/shapeshift-form.js1
-rw-r--r--ui/app/components/transaction-list-item-icon.js8
-rw-r--r--ui/app/components/transaction-list-item.js1
-rw-r--r--ui/app/components/transaction-list.js4
-rw-r--r--ui/app/conf-tx.js20
-rw-r--r--ui/app/css/index.css10
-rw-r--r--ui/app/first-time/init-menu.js1
-rw-r--r--ui/app/reducers/app.js27
-rw-r--r--ui/app/reducers/metamask.js20
-rw-r--r--ui/app/send.js2
-rw-r--r--ui/example.js6
-rw-r--r--ui/index.js4
-rw-r--r--ui/lib/tx-helper.js6
26 files changed, 259 insertions, 117 deletions
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index 7a0c599ba..514be7f25 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -24,12 +24,12 @@ function mapStateToProps (state) {
metamask: state.metamask,
identities: state.metamask.identities,
accounts: state.metamask.accounts,
- address: state.metamask.selectedAccount,
+ address: state.metamask.selectedAddress,
accountDetail: state.appState.accountDetail,
network: state.metamask.network,
- unconfMsgs: valuesFor(state.metamask.unconfMsgs),
+ unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
shapeShiftTxList: state.metamask.shapeShiftTxList,
- transactions: state.metamask.selectedAccountTxList || [],
+ transactions: state.metamask.selectedAddressTxList || [],
}
}
@@ -41,6 +41,7 @@ function AccountDetailScreen () {
AccountDetailScreen.prototype.render = function () {
var props = this.props
var selected = props.address || Object.keys(props.accounts)[0]
+ var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
var identity = props.identities[selected]
var account = props.accounts[selected]
const { network } = props
@@ -116,22 +117,20 @@ AccountDetailScreen.prototype.render = function () {
marginBottom: '15px',
color: '#AEAEAE',
},
- }, ethUtil.toChecksumAddress(selected)),
+ }, checksumAddress),
// copy and export
h('.flex-row', {
style: {
justifyContent: 'flex-end',
- position: 'relative',
- bottom: '15px',
},
}, [
h(AccountInfoLink, { selected, network }),
h(CopyButton, {
- value: ethUtil.toChecksumAddress(selected),
+ value: checksumAddress,
}),
h(Tooltip, {
@@ -247,11 +246,11 @@ AccountDetailScreen.prototype.subview = function () {
}
AccountDetailScreen.prototype.transactionList = function () {
- const {transactions, unconfMsgs, address, network, shapeShiftTxList } = this.props
+ const {transactions, unapprovedMsgs, address, network, shapeShiftTxList } = this.props
return h(TransactionList, {
transactions: transactions.sort((a, b) => b.time - a.time),
network,
- unconfMsgs,
+ unapprovedMsgs,
address,
shapeShiftTxList,
viewPendingTx: (txId) => {
diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js
index 16019c88a..2a3c13d05 100644
--- a/ui/app/accounts/account-list-item.js
+++ b/ui/app/accounts/account-list-item.js
@@ -15,9 +15,10 @@ function AccountListItem () {
}
AccountListItem.prototype.render = function () {
- const { identity, selectedAccount, accounts, onShowDetail } = this.props
+ const { identity, selectedAddress, accounts, onShowDetail } = this.props
- const isSelected = selectedAccount === identity.address
+ const checksumAddress = identity && identity.address && ethUtil.toChecksumAddress(identity.address)
+ const isSelected = selectedAddress === identity.address
const account = accounts[identity.address]
const selectedClass = isSelected ? '.selected' : ''
@@ -48,7 +49,7 @@ AccountListItem.prototype.render = function () {
overflow: 'hidden',
textOverflow: 'ellipsis',
},
- }, ethUtil.toChecksumAddress(identity.address)),
+ }, checksumAddress),
h(EthBalance, {
value: account && account.balance,
style: {
@@ -65,7 +66,7 @@ AccountListItem.prototype.render = function () {
},
}, [
h(CopyButton, {
- value: ethUtil.toChecksumAddress(identity.address),
+ value: checksumAddress,
}),
]),
])
diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js
index 18a6b985c..96350852a 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/accounts/import/index.js
@@ -6,11 +6,11 @@ import Select from 'react-select'
// Subviews
const JsonImportView = require('./json.js')
-const SeedImportView = require('./seed.js')
const PrivateKeyImportView = require('./private-key.js')
const menuItems = [
'Private Key',
+ 'JSON File',
]
module.exports = connect(mapStateToProps)(AccountImportSubview)
@@ -81,10 +81,10 @@ AccountImportSubview.prototype.renderImportView = function() {
const current = type || menuItems[0]
switch (current) {
- case 'HD Key Tree':
- return h(SeedImportView)
case 'Private Key':
return h(PrivateKeyImportView)
+ case 'JSON File':
+ return h(JsonImportView)
default:
return h(JsonImportView)
}
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js
index 22cf95cfd..1c2b331d4 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/accounts/import/json.js
@@ -2,11 +2,15 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
+const actions = require('../../actions')
+const FileInput = require('react-simple-file-input').default
module.exports = connect(mapStateToProps)(JsonImportSubview)
function mapStateToProps (state) {
- return {}
+ return {
+ error: state.appState.warning,
+ }
}
inherits(JsonImportSubview, Component)
@@ -15,13 +19,80 @@ function JsonImportSubview () {
}
JsonImportSubview.prototype.render = function () {
+ const { error } = this.props
+
return (
h('div', {
style: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ padding: '5px 15px 0px 15px',
},
}, [
- `Upload your json file here!`,
+
+ h('p', 'Used by a variety of different clients'),
+
+ h(FileInput, {
+ readAs: 'text',
+ onLoad: this.onLoad.bind(this),
+ style: {
+ margin: '20px 0px 12px 20px',
+ fontSize: '15px',
+ },
+ }),
+
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ placeholder: 'Enter password',
+ id: 'json-password-box',
+ onKeyPress: this.createKeyringOnEnter.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ h('button.primary', {
+ onClick: this.createNewKeychain.bind(this),
+ style: {
+ margin: 12,
+ },
+ }, 'Import'),
+
+ error ? h('span.warning', error) : null,
])
)
}
+JsonImportSubview.prototype.onLoad = function (event, file) {
+ this.setState({file: file, fileContents: event.target.result})
+}
+
+JsonImportSubview.prototype.createKeyringOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+}
+
+JsonImportSubview.prototype.createNewKeychain = function () {
+ const state = this.state
+ const { fileContents } = state
+
+ if (!fileContents) {
+ const message = 'You must select a file to import.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ const passwordInput = document.getElementById('json-password-box')
+ const password = passwordInput.value
+
+ if (!password) {
+ const message = 'You must enter a password for the selected file.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ this.props.dispatch(actions.importNewAccount('JSON File', [ fileContents, password ]))
+}
+
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js
index 6b988a76b..b139a0374 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/accounts/import/private-key.js
@@ -2,7 +2,6 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const type = 'Simple Key Pair'
const actions = require('../../actions')
module.exports = connect(mapStateToProps)(PrivateKeyImportView)
@@ -64,6 +63,6 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
- this.props.dispatch(actions.addNewKeyring(type, [ privateKey ]))
+ this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ]))
}
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
index e6f376735..e236a4e85 100644
--- a/ui/app/accounts/index.js
+++ b/ui/app/accounts/index.js
@@ -10,16 +10,16 @@ const AccountListItem = require('./account-list-item')
module.exports = connect(mapStateToProps)(AccountsScreen)
function mapStateToProps (state) {
- const pendingTxs = valuesFor(state.metamask.unconfTxs)
+ const pendingTxs = valuesFor(state.metamask.unapprovedTxs)
.filter(tx => tx.txParams.metamaskNetworkId === state.metamask.network)
- const pendingMsgs = valuesFor(state.metamask.unconfMsgs)
+ const pendingMsgs = valuesFor(state.metamask.unapprovedMsgs)
const pending = pendingTxs.concat(pendingMsgs)
return {
accounts: state.metamask.accounts,
identities: state.metamask.identities,
- unconfTxs: state.metamask.unconfTxs,
- selectedAccount: state.metamask.selectedAccount,
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ selectedAddress: state.metamask.selectedAddress,
scrollToBottom: state.appState.scrollToBottom,
pending,
keyrings: state.metamask.keyrings,
@@ -35,7 +35,7 @@ AccountsScreen.prototype.render = function () {
const props = this.props
const { keyrings } = props
const identityList = valuesFor(props.identities)
- const unconfTxList = valuesFor(props.unconfTxs)
+ const unapprovedTxList = valuesFor(props.unapprovedTxs)
return (
@@ -80,7 +80,7 @@ AccountsScreen.prototype.render = function () {
return h(AccountListItem, {
key: `acct-panel-${identity.address}`,
identity,
- selectedAccount: this.props.selectedAccount,
+ selectedAddress: this.props.selectedAddress,
accounts: this.props.accounts,
onShowDetail: this.onShowDetail.bind(this),
pending,
@@ -107,7 +107,7 @@ AccountsScreen.prototype.render = function () {
h('hr.horizontal-line'),
]),
- unconfTxList.length ? (
+ unapprovedTxList.length ? (
h('.unconftx-link.flex-row.flex-center', {
onClick: this.navigateToConfTx.bind(this),
@@ -139,13 +139,6 @@ AccountsScreen.prototype.navigateToConfTx = function () {
this.props.dispatch(actions.showConfTxPage())
}
-AccountsScreen.prototype.onSelect = function (address, event) {
- event.stopPropagation()
- // if already selected, deselect
- if (this.props.selectedAccount === address) address = null
- this.props.dispatch(actions.setSelectedAccount(address))
-}
-
AccountsScreen.prototype.onShowDetail = function (address, event) {
event.stopPropagation()
this.props.dispatch(actions.showAccountDetail(address))
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 9a68d231a..65e5add8c 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -43,6 +43,7 @@ var actions = {
createNewVaultAndRestore: createNewVaultAndRestore,
createNewVaultInProgress: createNewVaultInProgress,
addNewKeyring,
+ importNewAccount,
addNewAccount,
NEW_ACCOUNT_SCREEN: 'NEW_ACCOUNT_SCREEN',
navigateToNewAccountScreen,
@@ -89,7 +90,6 @@ var actions = {
TRANSACTION_ERROR: 'TRANSACTION_ERROR',
NEXT_TX: 'NEXT_TX',
PREVIOUS_TX: 'PREV_TX',
- setSelectedAccount: setSelectedAccount,
signMsg: signMsg,
cancelMsg: cancelMsg,
sendTx: sendTx,
@@ -158,6 +158,7 @@ var actions = {
showNewKeychain: showNewKeychain,
callBackgroundThenUpdate,
+ forceUpdateMetamaskState,
}
module.exports = actions
@@ -179,13 +180,14 @@ function tryUnlockMetamask (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
dispatch(actions.unlockInProgress())
- background.submitPassword(password, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.submitPassword`)
+ background.submitPassword(password, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.unlockFailed(err.message))
} else {
dispatch(actions.transitionForward())
- dispatch(actions.updateMetamaskState(newState))
+ forceUpdateMetamaskState(dispatch)
}
})
}
@@ -206,6 +208,7 @@ function transitionBackward () {
function confirmSeedWords () {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.clearSeedWordCache`)
background.clearSeedWordCache((err, account) => {
dispatch(actions.hideLoadingIndication())
if (err) {
@@ -221,6 +224,7 @@ function confirmSeedWords () {
function createNewVaultAndRestore (password, seed) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.createNewVaultAndRestore`)
background.createNewVaultAndRestore(password, seed, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
@@ -230,7 +234,23 @@ function createNewVaultAndRestore (password, seed) {
}
function createNewVaultAndKeychain (password) {
- return callBackgroundThenUpdate(background.createNewVaultAndKeychain, password)
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.createNewVaultAndKeychain`)
+ background.createNewVaultAndKeychain(password, (err) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ if (global.METAMASK_DEBUG) console.log(`background.placeSeedWords`)
+ background.placeSeedWords((err) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.hideLoadingIndication())
+ forceUpdateMetamaskState(dispatch)
+ })
+ })
+ }
}
function revealSeedConfirmation () {
@@ -242,8 +262,10 @@ function revealSeedConfirmation () {
function requestRevealSeed (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.submitPassword`)
background.submitPassword(password, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
+ if (global.METAMASK_DEBUG) console.log(`background.placeSeedWords`)
background.placeSeedWords((err) => {
if (err) return dispatch(actions.displayWarning(err.message))
dispatch(actions.hideLoadingIndication())
@@ -255,15 +277,37 @@ function requestRevealSeed (password) {
function addNewKeyring (type, opts) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.addNewKeyring(type, opts, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.addNewKeyring`)
+ background.addNewKeyring(type, opts, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.updateMetamaskState(newState))
dispatch(actions.showAccountsPage())
})
}
}
+function importNewAccount (strategy, args) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication('This may take a while, be patient.'))
+ if (global.METAMASK_DEBUG) console.log(`background.importAccountWithStrategy`)
+ background.importAccountWithStrategy(strategy, args, (err) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) return dispatch(actions.displayWarning(err.message))
+ if (global.METAMASK_DEBUG) console.log(`background.getState`)
+ background.getState((err, newState) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch({
+ type: actions.SHOW_ACCOUNT_DETAIL,
+ value: newState.selectedAddress,
+ })
+ })
+ })
+ }
+}
+
function navigateToNewAccountScreen() {
return {
type: this.NEW_ACCOUNT_SCREEN,
@@ -271,6 +315,7 @@ function navigateToNewAccountScreen() {
}
function addNewAccount () {
+ if (global.METAMASK_DEBUG) console.log(`background.addNewAccount`)
return callBackgroundThenUpdate(background.addNewAccount)
}
@@ -280,15 +325,16 @@ function showInfoPage () {
}
}
-function setSelectedAccount (address) {
- return callBackgroundThenUpdate(background.setSelectedAccount, address)
-}
-
-function setCurrentFiat (fiat) {
+function setCurrentFiat (currencyCode) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
- background.setCurrentFiat(fiat, (data, err) => {
+ if (global.METAMASK_DEBUG) console.log(`background.setCurrentFiat`)
+ background.setCurrentCurrency(currencyCode, (err, data) => {
dispatch(this.hideLoadingIndication())
+ if (err) {
+ console.error(err.stack)
+ return dispatch(actions.displayWarning(err.message))
+ }
dispatch({
type: this.SET_CURRENT_FIAT,
value: {
@@ -305,6 +351,7 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.signMessage`)
background.signMessage(msgData, (err) => {
dispatch(actions.hideLoadingIndication())
@@ -316,6 +363,7 @@ function signMsg (msgData) {
function signTx (txData) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.setGasMultiplier`)
background.setGasMultiplier(txData.gasMultiplier, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
web3.eth.sendTransaction(txData, (err, data) => {
@@ -331,9 +379,9 @@ function signTx (txData) {
function sendTx (txData) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.approveTransaction`)
background.approveTransaction(txData.id, (err) => {
if (err) {
- alert(err.message)
dispatch(actions.txError(err))
return console.error(err.message)
}
@@ -357,11 +405,13 @@ function txError (err) {
}
function cancelMsg (msgData) {
+ if (global.METAMASK_DEBUG) console.log(`background.cancelMessage`)
background.cancelMessage(msgData.id)
return actions.completedTx(msgData.id)
}
function cancelTx (txData) {
+ if (global.METAMASK_DEBUG) console.log(`background.cancelTransaction`)
background.cancelTransaction(txData.id)
return actions.completedTx(txData.id)
}
@@ -403,6 +453,7 @@ function showImportPage () {
function agreeToDisclaimer () {
return (dispatch) => {
dispatch(this.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.agreeToDisclaimer`)
background.agreeToDisclaimer((err) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
@@ -473,22 +524,22 @@ function updateMetamaskState (newState) {
}
function lockMetamask () {
+ if (global.METAMASK_DEBUG) console.log(`background.setLocked`)
return callBackgroundThenUpdate(background.setLocked)
}
function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.setSelectedAccount(address, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.setSelectedAddress`)
+ background.setSelectedAddress(address, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
-
- dispatch(actions.updateMetamaskState(newState))
dispatch({
type: actions.SHOW_ACCOUNT_DETAIL,
- value: newState.selectedAccount,
+ value: address,
})
})
}
@@ -553,6 +604,7 @@ function goBackToInitView () {
function markNoticeRead (notice) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.markNoticeRead`)
background.markNoticeRead(notice, (err, notice) => {
dispatch(this.hideLoadingIndication())
if (err) {
@@ -584,6 +636,7 @@ function clearNotices () {
}
function markAccountsFound() {
+ if (global.METAMASK_DEBUG) console.log(`background.markAccountsFound`)
return callBackgroundThenUpdate(background.markAccountsFound)
}
@@ -592,6 +645,7 @@ function markAccountsFound() {
//
function setRpcTarget (newRpc) {
+ if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`)
background.setRpcTarget(newRpc)
return {
type: actions.SET_RPC_TARGET,
@@ -600,6 +654,7 @@ function setRpcTarget (newRpc) {
}
function setProviderType (type) {
+ if (global.METAMASK_DEBUG) console.log(`background.setProviderType`)
background.setProviderType(type)
return {
type: actions.SET_PROVIDER_TYPE,
@@ -608,15 +663,17 @@ function setProviderType (type) {
}
function useEtherscanProvider () {
+ if (global.METAMASK_DEBUG) console.log(`background.useEtherscanProvider`)
background.useEtherscanProvider()
return {
type: actions.USE_ETHERSCAN_PROVIDER,
}
}
-function showLoadingIndication () {
+function showLoadingIndication (message) {
return {
type: actions.SHOW_LOADING,
+ value: message,
}
}
@@ -663,6 +720,7 @@ function exportAccount (address) {
return function (dispatch) {
dispatch(self.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.exportAccount`)
background.exportAccount(address, function (err, result) {
dispatch(self.hideLoadingIndication())
@@ -686,6 +744,7 @@ function showPrivateKey (key) {
function saveAccountLabel (account, label) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.saveAccountLabel`)
background.saveAccountLabel(account, label, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
@@ -707,6 +766,7 @@ function showSendPage () {
function buyEth (address, amount) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.buyEth`)
background.buyEth(address, amount)
dispatch({
type: actions.BUY_ETH,
@@ -782,9 +842,11 @@ function coinShiftRquest (data, marketData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
shapeShiftRequest('shift', { method: 'POST', data}, (response) => {
+ dispatch(actions.hideLoadingIndication())
if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
Deposit your ${response.depositType} to the address bellow:`
+ if (global.METAMASK_DEBUG) console.log(`background.createShapeShiftTx`)
background.createShapeShiftTx(response.deposit, response.depositType)
dispatch(actions.showQrView(response.deposit, [message].concat(marketData)))
})
@@ -853,12 +915,22 @@ function shapeShiftRequest (query, options, cb) {
function callBackgroundThenUpdate (method, ...args) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- method.call(background, ...args, (err, newState) => {
+ method.call(background, ...args, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
- dispatch(actions.updateMetamaskState(newState))
+ forceUpdateMetamaskState(dispatch)
})
}
}
+
+function forceUpdateMetamaskState(dispatch){
+ if (global.METAMASK_DEBUG) console.log(`background.getState`)
+ background.getState((err, newState) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ })
+}
diff --git a/ui/app/app.js b/ui/app/app.js
index 0e04c334c..3bc4897c8 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -43,6 +43,7 @@ function mapStateToProps (state) {
return {
// state from plugin
isLoading: state.appState.isLoading,
+ loadingMessage: state.appState.loadingMessage,
isDisclaimerConfirmed: state.metamask.isDisclaimerConfirmed,
noActiveNotices: state.metamask.noActiveNotices,
isInitialized: state.metamask.isInitialized,
@@ -51,8 +52,8 @@ function mapStateToProps (state) {
activeAddress: state.appState.activeAddress,
transForward: state.appState.transForward,
seedWords: state.metamask.seedWords,
- unconfTxs: state.metamask.unconfTxs,
- unconfMsgs: state.metamask.unconfMsgs,
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
menuOpen: state.appState.menuOpen,
network: state.metamask.network,
provider: state.metamask.provider,
@@ -64,7 +65,7 @@ function mapStateToProps (state) {
App.prototype.render = function () {
var props = this.props
- const { isLoading, transForward } = props
+ const { isLoading, loadingMessage, transForward } = props
return (
@@ -76,7 +77,7 @@ App.prototype.render = function () {
},
}, [
- h(LoadingIndicator, { isLoading }),
+ h(LoadingIndicator, { isLoading, loadingMessage }),
// app bar
this.renderAppBar(),
diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js
index afda5bf59..3074bd7cd 100644
--- a/ui/app/components/buy-button-subview.js
+++ b/ui/app/components/buy-button-subview.js
@@ -13,7 +13,6 @@ module.exports = connect(mapStateToProps)(BuyButtonSubview)
function mapStateToProps (state) {
return {
- selectedAccount: state.selectedAccount,
warning: state.appState.warning,
buyView: state.appState.buyView,
network: state.metamask.network,
diff --git a/ui/app/components/coinbase-form.js b/ui/app/components/coinbase-form.js
index 430a3eead..40f5719bb 100644
--- a/ui/app/components/coinbase-form.js
+++ b/ui/app/components/coinbase-form.js
@@ -9,7 +9,6 @@ module.exports = connect(mapStateToProps)(CoinbaseForm)
function mapStateToProps (state) {
return {
- selectedAccount: state.selectedAccount,
warning: state.appState.warning,
}
}
diff --git a/ui/app/components/loading.js b/ui/app/components/loading.js
index ae735894f..88dc535df 100644
--- a/ui/app/components/loading.js
+++ b/ui/app/components/loading.js
@@ -12,7 +12,7 @@ function LoadingIndicator () {
}
LoadingIndicator.prototype.render = function () {
- var isLoading = this.props.isLoading
+ const { isLoading, loadingMessage } = this.props
return (
h(ReactCSSTransitionGroup, {
@@ -37,8 +37,14 @@ LoadingIndicator.prototype.render = function () {
h('img', {
src: 'images/loading.svg',
}),
+
+ showMessageIfAny(loadingMessage),
]) : null,
])
)
}
+function showMessageIfAny (loadingMessage) {
+ if (!loadingMessage) return null
+ return h('span', loadingMessage)
+}
diff --git a/ui/app/components/pending-msg-details.js b/ui/app/components/pending-msg-details.js
index 404cb8ae2..16308d121 100644
--- a/ui/app/components/pending-msg-details.js
+++ b/ui/app/components/pending-msg-details.js
@@ -16,7 +16,7 @@ PendingMsgDetails.prototype.render = function () {
var msgData = state.txData
var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAccount
+ var address = msgParams.from || state.selectedAddress
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js
index 286931f6f..e8615404e 100644
--- a/ui/app/components/pending-tx-details.js
+++ b/ui/app/components/pending-tx-details.js
@@ -22,7 +22,7 @@ PTXP.render = function () {
var txData = props.txData
var txParams = txData.txParams || {}
- var address = txParams.from || props.selectedAccount
+ var address = txParams.from || props.selectedAddress
var identity = props.identities[address] || { address: address }
var account = props.accounts[address]
var balance = account ? account.balance : '0x0'
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index 383d5b623..8c9686035 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -10,7 +10,6 @@ module.exports = connect(mapStateToProps)(ShapeshiftForm)
function mapStateToProps (state) {
return {
- selectedAccount: state.selectedAccount,
warning: state.appState.warning,
isSubLoading: state.appState.isSubLoading,
qrRequested: state.appState.qrRequested,
diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js
index 353401099..90b4ec094 100644
--- a/ui/app/components/transaction-list-item-icon.js
+++ b/ui/app/components/transaction-list-item-icon.js
@@ -15,15 +15,9 @@ TransactionIcon.prototype.render = function () {
const { transaction, txParams, isMsg } = this.props
switch (transaction.status) {
case 'unapproved':
- return h('.unapproved-tx', {
+ return h( !isMsg ? '.unapproved-tx-icon' : 'i.fa.fa-certificate.fa-lg', {
style: {
width: '24px',
- height: '24px',
- background: '#4dffff',
- border: 'solid',
- borderColor: '#AEAEAE',
- borderWidth: '0.5px',
- borderRadius: '13px',
},
})
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 95e850264..44d2dc587 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -33,7 +33,6 @@ TransactionListItem.prototype.render = function () {
var isMsg = ('msgParams' in transaction)
var isTx = ('txParams' in transaction)
var isPending = transaction.status === 'unapproved'
-
let txParams
if (isTx) {
txParams = transaction.txParams
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
index b055ca9d5..3ae953637 100644
--- a/ui/app/components/transaction-list.js
+++ b/ui/app/components/transaction-list.js
@@ -13,13 +13,13 @@ function TransactionList () {
}
TransactionList.prototype.render = function () {
- const { transactions, network, unconfMsgs } = this.props
+ const { transactions, network, unapprovedMsgs } = this.props
var shapeShiftTxList
if (network === '1') {
shapeShiftTxList = this.props.shapeShiftTxList
}
- const txsToRender = !shapeShiftTxList ? transactions.concat(unconfMsgs) : transactions.concat(unconfMsgs, shapeShiftTxList)
+ const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
.sort((a, b) => b.time - a.time)
return (
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index a6e03c3ed..a27219576 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -19,9 +19,9 @@ function mapStateToProps (state) {
return {
identities: state.metamask.identities,
accounts: state.metamask.accounts,
- selectedAccount: state.metamask.selectedAccount,
- unconfTxs: state.metamask.unconfTxs,
- unconfMsgs: state.metamask.unconfMsgs,
+ selectedAddress: state.metamask.selectedAddress,
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
index: state.appState.currentView.context,
warning: state.appState.warning,
network: state.metamask.network,
@@ -39,10 +39,10 @@ ConfirmTxScreen.prototype.render = function () {
var network = state.network
var provider = state.provider
- var unconfTxs = state.unconfTxs
- var unconfMsgs = state.unconfMsgs
+ var unapprovedTxs = state.unapprovedTxs
+ var unapprovedMsgs = state.unapprovedMsgs
- var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
+ var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
var index = state.index !== undefined && unconfTxList[index] ? state.index : 0
var txData = unconfTxList[index] || {}
var txParams = txData.params || {}
@@ -99,12 +99,12 @@ ConfirmTxScreen.prototype.render = function () {
// Properties
txData: txData,
key: txData.id,
- selectedAccount: state.selectedAccount,
+ selectedAddress: state.selectedAddress,
accounts: state.accounts,
identities: state.identities,
insufficientBalance: this.checkBalanceAgainstTx(txData),
// Actions
- buyEth: this.buyEth.bind(this, txParams.from || state.selectedAccount),
+ buyEth: this.buyEth.bind(this, txParams.from || state.selectedAddress),
sendTransaction: this.sendTransaction.bind(this, txData),
cancelTransaction: this.cancelTransaction.bind(this, txData),
signMessage: this.signMessage.bind(this, txData),
@@ -131,10 +131,10 @@ function currentTxView (opts) {
ConfirmTxScreen.prototype.checkBalanceAgainstTx = function (txData) {
if (!txData.txParams) return false
var state = this.props
- var address = txData.txParams.from || state.selectedAccount
+ var address = txData.txParams.from || state.selectedAddress
var account = state.accounts[address]
var balance = account ? account.balance : '0x0'
- var maxCost = new BN(txData.maxCost)
+ var maxCost = new BN(txData.maxCost, 16)
var balanceBn = new BN(ethUtil.stripHexPrefix(balance), 16)
return maxCost.gt(balanceBn)
diff --git a/ui/app/css/index.css b/ui/app/css/index.css
index 16e1dbe7e..4b9b5b67d 100644
--- a/ui/app/css/index.css
+++ b/ui/app/css/index.css
@@ -408,6 +408,16 @@ input.large-input {
.name-label{
}
+
+.unapproved-tx-icon {
+ height: 24px;
+ background: #4dffff;
+ border: solid;
+ border-color: #AEAEAE;
+ border-width: 0.5px;
+ border-radius: 13px;
+}
+
.edit-text {
height: 100%;
visibility: hidden;
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 152d28809..cc7c51bd3 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -152,7 +152,6 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
var password = passwordBox.value
var passwordConfirmBox = document.getElementById('password-box-confirm')
var passwordConfirm = passwordConfirmBox.value
- // var entropy = document.getElementById('entropy-text-entry').value
if (password.length < 8) {
this.warning = 'password not long enough'
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index ae91272cc..de6536c2e 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -7,10 +7,10 @@ module.exports = reduceApp
function reduceApp (state, action) {
// clone and defaults
- const selectedAccount = state.metamask.selectedAccount
+ const selectedAddress = state.metamask.selectedAddress
const pendingTxs = hasPendingTxs(state)
let name = 'accounts'
- if (selectedAccount) {
+ if (selectedAddress) {
name = 'accountDetail'
}
if (pendingTxs) {
@@ -20,7 +20,7 @@ function reduceApp (state, action) {
var defaultView = {
name,
detailView: null,
- context: selectedAccount,
+ context: selectedAddress,
}
// confirm seed words
@@ -307,11 +307,11 @@ function reduceApp (state, action) {
})
case actions.COMPLETED_TX:
- var unconfTxs = state.metamask.unconfTxs
- var unconfMsgs = state.metamask.unconfMsgs
+ var unapprovedTxs = state.metamask.unapprovedTxs
+ var unapprovedMsgs = state.metamask.unapprovedMsgs
var network = state.metamask.network
- var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
+ var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
.filter(tx => tx !== tx.id)
if (unconfTxList && unconfTxList.length > 0) {
@@ -331,7 +331,7 @@ function reduceApp (state, action) {
warning: null,
currentView: {
name: 'accountDetail',
- context: state.metamask.selectedAccount,
+ context: state.metamask.selectedAddress,
},
accountDetail: {
subview: 'transactions',
@@ -386,6 +386,7 @@ function reduceApp (state, action) {
case actions.SHOW_LOADING:
return extend(appState, {
isLoading: true,
+ loadingMessage: action.value,
})
case actions.HIDE_LOADING:
@@ -571,18 +572,18 @@ function reduceApp (state, action) {
}
function hasPendingTxs (state) {
- var unconfTxs = state.metamask.unconfTxs
- var unconfMsgs = state.metamask.unconfMsgs
+ var unapprovedTxs = state.metamask.unapprovedTxs
+ var unapprovedMsgs = state.metamask.unapprovedMsgs
var network = state.metamask.network
- var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
+ var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
return unconfTxList.length > 0
}
function indexForPending (state, txId) {
- var unconfTxs = state.metamask.unconfTxs
- var unconfMsgs = state.metamask.unconfMsgs
+ var unapprovedTxs = state.metamask.unapprovedTxs
+ var unapprovedMsgs = state.metamask.unapprovedMsgs
var network = state.metamask.network
- var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
+ var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
let idx
unconfTxList.forEach((tx, i) => {
if (tx.id === txId) {
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 8679ab062..4f13c1ab1 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -12,7 +12,7 @@ function reduceMetamask (state, action) {
isUnlocked: false,
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
- unconfTxs: {},
+ unapprovedTxs: {},
currentFiat: 'USD',
conversionRate: 0,
conversionDate: 'N/A',
@@ -50,7 +50,7 @@ function reduceMetamask (state, action) {
return extend(metamaskState, {
isUnlocked: true,
isInitialized: true,
- selectedAccount: action.value,
+ selectedAddress: action.value,
})
case actions.LOCK_METAMASK:
@@ -76,17 +76,17 @@ function reduceMetamask (state, action) {
case actions.COMPLETED_TX:
var stringId = String(action.id)
newState = extend(metamaskState, {
- unconfTxs: {},
- unconfMsgs: {},
+ unapprovedTxs: {},
+ unapprovedMsgs: {},
})
- for (const id in metamaskState.unconfTxs) {
+ for (const id in metamaskState.unapprovedTxs) {
if (id !== stringId) {
- newState.unconfTxs[id] = metamaskState.unconfTxs[id]
+ newState.unapprovedTxs[id] = metamaskState.unapprovedTxs[id]
}
}
- for (const id in metamaskState.unconfMsgs) {
+ for (const id in metamaskState.unapprovedMsgs) {
if (id !== stringId) {
- newState.unconfMsgs[id] = metamaskState.unconfMsgs[id]
+ newState.unapprovedMsgs[id] = metamaskState.unapprovedMsgs[id]
}
}
return newState
@@ -101,7 +101,7 @@ function reduceMetamask (state, action) {
newState = extend(metamaskState, {
isUnlocked: true,
isInitialized: true,
- selectedAccount: action.value,
+ selectedAddress: action.value,
})
delete newState.seedWords
return newState
@@ -110,7 +110,7 @@ function reduceMetamask (state, action) {
newState = extend(metamaskState, {
isUnlocked: true,
isInitialized: true,
- selectedAccount: action.value,
+ selectedAddress: action.value,
})
delete newState.seedWords
return newState
diff --git a/ui/app/send.js b/ui/app/send.js
index b8af19028..d16270b41 100644
--- a/ui/app/send.js
+++ b/ui/app/send.js
@@ -16,7 +16,7 @@ module.exports = connect(mapStateToProps)(SendTransactionScreen)
function mapStateToProps (state) {
var result = {
- address: state.metamask.selectedAccount,
+ address: state.metamask.selectedAddress,
accounts: state.metamask.accounts,
identities: state.metamask.identities,
warning: state.appState.warning,
diff --git a/ui/example.js b/ui/example.js
index 888748c48..4627c0e9c 100644
--- a/ui/example.js
+++ b/ui/example.js
@@ -29,7 +29,7 @@ var identities = {
},
}
-var unconfTxs = {}
+var unapprovedTxs = {}
addUnconfTx({
from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
@@ -45,7 +45,7 @@ addUnconfTx({
function addUnconfTx (txParams) {
var time = (new Date()).getTime()
var id = createRandomId()
- unconfTxs[id] = {
+ unapprovedTxs[id] = {
id: id,
txParams: txParams,
time: time,
@@ -59,7 +59,7 @@ function getState () {
return {
isUnlocked: isUnlocked,
identities: isUnlocked ? identities : {},
- unconfTxs: isUnlocked ? unconfTxs : {},
+ unapprovedTxs: isUnlocked ? unapprovedTxs : {},
selectedAccount: selectedAccount,
}
}
diff --git a/ui/index.js b/ui/index.js
index dedfd8c8c..8855064f6 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -32,8 +32,8 @@ function startApp (metamaskState, accountManager, opts) {
})
// if unconfirmed txs, start on txConf page
- var unconfirmedTxsAll = txHelper(metamaskState.unconfTxs, metamaskState.unconfMsgs, metamaskState.network)
- if (unconfirmedTxsAll.length > 0) {
+ var unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.network)
+ if (unapprovedTxsAll.length > 0) {
store.dispatch(actions.showConfTxPage())
}
diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js
index c984bc9af..fa7a94cdc 100644
--- a/ui/lib/tx-helper.js
+++ b/ui/lib/tx-helper.js
@@ -1,8 +1,8 @@
const valuesFor = require('../app/util').valuesFor
-module.exports = function (unconfTxs, unconfMsgs, network) {
- var txValues = network ? valuesFor(unconfTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unconfTxs)
- var msgValues = valuesFor(unconfMsgs)
+module.exports = function (unapprovedTxs, unapprovedMsgs, network) {
+ var txValues = network ? valuesFor(unapprovedTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
+ var msgValues = valuesFor(unapprovedMsgs)
var allValues = txValues.concat(msgValues)
return allValues.sort(tx => tx.time)
}