aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/scripts/background.js42
-rw-r--r--app/scripts/config.js7
-rw-r--r--app/scripts/controllers/transactions.js (renamed from app/scripts/transaction-manager.js)4
-rw-r--r--app/scripts/first-time-state.js2
-rw-r--r--app/scripts/lib/config-manager.js13
-rw-r--r--app/scripts/metamask-controller.js32
-rw-r--r--app/scripts/migrations/013.js34
-rw-r--r--app/scripts/migrations/index.js1
-rw-r--r--mascara/README.md13
-rw-r--r--mascara/ui/index.html3
-rw-r--r--package.json14
-rw-r--r--test/lib/migrations/001.json15
-rw-r--r--test/lib/mock-store.js18
-rw-r--r--test/unit/components/pending-tx-test.js89
-rw-r--r--test/unit/migrations-test.js6
-rw-r--r--test/unit/tx-controller-test.js (renamed from test/unit/tx-manager-test.js)108
-rw-r--r--ui/app/account-detail.js10
-rw-r--r--ui/app/accounts/account-list-item.js5
-rw-r--r--ui/app/accounts/index.js6
-rw-r--r--ui/app/app.js2
-rw-r--r--ui/app/components/drop-menu-item.js2
-rw-r--r--ui/app/components/ens-input.js5
-rw-r--r--ui/app/components/eth-balance.js16
-rw-r--r--ui/app/components/fiat-value.js20
-rw-r--r--ui/app/components/identicon.js13
-rw-r--r--ui/app/components/network.js4
-rw-r--r--ui/app/components/pending-tx.js93
-rw-r--r--ui/app/components/shift-list-item.js12
-rw-r--r--ui/app/components/transaction-list-item.js8
-rw-r--r--ui/app/components/transaction-list.js3
-rw-r--r--ui/app/conf-tx.js8
-rw-r--r--ui/app/config.js2
-rw-r--r--ui/app/send.js24
34 files changed, 424 insertions, 211 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 08dd41a3b..b49d8f3cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- Trim currency list.
- Enable decimals in our gas prices.
- Fix reset button.
+- Fix event filter bug introduced by newer versions of Geth.
## 3.6.4 2017-5-8
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 58f8e7556..63c8a7252 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,6 +1,5 @@
const urlUtil = require('url')
const endOfStream = require('end-of-stream')
-const asyncQ = require('async-q')
const pipe = require('pump')
const LocalStorageStore = require('obs-store/lib/localStorage')
const storeTransform = require('obs-store/lib/transform')
@@ -30,34 +29,29 @@ let popupIsOpen = false
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
// initialization flow
-asyncQ.waterfall([
- () => loadStateFromPersistence(),
- (initState) => setupController(initState),
-])
-.then(() => console.log('MetaMask initialization complete.'))
-.catch((err) => { console.error(err) })
+initialize().catch(console.error)
+
+async function initialize() {
+ const initState = await loadStateFromPersistence()
+ await setupController(initState)
+ console.log('MetaMask initialization complete.')
+}
//
// State and Persistence
//
-function loadStateFromPersistence () {
+async function loadStateFromPersistence () {
// migrations
const migrator = new Migrator({ migrations })
- const initialState = migrator.generateInitialState(firstTimeState)
- return asyncQ.waterfall([
- // read from disk
- () => Promise.resolve(diskStore.getState() || initialState),
- // migrate data
- (versionedData) => migrator.migrateData(versionedData),
- // write to disk
- (versionedData) => {
- diskStore.putState(versionedData)
- return Promise.resolve(versionedData)
- },
- // resolve to just data
- (versionedData) => Promise.resolve(versionedData.data),
- ])
+ // read from disk
+ let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState)
+ // migrate data
+ versionedData = await migrator.migrateData(versionedData)
+ // write to disk
+ diskStore.putState(versionedData)
+ // return just the data
+ return versionedData.data
}
function setupController (initState) {
@@ -120,13 +114,13 @@ function setupController (initState) {
//
updateBadge()
- controller.txManager.on('updateBadge', updateBadge)
+ controller.txController.on('updateBadge', updateBadge)
controller.messageManager.on('updateBadge', updateBadge)
// plugin badge text
function updateBadge () {
var label = ''
- var unapprovedTxCount = controller.txManager.unapprovedTxCount
+ var unapprovedTxCount = controller.txController.unapprovedTxCount
var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
var count = unapprovedTxCount + unapprovedMsgCount
if (count) {
diff --git a/app/scripts/config.js b/app/scripts/config.js
index 391c67230..8e28db80e 100644
--- a/app/scripts/config.js
+++ b/app/scripts/config.js
@@ -1,17 +1,14 @@
const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask'
-const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask'
+const ROPSTEN_RPC_URL = 'https://ropsten.infura.io/metamask'
const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask'
const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask'
-const DEFAULT_RPC_URL = TESTNET_RPC_URL
global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
module.exports = {
network: {
- default: DEFAULT_RPC_URL,
mainnet: MAINET_RPC_URL,
- testnet: TESTNET_RPC_URL,
- morden: TESTNET_RPC_URL,
+ ropsten: ROPSTEN_RPC_URL,
kovan: KOVAN_RPC_URL,
rinkeby: RINKEBY_RPC_URL,
},
diff --git a/app/scripts/transaction-manager.js b/app/scripts/controllers/transactions.js
index 9f267160f..21dd25b30 100644
--- a/app/scripts/transaction-manager.js
+++ b/app/scripts/controllers/transactions.js
@@ -5,8 +5,8 @@ const Semaphore = require('semaphore')
const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const EthQuery = require('eth-query')
-const TxProviderUtil = require('./lib/tx-utils')
-const createId = require('./lib/random-id')
+const TxProviderUtil = require('../lib/tx-utils')
+const createId = require('../lib/random-id')
module.exports = class TransactionManager extends EventEmitter {
constructor (opts) {
diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js
index 87a7bb7b5..29ec1d8d3 100644
--- a/app/scripts/first-time-state.js
+++ b/app/scripts/first-time-state.js
@@ -5,7 +5,7 @@
module.exports = {
config: {
provider: {
- type: 'testnet',
+ type: 'rinkeby',
},
},
}
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index ab9410842..d77cd2126 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -2,13 +2,11 @@ const MetamaskConfig = require('../config.js')
const ethUtil = require('ethereumjs-util')
const normalize = require('eth-sig-util').normalize
-const TESTNET_RPC = MetamaskConfig.network.testnet
const MAINNET_RPC = MetamaskConfig.network.mainnet
-const MORDEN_RPC = MetamaskConfig.network.morden
+const ROPSTEN_RPC = MetamaskConfig.network.ropsten
const KOVAN_RPC = MetamaskConfig.network.kovan
const RINKEBY_RPC = MetamaskConfig.network.rinkeby
-
/* The config-manager is a convenience object
* wrapping a pojo-migrator.
*
@@ -147,11 +145,8 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
case 'mainnet':
return MAINNET_RPC
- case 'testnet':
- return TESTNET_RPC
-
- case 'morden':
- return MORDEN_RPC
+ case 'ropsten':
+ return ROPSTEN_RPC
case 'kovan':
return KOVAN_RPC
@@ -160,7 +155,7 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
return RINKEBY_RPC
default:
- return provider && provider.rpcTarget ? provider.rpcTarget : TESTNET_RPC
+ return provider && provider.rpcTarget ? provider.rpcTarget : RINKEBY_RPC
}
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 175602ec1..f18da9033 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -17,7 +17,7 @@ const ShapeShiftController = require('./controllers/shapeshift')
const AddressBookController = require('./controllers/address-book')
const MessageManager = require('./lib/message-manager')
const PersonalMessageManager = require('./lib/personal-message-manager')
-const TxManager = require('./transaction-manager')
+const TransactionController = require('./controllers/transactions')
const ConfigManager = require('./lib/config-manager')
const autoFaucet = require('./lib/auto-faucet')
const nodeify = require('./lib/nodeify')
@@ -90,8 +90,8 @@ module.exports = class MetamaskController extends EventEmitter {
}, this.keyringController)
// tx mgmt
- this.txManager = new TxManager({
- initState: initState.TransactionManager,
+ this.txController = new TransactionController({
+ initState: initState.TransactionController || initState.TransactionManager,
networkStore: this.networkStore,
preferencesStore: this.preferencesController.store,
txHistoryLimit: 40,
@@ -119,8 +119,8 @@ module.exports = class MetamaskController extends EventEmitter {
this.publicConfigStore = this.initPublicConfigStore()
// manual disk state subscriptions
- this.txManager.store.subscribe((state) => {
- this.store.updateState({ TransactionManager: state })
+ this.txController.store.subscribe((state) => {
+ this.store.updateState({ TransactionController: state })
})
this.keyringController.store.subscribe((state) => {
this.store.updateState({ KeyringController: state })
@@ -144,7 +144,7 @@ module.exports = class MetamaskController extends EventEmitter {
// manual mem state subscriptions
this.networkStore.subscribe(this.sendUpdate.bind(this))
this.ethStore.subscribe(this.sendUpdate.bind(this))
- this.txManager.memStore.subscribe(this.sendUpdate.bind(this))
+ this.txController.memStore.subscribe(this.sendUpdate.bind(this))
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
this.personalMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
@@ -223,7 +223,7 @@ module.exports = class MetamaskController extends EventEmitter {
},
this.networkStore.getState(),
this.ethStore.getState(),
- this.txManager.memStore.getState(),
+ this.txController.memStore.getState(),
this.messageManager.memStore.getState(),
this.personalMessageManager.memStore.getState(),
this.keyringController.memStore.getState(),
@@ -248,7 +248,7 @@ module.exports = class MetamaskController extends EventEmitter {
getApi () {
const keyringController = this.keyringController
const preferencesController = this.preferencesController
- const txManager = this.txManager
+ const txController = this.txController
const noticeController = this.noticeController
const addressBookController = this.addressBookController
@@ -289,9 +289,9 @@ module.exports = class MetamaskController extends EventEmitter {
saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController),
exportAccount: nodeify(keyringController.exportAccount).bind(keyringController),
- // txManager
- approveTransaction: txManager.approveTransaction.bind(txManager),
- cancelTransaction: txManager.cancelTransaction.bind(txManager),
+ // txController
+ approveTransaction: txController.approveTransaction.bind(txController),
+ cancelTransaction: txController.cancelTransaction.bind(txController),
updateAndApproveTransaction: this.updateAndApproveTx.bind(this),
// messageManager
@@ -421,12 +421,12 @@ module.exports = class MetamaskController extends EventEmitter {
newUnapprovedTransaction (txParams, cb) {
log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
const self = this
- self.txManager.addUnapprovedTransaction(txParams, (err, txMeta) => {
+ self.txController.addUnapprovedTransaction(txParams, (err, txMeta) => {
if (err) return cb(err)
self.sendUpdate()
self.opts.showUnapprovedTx(txMeta)
// listen for tx completion (success, fail)
- self.txManager.once(`${txMeta.id}:finished`, (completedTx) => {
+ self.txController.once(`${txMeta.id}:finished`, (completedTx) => {
switch (completedTx.status) {
case 'submitted':
return cb(null, completedTx.hash)
@@ -477,9 +477,9 @@ module.exports = class MetamaskController extends EventEmitter {
updateAndApproveTx (txMeta, cb) {
log.debug(`MetaMaskController - updateAndApproveTx: ${JSON.stringify(txMeta)}`)
- const txManager = this.txManager
- txManager.updateTx(txMeta)
- txManager.approveTransaction(txMeta.id, cb)
+ const txController = this.txController
+ txController.updateTx(txMeta)
+ txController.approveTransaction(txMeta.id, cb)
}
signMessage (msgParams, cb) {
diff --git a/app/scripts/migrations/013.js b/app/scripts/migrations/013.js
new file mode 100644
index 000000000..8f11e510e
--- /dev/null
+++ b/app/scripts/migrations/013.js
@@ -0,0 +1,34 @@
+const version = 13
+
+/*
+
+This migration modifies the network config from ambiguous 'testnet' to explicit 'ropsten'
+
+*/
+
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ try {
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ } catch (err) {
+ console.warn(`MetaMask Migration #${version}` + err.stack)
+ }
+ return Promise.resolve(versionedData)
+ },
+}
+
+function transformState (state) {
+ const newState = state
+ if (newState.config.provider.type === 'testnet') {
+ newState.config.provider.type = 'ropsten'
+ }
+ return newState
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 019b4d13d..3a95cf88e 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -23,4 +23,5 @@ module.exports = [
require('./010'),
require('./011'),
require('./012'),
+ require('./013'),
]
diff --git a/mascara/README.md b/mascara/README.md
index db5b4f404..6e3bfe96b 100644
--- a/mascara/README.md
+++ b/mascara/README.md
@@ -3,7 +3,7 @@ start the dual servers (dapp + mascara)
npm run mascara
```
-## First time use:
+### First time use:
- navigate to: http://localhost:9001
- Create an Account
@@ -11,7 +11,7 @@ npm run mascara
- open devTools
- click Sync Tx
-## Tests:
+### Tests:
```
npm run testMascara
@@ -22,3 +22,12 @@ Test will run in browser, you will have to have these browsers installed:
- Chrome
- Firefox
- Opera
+
+
+### Deploy:
+
+Will build and deploy mascara via docker
+
+```
+docker-compose build && docker-compose stop && docker-compose up -d && docker-compose logs --tail 200 -f
+``` \ No newline at end of file
diff --git a/mascara/ui/index.html b/mascara/ui/index.html
index c5eeb05ef..eac8e4898 100644
--- a/mascara/ui/index.html
+++ b/mascara/ui/index.html
@@ -2,7 +2,8 @@
<html>
<head>
<meta charset="utf-8">
- <title>MetaMask Plugin</title>
+ <title>MetaMascara Alpha</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app-content"></div>
diff --git a/package.json b/package.json
index f4bdbd998..eb5ed8a32 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
{
"presets": [
"es2015",
- "stage-3"
+ "stage-0"
]
}
],
@@ -45,7 +45,6 @@
},
"dependencies": {
"async": "^1.5.2",
- "async-q": "^0.3.1",
"babel-runtime": "^6.23.0",
"bip39": "^2.2.0",
"bluebird": "^3.5.0",
@@ -57,6 +56,7 @@
"debounce": "^1.0.0",
"deep-extend": "^0.4.1",
"denodeify": "^1.2.1",
+ "detect-node": "^2.0.3",
"disc": "^1.3.2",
"dnode": "^1.2.2",
"end-of-stream": "^1.1.0",
@@ -121,14 +121,14 @@
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "0.18.2",
- "web3-provider-engine": "^12.0.3",
+ "web3-provider-engine": "^12.0.6",
"web3-stream-provider": "^2.0.6",
"xtend": "^4.0.1"
},
"devDependencies": {
"babel-eslint": "^6.0.5",
"babel-plugin-transform-runtime": "^6.23.0",
- "babel-preset-stage-3": "^6.24.1",
+ "babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.7.2",
"babelify": "^7.2.0",
"beefy": "^2.1.5",
@@ -136,9 +136,11 @@
"browserify": "^13.0.0",
"chai": "^3.5.0",
"clone": "^1.0.2",
+ "create-react-factory": "^0.2.1",
"deep-freeze-strict": "^1.1.1",
"del": "^2.2.0",
"envify": "^4.0.0",
+ "enzyme": "^2.8.2",
"eslint-plugin-chai": "0.0.1",
"eslint-plugin-mocha": "^4.9.0",
"fs-promise": "^1.0.0",
@@ -165,6 +167,10 @@
"prompt": "^1.0.0",
"qs": "^6.2.0",
"qunit": "^0.9.1",
+ "react-addons-test-utils": "^15.5.1",
+ "react-dom": "^15.5.4",
+ "react-test-renderer": "^15.5.4",
+ "react-testutils-additions": "^15.2.0",
"sinon": "^1.17.3",
"tape": "^4.5.1",
"testem": "^1.10.3",
diff --git a/test/lib/migrations/001.json b/test/lib/migrations/001.json
index 2fe6dd836..7bd55a50e 100644
--- a/test/lib/migrations/001.json
+++ b/test/lib/migrations/001.json
@@ -1 +1,14 @@
-{"version":0,"data":{"wallet":"{\"encSeed\":{\"encStr\":\"rT1C1jjkFRfmrwefscFcwZohl4f+HfIFlBZ9AM4ZD8atJmfKDIQCVK11NYDKYv8ZMIY03f3t8MuoZvfzBL8IJsWnZUhpzVTNNiARQJD2WpGA19eNBzgZm4vd0GwkIUruUDeJXu0iv2j9wU8hOQUqPbOePPy2Am5ro97iuvMAroRTnEKD60qFVg==\",\"nonce\":\"YUY2mwNq2v3FV0Fi94QnSiKFOLYfDR95\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"Iyi7ft4JQ9UtwrSXRT6ZIHPtZqJhe99rh0uWhNc6QLan6GanY2ZQeU0tt76CBealEWJyrJReSxGQdqDmSDYjpjH3m4JO5l0DfPLPseCqzXV/W+dzM0ubJ8lztLwpwi0L+vULNMqCx4dQtoNbNBq1QZUnjtpm6O8mWpScspboww==\",\"nonce\":\"Z7RqtjNjC6FrLUj5wVW1+HkjOW6Hib6K\"},\"hdIndex\":3,\"encPrivKeys\":{\"edb81c10122f34040cc4bef719a272fbbb1cf897\":{\"key\":\"8ab81tKBd4+CLAbzvS7SBFRTd6VWXBs86uBE43lgcmBu2U7UB22xdH64Q2hUf9eB\",\"nonce\":\"aGUEqI033FY39zKjWmZSI6PQrCLvkiRP\"},\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\":{\"key\":\"+i3wmf4b+B898QtlOBfL0Ixirjg59/LLPX61vQ2L0xRPjXzNog0O4Wn15RemM5mY\",\"nonce\":\"imKrlkuoC5uuFkzJBbuDBluGCPJXNTKm\"},\"2340695474656e3124b8eba1172fbfb00eeac8f8\":{\"key\":\"pi+H9D8LYKsdCQKrfaJtsGFjE+X9s74xN675tsoIKrbPXhtpxMLOIQVtSqYveF62\",\"nonce\":\"49g80wDTovHwbguVVYf2FsYbp7Db5OAR\"}},\"addresses\":[\"edb81c10122f34040cc4bef719a272fbbb1cf897\",\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\",\"2340695474656e3124b8eba1172fbfb00eeac8f8\"]}},\"version\":2}","config":{"provider":{"type":"etherscan"}}},"meta":{"version":0}} \ No newline at end of file
+{
+ "version": 0,
+ "data": {
+ "wallet": "{\"encSeed\":{\"encStr\":\"rT1C1jjkFRfmrwefscFcwZohl4f+HfIFlBZ9AM4ZD8atJmfKDIQCVK11NYDKYv8ZMIY03f3t8MuoZvfzBL8IJsWnZUhpzVTNNiARQJD2WpGA19eNBzgZm4vd0GwkIUruUDeJXu0iv2j9wU8hOQUqPbOePPy2Am5ro97iuvMAroRTnEKD60qFVg==\",\"nonce\":\"YUY2mwNq2v3FV0Fi94QnSiKFOLYfDR95\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"Iyi7ft4JQ9UtwrSXRT6ZIHPtZqJhe99rh0uWhNc6QLan6GanY2ZQeU0tt76CBealEWJyrJReSxGQdqDmSDYjpjH3m4JO5l0DfPLPseCqzXV/W+dzM0ubJ8lztLwpwi0L+vULNMqCx4dQtoNbNBq1QZUnjtpm6O8mWpScspboww==\",\"nonce\":\"Z7RqtjNjC6FrLUj5wVW1+HkjOW6Hib6K\"},\"hdIndex\":3,\"encPrivKeys\":{\"edb81c10122f34040cc4bef719a272fbbb1cf897\":{\"key\":\"8ab81tKBd4+CLAbzvS7SBFRTd6VWXBs86uBE43lgcmBu2U7UB22xdH64Q2hUf9eB\",\"nonce\":\"aGUEqI033FY39zKjWmZSI6PQrCLvkiRP\"},\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\":{\"key\":\"+i3wmf4b+B898QtlOBfL0Ixirjg59/LLPX61vQ2L0xRPjXzNog0O4Wn15RemM5mY\",\"nonce\":\"imKrlkuoC5uuFkzJBbuDBluGCPJXNTKm\"},\"2340695474656e3124b8eba1172fbfb00eeac8f8\":{\"key\":\"pi+H9D8LYKsdCQKrfaJtsGFjE+X9s74xN675tsoIKrbPXhtpxMLOIQVtSqYveF62\",\"nonce\":\"49g80wDTovHwbguVVYf2FsYbp7Db5OAR\"}},\"addresses\":[\"edb81c10122f34040cc4bef719a272fbbb1cf897\",\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\",\"2340695474656e3124b8eba1172fbfb00eeac8f8\"]}},\"version\":2}",
+ "config": {
+ "provider": {
+ "type": "etherscan"
+ }
+ }
+ },
+ "meta": {
+ "version": 0
+ }
+} \ No newline at end of file
diff --git a/test/lib/mock-store.js b/test/lib/mock-store.js
new file mode 100644
index 000000000..4714c3485
--- /dev/null
+++ b/test/lib/mock-store.js
@@ -0,0 +1,18 @@
+const createStore = require('redux').createStore
+const applyMiddleware = require('redux').applyMiddleware
+const thunkMiddleware = require('redux-thunk')
+const createLogger = require('redux-logger')
+const rootReducer = function() {}
+
+module.exports = configureStore
+
+const loggerMiddleware = createLogger()
+
+const createStoreWithMiddleware = applyMiddleware(
+ thunkMiddleware,
+ loggerMiddleware
+)(createStore)
+
+function configureStore (initialState) {
+ return createStoreWithMiddleware(rootReducer, initialState)
+}
diff --git a/test/unit/components/pending-tx-test.js b/test/unit/components/pending-tx-test.js
new file mode 100644
index 000000000..fe8290003
--- /dev/null
+++ b/test/unit/components/pending-tx-test.js
@@ -0,0 +1,89 @@
+const assert = require('assert')
+const additions = require('react-testutils-additions')
+const h = require('react-hyperscript')
+const PendingTx = require('../../../ui/app/components/pending-tx')
+const createReactFactory = require('create-react-factory').createReactFactory
+const React = require('react')
+const shallow = require('react-test-renderer/shallow')
+const Factory = createReactFactory(PendingTx)
+const ReactTestUtils = require('react-addons-test-utils')
+const ethUtil = require('ethereumjs-util')
+
+describe.only('PendingTx', function () {
+ let pendingTxComponent
+
+ const identities = {
+ '0xfdea65c8e26263f6d9a1b5de9555d2931a33b826': {
+ name: 'Main Account 1',
+ balance: '0x00000000000000056bc75e2d63100000',
+ },
+ }
+
+ const gasPrice = '0x4A817C800' // 20 Gwei
+ const txData = {
+ 'id':5021615666270214,
+ 'time':1494458763011,
+ 'status':'unapproved',
+ 'metamaskNetworkId':'1494442339676',
+ 'txParams':{
+ 'from':'0xfdea65c8e26263f6d9a1b5de9555d2931a33b826',
+ 'to':'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb',
+ 'value':'0xde0b6b3a7640000',
+ gasPrice,
+ 'gas':'0x7b0c'},
+ 'gasLimitSpecified':false,
+ 'estimatedGas':'0x5208',
+ }
+
+
+ it('should use updated values when edited.', function (done) {
+
+ const renderer = ReactTestUtils.createRenderer();
+ const newGasPrice = '0x77359400'
+
+ const props = {
+ identities,
+ accounts: identities,
+ txData,
+ sendTransaction: (txMeta, event) => {
+
+ // Assert changes:
+ const result = ethUtil.addHexPrefix(txMeta.txParams.gasPrice)
+ assert.notEqual(result, gasPrice, 'gas price should change')
+ assert.equal(result, newGasPrice, 'gas price assigned.')
+ done()
+ },
+ }
+
+ const pendingTxComponent = h(PendingTx, props)
+ const component = additions.renderIntoDocument(pendingTxComponent);
+ renderer.render(pendingTxComponent)
+ const result = renderer.getRenderOutput()
+ const form = result.props.children
+ const children = form.props.children[form.props.children.length - 1]
+ assert.equal(result.type, 'div', 'should create a div')
+
+ try{
+
+ const input = additions.find(component, '.cell.row input[type="number"]')[1]
+ ReactTestUtils.Simulate.change(input, {
+ target: {
+ value: 2,
+ checkValidity() { return true },
+ }
+ })
+
+ let form = additions.find(component, 'form')[0]
+ form.checkValidity = () => true
+ form.getFormEl = () => { return { checkValidity() { return true } } }
+ ReactTestUtils.Simulate.submit(form, { preventDefault() {}, target: { checkValidity() {return true} } })
+
+ } catch (e) {
+ console.log("WHAAAA")
+ console.error(e)
+ }
+
+ })
+
+})
+
diff --git a/test/unit/migrations-test.js b/test/unit/migrations-test.js
index 324e4d056..5bad25a45 100644
--- a/test/unit/migrations-test.js
+++ b/test/unit/migrations-test.js
@@ -16,6 +16,7 @@ const migration9 = require(path.join('..', '..', 'app', 'scripts', 'migrations',
const migration10 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '010'))
const migration11 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '011'))
const migration12 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '012'))
+const migration13 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '013'))
const oldTestRpc = 'https://rawtestrpc.metamask.io/'
@@ -97,6 +98,11 @@ describe('wallet1 is migrated successfully', () => {
}).then((twelfthResult) => {
assert.equal(twelfthResult.data.NoticeController.noticesList[0].body, '', 'notices that have been read should have an empty body.')
assert.equal(twelfthResult.data.NoticeController.noticesList[1].body, 'nonempty', 'notices that have not been read should not have an empty body.')
+
+ assert.equal(twelfthResult.data.config.provider.type, 'testnet', 'network is originally testnet.')
+ return migration13.migrate(twelfthResult)
+ }).then((thirteenthResult) => {
+ assert.equal(thirteenthResult.data.config.provider.type, 'ropsten', 'network has been changed to ropsten.')
})
})
})
diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-controller-test.js
index b5d148723..d0b32ff41 100644
--- a/test/unit/tx-manager-test.js
+++ b/test/unit/tx-controller-test.js
@@ -3,17 +3,17 @@ const EventEmitter = require('events')
const ethUtil = require('ethereumjs-util')
const EthTx = require('ethereumjs-tx')
const ObservableStore = require('obs-store')
-const TransactionManager = require('../../app/scripts/transaction-manager')
+const TransactionController = require('../../app/scripts/controllers/transactions')
const noop = () => true
const currentNetworkId = 42
const otherNetworkId = 36
const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
describe('Transaction Manager', function () {
- let txManager
+ let txController
beforeEach(function () {
- txManager = new TransactionManager({
+ txController = new TransactionController({
networkStore: new ObservableStore({ network: currentNetworkId }),
txHistoryLimit: 10,
blockTracker: new EventEmitter(),
@@ -29,7 +29,7 @@ describe('Transaction Manager', function () {
var sample = {
value: '0x01',
}
- txManager.txProviderUtils.validateTxParams(sample, (err) => {
+ txController.txProviderUtils.validateTxParams(sample, (err) => {
assert.equal(err, null, 'no error')
})
})
@@ -38,7 +38,7 @@ describe('Transaction Manager', function () {
var sample = {
value: '-0x01',
}
- txManager.txProviderUtils.validateTxParams(sample, (err) => {
+ txController.txProviderUtils.validateTxParams(sample, (err) => {
assert.ok(err, 'error')
})
})
@@ -46,7 +46,7 @@ describe('Transaction Manager', function () {
describe('#getTxList', function () {
it('when new should return empty array', function () {
- var result = txManager.getTxList()
+ var result = txController.getTxList()
assert.ok(Array.isArray(result))
assert.equal(result.length, 0)
})
@@ -58,8 +58,8 @@ describe('Transaction Manager', function () {
describe('#addTx', function () {
it('adds a tx returned in getTxList', function () {
var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
- var result = txManager.getTxList()
+ txController.addTx(tx, noop)
+ var result = txController.getTxList()
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].id, 1)
@@ -68,45 +68,45 @@ describe('Transaction Manager', function () {
it('does not override txs from other networks', function () {
var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }
var tx2 = { id: 2, status: 'confirmed', metamaskNetworkId: otherNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
- txManager.addTx(tx2, noop)
- var result = txManager.getFullTxList()
- var result2 = txManager.getTxList()
+ txController.addTx(tx, noop)
+ txController.addTx(tx2, noop)
+ var result = txController.getFullTxList()
+ var result2 = txController.getTxList()
assert.equal(result.length, 2, 'txs were deleted')
assert.equal(result2.length, 1, 'incorrect number of txs on network.')
})
it('cuts off early txs beyond a limit', function () {
- const limit = txManager.txHistoryLimit
+ const limit = txController.txHistoryLimit
for (let i = 0; i < limit + 1; i++) {
const tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
+ txController.addTx(tx, noop)
}
- var result = txManager.getTxList()
+ var result = txController.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 1, 'early txs truncted')
})
it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function () {
- const limit = txManager.txHistoryLimit
+ const limit = txController.txHistoryLimit
for (let i = 0; i < limit + 1; i++) {
const tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
+ txController.addTx(tx, noop)
}
- var result = txManager.getTxList()
+ var result = txController.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 1, 'early txs truncted')
})
it('cuts off early txs beyond a limit but does not cut unapproved txs', function () {
var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(unconfirmedTx, noop)
- const limit = txManager.txHistoryLimit
+ txController.addTx(unconfirmedTx, noop)
+ const limit = txController.txHistoryLimit
for (let i = 1; i < limit + 1; i++) {
const tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
+ txController.addTx(tx, noop)
}
- var result = txManager.getTxList()
+ var result = txController.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
assert.equal(result[0].id, 0, 'first tx should still be there')
assert.equal(result[0].status, 'unapproved', 'first tx should be unapproved')
@@ -117,9 +117,9 @@ describe('Transaction Manager', function () {
describe('#setTxStatusSigned', function () {
it('sets the tx status to signed', function () {
var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx, noop)
- txManager.setTxStatusSigned(1)
- var result = txManager.getTxList()
+ txController.addTx(tx, noop)
+ txController.setTxStatusSigned(1)
+ var result = txController.getTxList()
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].status, 'signed')
@@ -132,18 +132,18 @@ describe('Transaction Manager', function () {
assert(true, 'event listener has been triggered and noop executed')
done()
}
- txManager.addTx(tx)
- txManager.on('1:signed', noop)
- txManager.setTxStatusSigned(1)
+ txController.addTx(tx)
+ txController.on('1:signed', noop)
+ txController.setTxStatusSigned(1)
})
})
describe('#setTxStatusRejected', function () {
it('sets the tx status to rejected', function () {
var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx)
- txManager.setTxStatusRejected(1)
- var result = txManager.getTxList()
+ txController.addTx(tx)
+ txController.setTxStatusRejected(1)
+ var result = txController.getTxList()
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].status, 'rejected')
@@ -152,31 +152,31 @@ describe('Transaction Manager', function () {
it('should emit a rejected event to signal the exciton of callback', (done) => {
this.timeout(10000)
var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
- txManager.addTx(tx)
+ txController.addTx(tx)
const noop = function (err, txId) {
assert(true, 'event listener has been triggered and noop executed')
done()
}
- txManager.on('1:rejected', noop)
- txManager.setTxStatusRejected(1)
+ txController.on('1:rejected', noop)
+ txController.setTxStatusRejected(1)
})
})
describe('#updateTx', function () {
it('replaces the tx with the same id', function () {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: currentNetworkId, txParams: {} })
- var result = txManager.getTx('1')
+ txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ txController.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: currentNetworkId, txParams: {} })
+ var result = txController.getTx('1')
assert.equal(result.hash, 'foo')
})
})
describe('#getUnapprovedTxList', function () {
it('returns unapproved txs in a hash', function () {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- const result = txManager.getUnapprovedTxList()
+ txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ const result = txController.getUnapprovedTxList()
assert.equal(typeof result, 'object')
assert.equal(result['1'].status, 'unapproved')
assert.equal(result['2'], undefined)
@@ -185,10 +185,10 @@ describe('Transaction Manager', function () {
describe('#getTx', function () {
it('returns a tx with the requested id', function () {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- assert.equal(txManager.getTx('1').status, 'unapproved')
- assert.equal(txManager.getTx('2').status, 'confirmed')
+ txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ assert.equal(txController.getTx('1').status, 'unapproved')
+ assert.equal(txController.getTx('2').status, 'confirmed')
})
})
@@ -206,28 +206,28 @@ describe('Transaction Manager', function () {
{ id: 8, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId },
{ id: 9, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId },
]
- txMetas.forEach((txMeta) => txManager.addTx(txMeta, noop))
+ txMetas.forEach((txMeta) => txController.addTx(txMeta, noop))
let filterParams
filterParams = { status: 'unapproved', from: '0xaa' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
filterParams = { status: 'unapproved', to: '0xaa' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
filterParams = { status: 'confirmed', from: '0xbb' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
filterParams = { status: 'confirmed' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
filterParams = { from: '0xaa' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
filterParams = { to: '0xaa' }
- assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
})
})
describe('#sign replay-protected tx', function () {
it('prepares a tx with the chainId set', function () {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
- txManager.signTransaction('1', (err, rawTx) => {
+ txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
+ txController.signTransaction('1', (err, rawTx) => {
if (err) return assert.fail('it should not fail')
const ethTx = new EthTx(ethUtil.toBuffer(rawTx))
assert.equal(ethTx.getChainId(), currentNetworkId)
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index d592a5ad6..7a78a360c 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -29,6 +29,8 @@ function mapStateToProps (state) {
unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
shapeShiftTxList: state.metamask.shapeShiftTxList,
transactions: state.metamask.selectedAddressTxList || [],
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
}
}
@@ -43,7 +45,7 @@ AccountDetailScreen.prototype.render = function () {
var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
var identity = props.identities[selected]
var account = props.accounts[selected]
- const { network } = props
+ const { network, conversionRate, currentCurrency } = props
return (
@@ -182,6 +184,8 @@ AccountDetailScreen.prototype.render = function () {
h(EthBalance, {
value: account && account.balance,
+ conversionRate,
+ currentCurrency,
style: {
lineHeight: '7px',
marginTop: '10px',
@@ -243,11 +247,13 @@ AccountDetailScreen.prototype.subview = function () {
}
AccountDetailScreen.prototype.transactionList = function () {
- const {transactions, unapprovedMsgs, address, network, shapeShiftTxList } = this.props
+ const {transactions, unapprovedMsgs, address,
+ network, shapeShiftTxList, conversionRate } = this.props
return h(TransactionList, {
transactions: transactions.sort((a, b) => b.time - a.time),
network,
unapprovedMsgs,
+ conversionRate,
address,
shapeShiftTxList,
viewPendingTx: (txId) => {
diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js
index 2a3c13d05..10a0b6cc7 100644
--- a/ui/app/accounts/account-list-item.js
+++ b/ui/app/accounts/account-list-item.js
@@ -15,7 +15,8 @@ function AccountListItem () {
}
AccountListItem.prototype.render = function () {
- const { identity, selectedAddress, accounts, onShowDetail } = this.props
+ const { identity, selectedAddress, accounts, onShowDetail,
+ conversionRate, currentCurrency } = this.props
const checksumAddress = identity && identity.address && ethUtil.toChecksumAddress(identity.address)
const isSelected = selectedAddress === identity.address
@@ -52,6 +53,8 @@ AccountListItem.prototype.render = function () {
}, checksumAddress),
h(EthBalance, {
value: account && account.balance,
+ currentCurrency,
+ conversionRate,
style: {
lineHeight: '7px',
marginTop: '10px',
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
index 9584ebad9..ac2615cd7 100644
--- a/ui/app/accounts/index.js
+++ b/ui/app/accounts/index.js
@@ -23,6 +23,8 @@ function mapStateToProps (state) {
scrollToBottom: state.appState.scrollToBottom,
pending,
keyrings: state.metamask.keyrings,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
}
}
@@ -33,7 +35,7 @@ function AccountsScreen () {
AccountsScreen.prototype.render = function () {
const props = this.props
- const { keyrings } = props
+ const { keyrings, conversionRate, currentCurrency } = props
const identityList = valuesFor(props.identities)
const unapprovedTxList = valuesFor(props.unapprovedTxs)
@@ -81,6 +83,8 @@ AccountsScreen.prototype.render = function () {
key: `acct-panel-${identity.address}`,
identity,
selectedAddress: this.props.selectedAddress,
+ conversionRate,
+ currentCurrency,
accounts: this.props.accounts,
onShowDetail: this.onShowDetail.bind(this),
pending,
diff --git a/ui/app/app.js b/ui/app/app.js
index bbfd58588..6e5aa57cd 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -249,7 +249,7 @@ App.prototype.renderNetworkDropdown = function () {
h(DropMenuItem, {
label: 'Ropsten Test Network',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setProviderType('testnet')),
+ action: () => props.dispatch(actions.setProviderType('ropsten')),
icon: h('.menu-icon.red-dot'),
activeNetworkRender: props.network,
provider: props.provider,
diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js
index bd9d8f597..e42948209 100644
--- a/ui/app/components/drop-menu-item.js
+++ b/ui/app/components/drop-menu-item.js
@@ -42,7 +42,7 @@ DropMenuItem.prototype.activeNetworkRender = function () {
if (providerType === 'mainnet') return h('.check', '✓')
break
case 'Ropsten Test Network':
- if (providerType === 'testnet') return h('.check', '✓')
+ if (providerType === 'ropsten') return h('.check', '✓')
break
case 'Kovan Test Network':
if (providerType === 'kovan') return h('.check', '✓')
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index 04c6222c2..3e44d83af 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -168,6 +168,7 @@ EnsInput.prototype.ensIconContents = function (recipient) {
}
}
-function getNetworkEnsSupport(network) {
+function getNetworkEnsSupport (network) {
return Boolean(networkMap[network])
-} \ No newline at end of file
+}
+
diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js
index 57ca84564..4f538fd31 100644
--- a/ui/app/components/eth-balance.js
+++ b/ui/app/components/eth-balance.js
@@ -16,20 +16,19 @@ function EthBalanceComponent () {
EthBalanceComponent.prototype.render = function () {
var props = this.props
let { value } = props
- var style = props.style
+ const { style, width } = props
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
value = value ? formatBalance(value, 6, needsParse) : '...'
- var width = props.width
return (
h('.ether-balance.ether-balance-amount', {
- style: style,
+ style,
}, [
h('div', {
style: {
display: 'inline',
- width: width,
+ width,
},
}, this.renderBalance(value)),
])
@@ -38,16 +37,17 @@ EthBalanceComponent.prototype.render = function () {
}
EthBalanceComponent.prototype.renderBalance = function (value) {
var props = this.props
+ const { conversionRate, shorten, incoming, currentCurrency } = props
if (value === 'None') return value
if (value === '...') return value
- var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
+ var balanceObj = generateBalanceObject(value, shorten ? 1 : 3)
var balance
var splitBalance = value.split(' ')
var ethNumber = splitBalance[0]
var ethSuffix = splitBalance[1]
const showFiat = 'showFiat' in props ? props.showFiat : true
- if (props.shorten) {
+ if (shorten) {
balance = balanceObj.shortBalance
} else {
balance = balanceObj.balance
@@ -73,7 +73,7 @@ EthBalanceComponent.prototype.renderBalance = function (value) {
width: '100%',
textAlign: 'right',
},
- }, this.props.incoming ? `+${balance}` : balance),
+ }, incoming ? `+${balance}` : balance),
h('div', {
style: {
color: ' #AEAEAE',
@@ -83,7 +83,7 @@ EthBalanceComponent.prototype.renderBalance = function (value) {
}, label),
]),
- showFiat ? h(FiatValue, { value: props.value }) : null,
+ showFiat ? h(FiatValue, { value: props.value, conversionRate, currentCurrency }) : null,
]))
)
}
diff --git a/ui/app/components/fiat-value.js b/ui/app/components/fiat-value.js
index 298809b30..8a64a1cfc 100644
--- a/ui/app/components/fiat-value.js
+++ b/ui/app/components/fiat-value.js
@@ -1,17 +1,9 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
-const connect = require('react-redux').connect
const formatBalance = require('../util').formatBalance
-module.exports = connect(mapStateToProps)(FiatValue)
-
-function mapStateToProps (state) {
- return {
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- }
-}
+module.exports = FiatValue
inherits(FiatValue, Component)
function FiatValue () {
@@ -20,23 +12,23 @@ function FiatValue () {
FiatValue.prototype.render = function () {
const props = this.props
+ const { conversionRate, currentCurrency } = props
+
const value = formatBalance(props.value, 6)
if (value === 'None') return value
var fiatDisplayNumber, fiatTooltipNumber
var splitBalance = value.split(' ')
- if (props.conversionRate !== 0) {
- fiatTooltipNumber = Number(splitBalance[0]) * props.conversionRate
+ if (conversionRate !== 0) {
+ fiatTooltipNumber = Number(splitBalance[0]) * conversionRate
fiatDisplayNumber = fiatTooltipNumber.toFixed(2)
} else {
fiatDisplayNumber = 'N/A'
fiatTooltipNumber = 'Unknown'
}
- var fiatSuffix = props.currentCurrency
-
- return fiatDisplay(fiatDisplayNumber, fiatSuffix)
+ return fiatDisplay(fiatDisplayNumber, currentCurrency)
}
function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index 6d4871d02..9de854b54 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -1,6 +1,7 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const isNode = require('detect-node')
const findDOMNode = require('react-dom').findDOMNode
const jazzicon = require('jazzicon')
const iconFactoryGen = require('../../lib/icon-factory')
@@ -40,8 +41,10 @@ IdenticonComponent.prototype.componentDidMount = function () {
var container = findDOMNode(this)
var diameter = props.diameter || this.defaultDiameter
- var img = iconFactory.iconForAddress(address, diameter, false)
- container.appendChild(img)
+ if (!isNode) {
+ var img = iconFactory.iconForAddress(address, diameter, false)
+ container.appendChild(img)
+ }
}
IdenticonComponent.prototype.componentDidUpdate = function () {
@@ -58,6 +61,8 @@ IdenticonComponent.prototype.componentDidUpdate = function () {
}
var diameter = props.diameter || this.defaultDiameter
- var img = iconFactory.iconForAddress(address, diameter, false)
- container.appendChild(img)
+ if (!isNode) {
+ var img = iconFactory.iconForAddress(address, diameter, false)
+ container.appendChild(img)
+ }
}
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index f7ea8c49e..31a8fc17c 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -34,7 +34,7 @@ Network.prototype.render = function () {
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
iconName = 'ethereum-network'
- } else if (providerName === 'testnet') {
+ } else if (providerName === 'ropsten') {
hoverText = 'Ropsten Test Network'
iconName = 'ropsten-test-network'
} else if (parseInt(networkNumber) === 3) {
@@ -90,7 +90,7 @@ Network.prototype.render = function () {
h('.menu-icon.golden-square'),
h('.network-name', {
style: {
- color: '#550077',
+ color: '#e7a218',
}},
'Rinkeby Test Net'),
])
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index 5c8d81d07..37a3a3bf3 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -1,5 +1,4 @@
const Component = require('react').Component
-const connect = require('react-redux').connect
const h = require('react-hyperscript')
const inherits = require('util').inherits
const actions = require('../actions')
@@ -20,12 +19,7 @@ const GWEI_FACTOR = new BN(1e9)
const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR)
const MIN_GAS_LIMIT_BN = new BN(21000)
-module.exports = connect(mapStateToProps)(PendingTx)
-
-function mapStateToProps (state) {
- return {}
-}
-
+module.exports = PendingTx
inherits(PendingTx, Component)
function PendingTx () {
Component.call(this)
@@ -37,7 +31,9 @@ function PendingTx () {
PendingTx.prototype.render = function () {
const props = this.props
+ const { currentCurrency } = props
+ const conversionRate = props.conversionRate
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
@@ -60,7 +56,6 @@ PendingTx.prototype.render = function () {
const maxCost = txFeeBn.add(valueBn)
const dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0
- const imageify = props.imageifyIdenticons === undefined ? true : props.imageifyIdenticons
const balanceBn = hexToBn(balance)
const insufficientBalance = balanceBn.lt(maxCost)
@@ -74,18 +69,8 @@ PendingTx.prototype.render = function () {
}, [
h('form#pending-tx-form', {
- onSubmit: (event) => {
- const txMeta = this.gatherTxMeta()
- event.preventDefault()
- const form = document.querySelector('form#pending-tx-form')
- const valid = form.checkValidity()
- this.setState({ valid })
- if (valid && this.verifyGasParams()) {
- props.sendTransaction(txMeta, event)
- } else {
- this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
- }
- },
+ onSubmit: this.onSubmit.bind(this),
+
}, [
// tx info
@@ -99,7 +84,6 @@ PendingTx.prototype.render = function () {
h(MiniAccountPanel, {
imageSeed: address,
- imageifyIdenticons: imageify,
picOrder: 'right',
}, [
h('span.font-small', {
@@ -120,6 +104,8 @@ PendingTx.prototype.render = function () {
}, [
h(EthBalance, {
value: balance,
+ conversionRate,
+ currentCurrency,
inline: true,
labelColor: '#F7861C',
}),
@@ -157,7 +143,7 @@ PendingTx.prototype.render = function () {
// in the way that gas and gasLimit currently are.
h('.row', [
h('.cell.label', 'Amount'),
- h(EthBalance, { value: txParams.value }),
+ h(EthBalance, { value: txParams.value, currentCurrency, conversionRate }),
]),
// Gas Limit (customizable)
@@ -176,12 +162,8 @@ PendingTx.prototype.render = function () {
position: 'relative',
top: '5px',
},
- onChange: (newBN) => {
- log.info(`Gas limit changed to ${newBN.toString(10)}`)
- const txMeta = this.gatherTxMeta()
- txMeta.txParams.gas = '0x' + newBN.toString('hex')
- this.setState({ txData: cloneObj(txMeta) })
- },
+ onChange: this.gasLimitChanged.bind(this),
+
ref: (hexInput) => { this.inputs.push(hexInput) },
}),
]),
@@ -202,12 +184,7 @@ PendingTx.prototype.render = function () {
position: 'relative',
top: '5px',
},
- onChange: (newBN) => {
- log.info(`Gas price changed to: ${newBN.toString(10)}`)
- const txMeta = this.gatherTxMeta()
- txMeta.txParams.gasPrice = '0x' + newBN.toString('hex')
- this.setState({ txData: cloneObj(txMeta) })
- },
+ onChange: this.gasPriceChanged.bind(this),
ref: (hexInput) => { this.inputs.push(hexInput) },
}),
]),
@@ -216,7 +193,7 @@ PendingTx.prototype.render = function () {
// Max Transaction Fee (calculated)
h('.cell.row', [
h('.cell.label', 'Max Transaction Fee'),
- h(EthBalance, { value: txFeeBn.toString(16) }),
+ h(EthBalance, { value: txFeeBn.toString(16), currentCurrency, conversionRate }),
]),
h('.cell.row', {
@@ -235,6 +212,8 @@ PendingTx.prototype.render = function () {
}, [
h(EthBalance, {
value: maxCost.toString(16),
+ currentCurrency,
+ conversionRate,
inline: true,
labelColor: 'black',
fontSize: '16px',
@@ -331,13 +310,11 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () {
const txData = props.txData
const txParams = txData.txParams || {}
const isContractDeploy = !('to' in txParams)
- const imageify = props.imageifyIdenticons === undefined ? true : props.imageifyIdenticons
// If it's not a contract deploy, send to the account
if (!isContractDeploy) {
return h(MiniAccountPanel, {
imageSeed: txParams.to,
- imageifyIdenticons: imageify,
picOrder: 'left',
}, [
h('span.font-small', {
@@ -353,7 +330,6 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () {
])
} else {
return h(MiniAccountPanel, {
- imageifyIdenticons: imageify,
picOrder: 'left',
}, [
@@ -367,6 +343,20 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () {
}
}
+PendingTx.prototype.gasPriceChanged = function (newBN) {
+ log.info(`Gas price changed to: ${newBN.toString(10)}`)
+ const txMeta = this.gatherTxMeta()
+ txMeta.txParams.gasPrice = '0x' + newBN.toString('hex')
+ this.setState({ txData: cloneObj(txMeta) })
+}
+
+PendingTx.prototype.gasLimitChanged = function (newBN) {
+ log.info(`Gas limit changed to ${newBN.toString(10)}`)
+ const txMeta = this.gatherTxMeta()
+ txMeta.txParams.gas = '0x' + newBN.toString('hex')
+ this.setState({ txData: cloneObj(txMeta) })
+}
+
PendingTx.prototype.resetGasFields = function () {
log.debug(`pending-tx resetGasFields`)
@@ -383,6 +373,33 @@ PendingTx.prototype.resetGasFields = function () {
})
}
+PendingTx.prototype.onSubmit = function (event) {
+ event.preventDefault()
+ const txMeta = this.gatherTxMeta()
+ const valid = this.checkValidity()
+ this.setState({ valid })
+ if (valid && this.verifyGasParams()) {
+ this.props.sendTransaction(txMeta, event)
+ } else {
+ this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
+ }
+}
+
+PendingTx.prototype.checkValidity = function () {
+ const form = this.getFormEl()
+ const valid = form.checkValidity()
+ return valid
+}
+
+PendingTx.prototype.getFormEl = function () {
+ const form = document.querySelector('form#pending-tx-form')
+ // Stub out form for unit tests:
+ if (!form) {
+ return { checkValidity () { return true } }
+ }
+ return form
+}
+
// After a customizable state value has been updated,
PendingTx.prototype.gatherTxMeta = function () {
log.debug(`pending-tx gatherTxMeta`)
diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js
index 96a7cba6e..32bfbeda4 100644
--- a/ui/app/components/shift-list-item.js
+++ b/ui/app/components/shift-list-item.js
@@ -8,14 +8,17 @@ const actions = require('../actions')
const addressSummary = require('../util').addressSummary
const CopyButton = require('./copyButton')
-const EtherBalance = require('./eth-balance')
+const EthBalance = require('./eth-balance')
const Tooltip = require('./tooltip')
module.exports = connect(mapStateToProps)(ShiftListItem)
function mapStateToProps (state) {
- return {}
+ return {
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ }
}
inherits(ShiftListItem, Component)
@@ -64,6 +67,7 @@ function formatDate (date) {
ShiftListItem.prototype.renderUtilComponents = function () {
var props = this.props
+ const { conversionRate, currentCurrency } = props
switch (props.response.status) {
case 'no_deposits':
@@ -94,8 +98,10 @@ ShiftListItem.prototype.renderUtilComponents = function () {
h(CopyButton, {
value: this.props.response.transaction,
}),
- h(EtherBalance, {
+ h(EthBalance, {
value: `${props.response.outgoingCoin}`,
+ conversionRate,
+ currentCurrency,
width: '55px',
shorten: true,
needsParse: false,
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 7fb2e88d9..c2a585003 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -2,7 +2,7 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
-const EtherBalance = require('./eth-balance')
+const EthBalance = require('./eth-balance')
const addressSummary = require('../util').addressSummary
const explorerLink = require('../../lib/explorer-link')
const CopyButton = require('./copyButton')
@@ -19,7 +19,7 @@ function TransactionListItem () {
}
TransactionListItem.prototype.render = function () {
- const { transaction, network } = this.props
+ const { transaction, network, conversionRate, currentCurrency } = this.props
if (transaction.key === 'shapeshift') {
if (network === '1') return h(ShiftListItem, transaction)
}
@@ -78,8 +78,10 @@ TransactionListItem.prototype.render = function () {
// Places a copy button if tx is successful, else places a placeholder empty div.
transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}),
- isTx ? h(EtherBalance, {
+ isTx ? h(EthBalance, {
value: txParams.value,
+ conversionRate,
+ currentCurrency,
width: '55px',
shorten: true,
showFiat: false,
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
index 3ae953637..37a757309 100644
--- a/ui/app/components/transaction-list.js
+++ b/ui/app/components/transaction-list.js
@@ -13,7 +13,7 @@ function TransactionList () {
}
TransactionList.prototype.render = function () {
- const { transactions, network, unapprovedMsgs } = this.props
+ const { transactions, network, unapprovedMsgs, conversionRate } = this.props
var shapeShiftTxList
if (network === '1') {
@@ -69,6 +69,7 @@ TransactionList.prototype.render = function () {
}
return h(TransactionListItem, {
transaction, i, network, key,
+ conversionRate,
showTx: (txId) => {
this.props.viewPendingTx(txId)
},
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 83ac5a4fd..0d7c4c1bb 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -27,6 +27,8 @@ function mapStateToProps (state) {
warning: state.appState.warning,
network: state.metamask.network,
provider: state.metamask.provider,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
}
}
@@ -37,8 +39,8 @@ function ConfirmTxScreen () {
ConfirmTxScreen.prototype.render = function () {
const props = this.props
- const { network, provider, unapprovedTxs,
- unapprovedMsgs, unapprovedPersonalMsgs } = props
+ const { network, provider, unapprovedTxs, currentCurrency,
+ unapprovedMsgs, unapprovedPersonalMsgs, conversionRate } = props
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
@@ -102,6 +104,8 @@ ConfirmTxScreen.prototype.render = function () {
selectedAddress: props.selectedAddress,
accounts: props.accounts,
identities: props.identities,
+ conversionRate,
+ currentCurrency,
// Actions
buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress),
sendTransaction: this.sendTransaction.bind(this, txData),
diff --git a/ui/app/config.js b/ui/app/config.js
index 26cfe663f..d7be26757 100644
--- a/ui/app/config.js
+++ b/ui/app/config.js
@@ -156,7 +156,7 @@ function currentProviderDisplay (metamaskState) {
value = 'Main Ethereum Network'
break
- case 'testnet':
+ case 'ropsten':
title = 'Current Network'
value = 'Ropsten Test Network'
break
diff --git a/ui/app/send.js b/ui/app/send.js
index eb32d5e06..fd6994145 100644
--- a/ui/app/send.js
+++ b/ui/app/send.js
@@ -21,6 +21,8 @@ function mapStateToProps (state) {
warning: state.appState.warning,
network: state.metamask.network,
addressBook: state.metamask.addressBook,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
}
result.error = result.warning && result.warning.split('.')[0]
@@ -40,13 +42,17 @@ function SendTransactionScreen () {
SendTransactionScreen.prototype.render = function () {
this.persistentFormParentId = 'send-tx-form'
- var state = this.props
- var address = state.address
- var account = state.account
- var identity = state.identity
- var network = state.network
- var identities = state.identities
- var addressBook = state.addressBook
+ const props = this.props
+ const {
+ address,
+ account,
+ identity,
+ network,
+ identities,
+ addressBook,
+ conversionRate,
+ currentCurrency,
+ } = props
return (
@@ -125,6 +131,8 @@ SendTransactionScreen.prototype.render = function () {
h(EthBalance, {
value: account && account.balance,
+ conversionRate,
+ currentCurrency,
}),
]),
@@ -147,7 +155,7 @@ SendTransactionScreen.prototype.render = function () {
]),
// error message
- state.error && h('span.error.flex-center', state.error),
+ props.error && h('span.error.flex-center', props.error),
// 'to' field
h('section.flex-row.flex-center', [